Skip to content

Commit

Permalink
fix: Only set AUTOCOMMIT isolation level during internal fixture setu…
Browse files Browse the repository at this point in the history
…p which requires it.
  • Loading branch information
DanCardin committed Feb 24, 2023
1 parent 4cc1847 commit fd8d313
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pytest-mock-resources"
version = "2.6.9"
version = "2.6.10"
description = "A pytest plugin for easily instantiating reproducible mock resources."
authors = [
"Omar Khan <oakhan3@gmail.com>",
Expand Down
11 changes: 6 additions & 5 deletions src/pytest_mock_resources/container/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ def check_fn(self):
s.close()


def get_sqlalchemy_engine(
config, database_name, isolation_level="AUTOCOMMIT", async_=False, **engine_kwargs
):
def get_sqlalchemy_engine(config, database_name, async_=False, autocommit=False, **engine_kwargs):
# For backwards compatibility, our hardcoded default is psycopg2, and async fixtures
# will not work with psycopg2, so we instead swap the default to the preferred async driver.
drivername = config.drivername
Expand All @@ -107,11 +105,14 @@ def get_sqlalchemy_engine(
database=database_name,
)

if autocommit:
engine_kwargs["isolation_level"] = "AUTOCOMMIT"

if getattr(url.get_dialect(), "is_async", None):
from sqlalchemy.ext.asyncio import create_async_engine

engine = create_async_engine(url, **engine_kwargs, isolation_level=isolation_level)
engine = create_async_engine(url, **engine_kwargs)
else:
engine = sqlalchemy.create_engine(url, **engine_kwargs, isolation_level=isolation_level)
engine = sqlalchemy.create_engine(url, **engine_kwargs)

return engine
12 changes: 9 additions & 3 deletions src/pytest_mock_resources/fixture/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ def _sync_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):
conn.close()
root_engine.dispose()

root_engine = cast(Engine, get_sqlalchemy_engine(pmr_config, pmr_config.root_database))
root_engine = cast(
Engine, get_sqlalchemy_engine(pmr_config, pmr_config.root_database, autocommit=True)
)
with root_engine.connect() as root_conn:
with root_conn.begin() as trans:
template_database, template_manager, engine_manager = create_engine_manager(
Expand All @@ -136,7 +138,9 @@ def _sync_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):

# Everything below is normal per-test context. We create a brand new database/engine/manager
# distinct from what might have been used for the template database.
root_engine = cast(Engine, get_sqlalchemy_engine(pmr_config, pmr_config.root_database))
root_engine = cast(
Engine, get_sqlalchemy_engine(pmr_config, pmr_config.root_database, autocommit=True)
)
with root_engine.connect() as root_conn:
with root_conn.begin() as trans:
database_name = _produce_clean_database(root_conn, createdb_template=template_database)
Expand All @@ -148,7 +152,9 @@ def _sync_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):


async def _async_fixture(pmr_config, engine_manager_kwargs, engine_kwargs):
root_engine = get_sqlalchemy_engine(pmr_config, pmr_config.root_database, async_=True)
root_engine = get_sqlalchemy_engine(
pmr_config, pmr_config.root_database, async_=True, autocommit=True
)

root_conn = await async_retry(root_engine.connect, retries=DEFAULT_RETRIES)
await root_conn.close()
Expand Down
4 changes: 3 additions & 1 deletion src/pytest_mock_resources/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ def pytest_sessionfinish(session, exitstatus):
try:
container = docker.container.inspect(container_id)
except Exception:
warnings.warn(f"Unrecognized container {container_id}")
warnings.warn(
f"Unrecognized container {container_id}. You may need to manually delete/edit {fn}"
)
else:
try:
container.kill()
Expand Down
10 changes: 10 additions & 0 deletions tests/fixture/test_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,13 @@ def test_createdb_template(createdb_template_pg):
"""Assert successful usage of a fixture which sets the `createdb_template` argument."""
with createdb_template_pg.begin() as conn:
conn.execute(Thing.__table__.insert().values({"id": 1}))


nested_transaction = create_postgres_fixture(Base)


def test_nested_transaction(nested_transaction):
"""Assert success with a fixture relying on being in a transaction (like SAVEPOINT)."""
with nested_transaction.begin() as conn:
with conn.begin_nested():
conn.execute(Thing.__table__.insert().values({"id": 1}))

0 comments on commit fd8d313

Please sign in to comment.