Support SQLAlchemy 2 database operations - #719
Conversation
PR Summary by QodoSupport SQLAlchemy 2 database operations
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1.
|
|
Addressed the two review findings in b791edb: legacy keyword, flat-list and scalar positional parameters are normalized, and the documentation now distinguishes SQLAlchemy 1.3 outer-transaction behavior from 1.4/2.x. Added regression tests for both findings (14 parameter cases failed before the fix). The initial database CI also exposed two test setup issues, fixed in 9da2d4f: a second MySQL setup query still passed a raw string to Local full suites pass with SQLAlchemy 2.0/1.4 (674 tests each) and 1.3 (650 tests, with unsupported future-mode cases skipped). The latest test-only follow-up was rerun on 2.0 with 674 passed. The updated upstream database/platform CI is pending. |
Coverage Report for CI Build 35565880800Coverage increased (+0.05%) to 92.169%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
|
The |
Fixes #648.
SQLAlchemy 2 removes
Engine.execute()and rejects raw SQL strings passed toConnection.execute(). As a result, petl rejects engines and fails to read/write through connections; sessions additionally run into autobegun transaction conflicts.Recognize engines without the removed method, execute driver SQL through
exec_driver_sql()when available, and retainexecute()for SQLAlchemy expressions and older versions. Session SQL strings usetext(). Centralize transaction handling so committed operations handle autobegun transactions, roll back on failure, and use the Session's own commit/rollback methods.commit=Falseleaves transactions under caller control. Internally opened connections and streaming results are released on completion, failure or iterator close.Remove the
<2.0bound from the database extra/test requirements and update both MySQL tests' raw SQL calls. Reset the PostgreSQL fixture before its named-cursor case, because the preceding Session case now correctly persists its final row. Document parameter styles, transaction ownership and iterator cleanup.Compatibility note:
commit=Truecommits the Session through its own API and commits an active connection transaction on SQLAlchemy 1.4/2.x. SQLAlchemy 1.3 connections retain their historical subtransaction behavior when an outer transaction is already active, leaving that outer commit/rollback to the caller. This is documented and tested separately fromcommit=False, which leaves transaction control to the caller across all versions. Raw strings on an engine/connection use driver parameters; legacy keyword, flat-list and scalar positional forms are normalized for modern execution APIs. Sessions use SQLAlchemy named binds.Validation (Windows, Python 3.12.14):
commit=True.E741in_hasmethodsexcluded. Staged diff check passes.[db]into a fresh environment selected SQLAlchemy 2.0.54. Outside the checkout, the installed package persisted an Engine write and Session append and read both rows back;pip checkpassed.The local skips include optional dependencies and external database tests. The runs emitted existing missing-driver/cursor-cleanup warnings; 1.3 also emits a Python 3.12 deprecation warning. Live MySQL/PostgreSQL, other Python versions and the documentation build were not tested locally; the existing upstream CI includes database services and the wider platform matrix.
Upstream validation on
9da2d4f: Test Changes passed all 27 jobs, including the database/platform matrix and documentation build; CodeQL also passed. The initial database CI failures were resolved by updating the remaining MySQL setup query and resetting the PostgreSQL named-cursor fixture after the Session case.