2.0.53
Released: September 14, 2026
orm
-
[orm] [bug] Fixed issue where an expression passed to
_orm.with_expression()that embedded a_sql.select(), such as a correlated_sql.exists(), would fail to populate the attribute correctly on the second and subsequent executions of an otherwise identical statement, when the_orm.query_expression()attribute was loaded by a relationship loader that emits a second query, i.e._orm.selectinload(),_orm.lazyload()or_orm.immediateload().References: #13560
-
[orm] [bug] Fixed memory issue where mapped classes, along with their
Tableand_orm.Mapperobjects, would not be garbage collected after the_orm.registryin which they were mapped had been disposed and dereferenced. The issue would occur for mappings that made use of_orm.relationship()together with constructs such as anIndexestablished against an ORM-annotated expression.References: #13566
-
[orm] [bug] Fixed issue where pickling an ORM object that had an instance level lazy loader established, such as when the
_orm.raiseload()option is used, would emit a spurious warning regarding the loader containing additional criteria, if the object had itself been unpickled from a previous serialization. This would occur for objects that cross more than one serialization boundary, such as when using multiprocessing.References: #13574
-
[orm] [bug] Fixed issue where calling
_orm.aliased()against an existing_orm.aliased()construct, without passing an explicit selectable, would disregard the selectable of the existing construct and produce an alias of the mapped table instead, if that selectable were anything other than a table or a plain subquery, leading to incorrect results and/or non-working queries.This includes
_orm.aliased()against a_orm.with_polymorphic()construct, which would previously produce an alias of the base mapped class only, discarding the polymorphic selectable and additional mappers. The new construct now retains these, so that criteria against subclass attributes and theinnerjoinandselectableparameters of_orm.with_polymorphic()take effect, and subclass columns are loaded up front. The SQL rendered for these constructs now includes the polymorphic selectable. -
[orm] [bug] Fixed issue where using
_orm.aliased()with both the_orm.aliased.nameand_orm.aliased.flatparameters, against an entity that is mapped to a join which includes anonymously named aliases, would embed the anonymous name symbol within the names generated for each element of the join, producing unusable SQL. An anonymously named element of the join is now aliased anonymously.References: #13583
engine
-
[engine] [bug] [asyncio] [pool] Fixed issue where a DBAPI connection would be left open and unreachable if an exception were raised within the
_events.PoolEvents.connect()or_events.PoolEvents.first_connect()event handlers, which is whereDialect.initialize()runs. The connection had been created but not yet associated with anything that could close it, so it was neither returned to the pool nor closed. For an asyncio driver in particular this could leak a server-side session for the life of the process, as the garbage collector is not able to close a connection that requires the event loop.References: #13548
sql
-
[sql] [bug] Fixed issue where calling
_sql.CTE.alias()on a_sql.CTEthat was itself produced by_sql.CTE.alias()would render SQL that referred to the name of the intermediate alias, which is not present in the WITH clause, rather than to the name of the original CTE, producing invalid SQL.References: #13583
schema
-
[schema] [bug] Fixed issue where reflecting a table with a foreign key constraint that names the same source column more than once, such as
FOREIGN KEY (a, a) REFERENCES r (b, c)which is accepted by backends such as PostgreSQL, would raiseArgumentErrorand fail the reflection of the entire table. AsForeignKeyConstrainthas no representation for this form, the constraint is now skipped with a warning, in the same way as one that names columns which are not present in the table, so that the remainder of the table is still reflected.Note that in the SQLAlchemy 2.1 series, full support for reflecting and constructing foreign key constraints with duplicated source columns has been added, with no warnings or skips.
References: #13525
postgresql
-
[postgresql] [bug] Fixed bug in
_reflection.Inspector.get_schema_names()for PostgreSQL where the query used to exclude system schemas relied onNOT LIKE 'pg_%', which treats the underscore as a SQLLIKEwildcard rather than a literal character. This caused user-created schemas that happen to start with "pg" followed by any other character, such aspgsqlorpgstats, to be silently excluded along with actual system schemas likepg_catalog. Pull request courtesy Evan Rusackas.References: #13472
mysql
-
[mysql] [bug] Ensure that CREATE TABLE DDL statements for MySQL and MariaDB dialects render the table options in a deterministic order. Previously the order could change depending on the Python seed.
References: #13523
sqlite
-
[sqlite] [usecase] [reflection] Implemented
_engine.Inspector.get_table_options()for the SQLite dialect, which previously raisedNotImplementedError. The method returns thesqlite_with_rowidandsqlite_strictdialect options for a table that was created using theWITHOUT ROWIDand / orSTRICTkeywords. As a result, these keywords are now also present in_schema.Table.kwargsfor a_schema.Tablethat is reflected using autoload, so that a table which is recreated from its reflected form, such as by Alembic's batch migration mode, renders the keywords again rather than silently dropping them.References: #13543
-
[sqlite] [bug] [reflection] Fixed issue in SQLite reflection where the name of a
PRIMARY KEY,UNIQUEorFOREIGN KEYconstraint would be reflected asNoneif theCONSTRAINT <name>clause were separated from the keyword that follows it by a newline rather than by spaces. As SQLite stores theCREATE TABLEstatement as it was originally typed, this affected tables created from hand-written DDL that spans multiple lines. The regular expressions used to recover constraint names, as well as theON UPDATE/ON DELETE,DEFERRABLEandINITIALLYoptions of a foreign key constraint, now accept any whitespace between tokens.References: #13528
-
[sqlite] [bug] [reflection] Reworked the regular expression that parses
FOREIGN KEYconstraints during SQLiteCREATE TABLEreflection so that the referred column list is matched unambiguously avoiding potential exponential backtracking. Pull request courtesy of Javid Khan.References: #13530
mssql
-
[mssql] [bug] [reflection] Fixed issue in SQL Server reflection where
TEXTandNTEXTcolumns would be reflected with a spurious length of 16 and 8, respectively. These are unlengthed LOB datatypes; the value originates from thesys.columns.max_lengthcolumn, which reports the size of the in-row LOB pointer rather than a character length for these types. The reflected_mssql.TEXTand_mssql.NTEXTtypes now have alengthofNone, so that a reflected table emits valid DDL when re-created, which previously failed with "Cannot specify a column width on data type text". Pull request courtesy Sam Debruyn.References: #13451
oracle
-
[oracle] [usecase] Added support for oracledb's new
terminate()feature, which allows for clean termination of an Oracle database connection in an asyncio context where the connection's state has fallen out of the event loop, and needs to be garbage collected. The feature is enabled automatically when using oracledb 26.0.0 or greater.References: #13578
tests
-
[tests] [bug] Altered the dialect reflection test
test_check_constraint_parenthesized_expressions()so that it does not convert the reflected constraint to lowercase, which interferes with some third party dialect's representation of reflected check constraints.References: #13521
misc
-
[bug] [installation] Added the
AUTHORSfile to the set of license files included in the built wheel, where previously only theLICENSEfile was present. As the text ofLICENSErefers toAUTHORSfor the list of copyright holders, the reference would not resolve for tools that inspect an installed distribution.References: #13518