From ec68f0b8f6b034a2c0fef2a2ec144b50c7d9556c Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 12 Oct 2026 16:41:01 +0000 Subject: [PATCH] Define uses_psycopg2_extras on both Postgres engines The driver-agnostic base declares it and the executescript path reads it, but neither concrete engine set it, so booting on the Rust engine failed with an AttributeError in schema preparation. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01ULdieJyQoHNzeHq42H2M1p --- synapse/storage/engines/postgres.py | 4 ++++ synapse/storage/engines/postgres_rust.py | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/synapse/storage/engines/postgres.py b/synapse/storage/engines/postgres.py index 4e2715b6d6..70ebcba8e6 100644 --- a/synapse/storage/engines/postgres.py +++ b/synapse/storage/engines/postgres.py @@ -43,6 +43,10 @@ class Psycopg2Engine( ): """The Postgres backend that talks to the database via psycopg2.""" + # psycopg2's cursor is a real psycopg2 cursor, so the `psycopg2.extras` + # helpers can be used on it directly. + uses_psycopg2_extras: bool = True + def __init__(self, database_config: Mapping[str, Any]): super().__init__(psycopg2, database_config) psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) diff --git a/synapse/storage/engines/postgres_rust.py b/synapse/storage/engines/postgres_rust.py index dc67651732..9ce0b3218b 100644 --- a/synapse/storage/engines/postgres_rust.py +++ b/synapse/storage/engines/postgres_rust.py @@ -57,6 +57,11 @@ _RETRYABLE_PGCODES = ("40001", "40P01") class RustPostgresEngine(PostgresEngine[Connection, Cursor]): """A :class:`PostgresEngine` that talks to the Rust backend's shim.""" + # The shim cursor is not a psycopg2 cursor, so the `psycopg2.extras` + # helpers can't be used on it; `LoggingTransaction.executescript` takes the + # shim's own multi-statement path instead. + uses_psycopg2_extras: bool = False + # SQL isolation-level names for each `IsolationLevel`. The shim has no # psycopg2-style `set_isolation_level`, so a per-transaction override is # applied as a `SET SESSION CHARACTERISTICS` statement (see