Summary
A Database constructed from a database Engine does not end up in the same connection/transaction state as one constructed from a URL. Code that relies on nested transactions / savepoints then breaks depending on how the Database was created.
This is related to the change to initialization in #46. When a Database is created from an existing engine, it may have an underlying transaction open and inaccessible (as it's held elsewhere). The URL path initializes everything from scratch.
When initializing from an existing engine, constructing a Database and then running operations that use savepoints (e.g. SQLAlchemy begin_nested()) fails with:
sqlalchemy.exc.InternalError: (psycopg.errors.NoActiveSqlTransaction)
SAVEPOINT can only be used in transaction blocks
Passing a URL avoids the error. Surfaced in the mapboard.topology-manager test suite (tests/map_areas/test_map_areas.py).
Likely cause
When a new Database object is created, refresh its connection and transaction state so behavior is consistent regardless of whether it was built from a URL or an existing Engine. A nested-transaction/savepoint test across both construction paths would be ideal (cf. the existing test_engine_reuse.py).
Summary
A
Databaseconstructed from a database Engine does not end up in the same connection/transaction state as one constructed from a URL. Code that relies on nested transactions / savepoints then breaks depending on how theDatabasewas created.This is related to the change to initialization in #46. When a
Databaseis created from an existing engine, it may have an underlying transaction open and inaccessible (as it's held elsewhere). The URL path initializes everything from scratch.When initializing from an existing engine, constructing a
Databaseand then running operations that use savepoints (e.g. SQLAlchemybegin_nested()) fails with:Passing a
URLavoids the error. Surfaced in themapboard.topology-managertest suite (tests/map_areas/test_map_areas.py).Likely cause
When a new
Databaseobject is created, refresh its connection and transaction state so behavior is consistent regardless of whether it was built from a URL or an existingEngine. A nested-transaction/savepoint test across both construction paths would be ideal (cf. the existingtest_engine_reuse.py).