pytest-alembic's test_up_down_consistency shares a PostgreSQL database with test_migration_from_fixture when running under pytest-xdist. Migration test fixtures that register seed data via the get_at_{revision}_data() naming convention are auto-discovered and inserted globally during EVERY upgrade pass. The test_up_down_consistency test does upgrade→downgrade→upgrade, so the second upgrade re-inserts the same rows, hitting UniqueViolation on primary keys. Additionally, fixture-seeded rows that lack columns dropped by earlier migrations (e.g. a column dropped by migration A but expected NOT NULL by migration A's downgrade) cause NotNullViolation during the downgrade pass.
Rename fixture seed functions from get_at_{revision}_data() to _seed_data() (underscore prefix) so they're NOT auto-discovered by the global at_revision_data registry. Insert data explicitly in each test function using raw SQL:
def _seed_data():
return [{"__tablename__": "my_table", "id": ..., ...}]
def test_migration_xyz(alembic_runner):
alembic_runner.migrate_up_to("prior_revision")
with alembic_runner.connection_executor.connection.connect() as conn:
for row in _seed_data():
table = row.pop("__tablename__")
cols = ", ".join(row.keys())
placeholders = ", ".join(f":{k}" for k in row.keys())
conn.execute(sa.text(f"INSERT INTO {table} ({cols}) VALUES ({placeholders})"), row)
conn.commit()This keeps fixture data scoped to the specific migration test and prevents pollution of test_up_down_consistency's round-trip cycle.