Skip to content

Commit 1290dc2

Browse files
snopokeclaude
andcommitted
test(procrastinate): skip apply_schema when schema already exists
apply_schema is NOT idempotent — procrastinate's schema.sql uses bare CREATE TYPE/CREATE TABLE, so re-running blows up with DuplicateObject on the second invocation (whether across tests in one run or across runs against a persistent DB). Split into two fixtures: a session-scoped _schema that does a one-time existence check + conditional apply, and the existing function-scoped app that opens/closes a fresh App per test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f0917a6 commit 1290dc2

1 file changed

Lines changed: 20 additions & 7 deletions

File tree

integration_tests/test_procrastinate.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,31 @@ def _check_log_errors(caplog):
3636
pytest.fail(f"log errors during '{when}': {errors}")
3737

3838

39+
@pytest.fixture(scope="session")
40+
def _schema():
41+
# apply_schema is NOT idempotent (schema.sql uses bare CREATE TYPE), so
42+
# only apply when the schema isn't already present.
43+
with psycopg.connect(PROCRASTINATE_DSN) as conn, conn.cursor() as cur:
44+
cur.execute("SELECT to_regclass('procrastinate_jobs')")
45+
if cur.fetchone()[0] is not None:
46+
return
47+
schema_conn = procrastinate.SyncPsycopgConnector(conninfo=PROCRASTINATE_DSN)
48+
schema_app = procrastinate.App(connector=schema_conn)
49+
with schema_app.open():
50+
schema_app.schema_manager.apply_schema()
51+
52+
3953
@pytest.fixture
40-
def app():
41-
# Async connector even though the tests are sync: run_worker raises
42-
# SyncConnectorConfigurationError on SyncPsycopgConnector. Async works in both contexts.
54+
def app(_schema):
55+
# Async connector: run_worker raises SyncConnectorConfigurationError on
56+
# SyncPsycopgConnector. Async connectors work in sync contexts too.
4357
#
44-
# Function-scoped because run_worker tears down the sync sub-connector
45-
# PsycopgConnector creates inside `app.open()`, and nothing reopens it for
46-
# the next test's defer() call. Cheap: apply_schema is idempotent.
58+
# Function-scoped because run_worker tears down the sync sub-connector that
59+
# PsycopgConnector spawns inside `app.open()`, leaving the next test's
60+
# defer() with no usable sync pool.
4761
conn = procrastinate.PsycopgConnector(conninfo=PROCRASTINATE_DSN)
4862
app = procrastinate.App(connector=conn)
4963
with app.open():
50-
app.schema_manager.apply_schema()
5164
yield app
5265

5366

0 commit comments

Comments
 (0)