Skip to content

Commit c467923

Browse files
committed
Fixes
1 parent 825f7cc commit c467923

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

conftest.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ def configure_psycopg():
2323
pass
2424

2525

26+
# ============================================================================
27+
# HELPER FUNCTIONS
28+
# ============================================================================
29+
30+
31+
async def _truncate_all_tables(ctx) -> None:
32+
"""Truncate all tables in the given context."""
33+
if ctx.apps:
34+
for model in ctx.apps.get_models_iterable():
35+
quote_char = model._meta.db.query_class.SQL_CONTEXT.quote_char
36+
await model._meta.db.execute_script(
37+
f"DELETE FROM {quote_char}{model._meta.db_table}{quote_char}" # nosec
38+
)
39+
40+
2641
# ============================================================================
2742
# PYTEST FIXTURES FOR TESTS
2843
# These fixtures provide different isolation patterns for test scenarios
@@ -57,6 +72,9 @@ async def db(db_module):
5772
Each test runs inside a transaction that gets rolled back at the end,
5873
providing isolation without the overhead of schema recreation.
5974
75+
For databases that don't support transactions (e.g., MySQL MyISAM),
76+
falls back to truncation cleanup.
77+
6078
This is the FASTEST isolation method - use for most tests.
6179
6280
Usage:
@@ -69,18 +87,25 @@ async def test_something(db):
6987
# Get connection from the context using its default connection
7088
conn = db_module.db()
7189

72-
# Start a savepoint/transaction
73-
transaction = conn._in_transaction()
74-
await transaction.__aenter__()
75-
76-
try:
90+
# Check if the database supports transactions
91+
if conn.capabilities.supports_transactions:
92+
# Start a savepoint/transaction
93+
transaction = conn._in_transaction()
94+
await transaction.__aenter__()
95+
96+
try:
97+
yield db_module
98+
finally:
99+
# Rollback the transaction (discards all changes made during test)
100+
class _RollbackException(Exception):
101+
pass
102+
103+
await transaction.__aexit__(_RollbackException, _RollbackException(), None)
104+
else:
105+
# For databases without transaction support (e.g., MyISAM),
106+
# fall back to truncation cleanup
77107
yield db_module
78-
finally:
79-
# Rollback the transaction (discards all changes made during test)
80-
class _RollbackException(Exception):
81-
pass
82-
83-
await transaction.__aexit__(_RollbackException, _RollbackException(), None)
108+
await _truncate_all_tables(db_module)
84109

85110

86111
@pytest_asyncio.fixture(scope="function")
@@ -148,14 +173,7 @@ async def test_with_transactions(db_truncate):
148173
# Table truncated after test
149174
"""
150175
yield db_module
151-
152-
# Truncate all tables after the test using context's apps
153-
if db_module.apps:
154-
for model in db_module.apps.get_models_iterable():
155-
quote_char = model._meta.db.query_class.SQL_CONTEXT.quote_char
156-
await model._meta.db.execute_script(
157-
f"DELETE FROM {quote_char}{model._meta.db_table}{quote_char}" # nosec
158-
)
176+
await _truncate_all_tables(db_module)
159177

160178

161179
# ============================================================================

0 commit comments

Comments
 (0)