erdoganpeker commited on
Commit
6eaedf2
·
1 Parent(s): 47de723

fix(deploy): disable asyncpg stmt cache in Alembic env for Supabase pooler

Browse files

database.py runtime engine already auto-detects pgbouncer and sets
statement_cache_size=0, but migrations/env.py builds its own asyncpg
engine for Alembic and was missing the same connect_args. Result:
'select pg_catalog.version()' triggered DuplicatePreparedStatementError
on the FIRST connection of every Alembic run.

Mirror the auto-detect (':6543/' or 'pooler.supabase.com' in URL) and
pass statement_cache_size=0 + prepared_statement_cache_size=0 via
async_engine_from_config(connect_args=...).

Files changed (1) hide show
  1. services/backend/migrations/env.py +13 -0
services/backend/migrations/env.py CHANGED
@@ -79,10 +79,23 @@ async def run_migrations_online() -> None:
79
  section = config.get_section(config.config_ini_section) or {}
80
  section["sqlalchemy.url"] = url
81
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  connectable = async_engine_from_config(
83
  section,
84
  prefix="sqlalchemy.",
85
  poolclass=pool.NullPool,
 
86
  )
87
 
88
  async with connectable.connect() as connection:
 
79
  section = config.get_section(config.config_ini_section) or {}
80
  section["sqlalchemy.url"] = url
81
 
82
+ # PgBouncer transaction-mode (Supabase shared pooler on :6543) does NOT
83
+ # support PostgreSQL prepared statements — asyncpg's default named-stmt
84
+ # cache fires DuplicatePreparedStatementError ("__asyncpg_stmt_1__")
85
+ # right at the dialect's "SELECT pg_catalog.version()" probe. Detect
86
+ # the pooler URL and disable both caches in the asyncpg connect kwargs.
87
+ connect_args = {}
88
+ if ":6543/" in url or "pooler.supabase.com" in url:
89
+ connect_args = {
90
+ "statement_cache_size": 0,
91
+ "prepared_statement_cache_size": 0,
92
+ }
93
+
94
  connectable = async_engine_from_config(
95
  section,
96
  prefix="sqlalchemy.",
97
  poolclass=pool.NullPool,
98
+ connect_args=connect_args,
99
  )
100
 
101
  async with connectable.connect() as connection: