fix(db): await AsyncConnection.execution_options in run_maintenance
execution_options() is a coroutine on AsyncConnection and must be awaited; the un-awaited call returned a coroutine, so exec_driver_sql() blew up with AttributeError and every table's VACUUM was skipped (Run-now reported 0/6). A prior change had wrongly dropped the await. Fix it and make the test mock execution_options async so this call shape is actually exercised. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -66,9 +66,10 @@ async def run_maintenance(tables: tuple[str, ...] | list[str] | None = None) ->
|
||||
results: list[dict] = []
|
||||
|
||||
async with engine.connect() as conn:
|
||||
# execution_options() is synchronous on AsyncConnection; it returns the
|
||||
# connection with AUTOCOMMIT set (VACUUM can't run in a transaction).
|
||||
autocommit = conn.execution_options(isolation_level="AUTOCOMMIT")
|
||||
# On AsyncConnection, execution_options() is a coroutine and MUST be
|
||||
# awaited (it returns the connection with AUTOCOMMIT set — VACUUM can't
|
||||
# run inside a transaction block).
|
||||
autocommit = await conn.execution_options(isolation_level="AUTOCOMMIT")
|
||||
for table in targets:
|
||||
t0 = time.monotonic()
|
||||
try:
|
||||
|
||||
@@ -16,7 +16,9 @@ def _mock_engine(exec_side_effect=None):
|
||||
conn = MagicMock()
|
||||
autocommit = MagicMock()
|
||||
autocommit.exec_driver_sql = AsyncMock(side_effect=exec_side_effect)
|
||||
conn.execution_options.return_value = autocommit # sync on AsyncConnection
|
||||
# On AsyncConnection, execution_options() is a coroutine — mock it as async
|
||||
# so the test exercises the real (awaited) call shape.
|
||||
conn.execution_options = AsyncMock(return_value=autocommit)
|
||||
cm = AsyncMock()
|
||||
cm.__aenter__ = AsyncMock(return_value=conn)
|
||||
cm.__aexit__ = AsyncMock(return_value=False)
|
||||
@@ -36,9 +38,9 @@ async def test_vacuums_each_allowlisted_table_once():
|
||||
assert issued == [f"VACUUM (ANALYZE) {t}" for t in MAINTENANCE_TABLES]
|
||||
assert all(r["ok"] for r in summary["tables"])
|
||||
assert len(summary["tables"]) == len(MAINTENANCE_TABLES)
|
||||
# AUTOCOMMIT was requested — VACUUM cannot run inside a transaction.
|
||||
# AUTOCOMMIT was requested (and awaited) — VACUUM can't run in a transaction.
|
||||
conn = engine.connect.return_value.__aenter__.return_value
|
||||
conn.execution_options.assert_called_once_with(isolation_level="AUTOCOMMIT")
|
||||
conn.execution_options.assert_awaited_once_with(isolation_level="AUTOCOMMIT")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user