Skip to content

Update sqlalchemy to 2.0.54 - #1495

Open
pyup-bot wants to merge 1 commit into
masterfrom
pyup-update-sqlalchemy-0.9.7-to-2.0.54
Open

pyup-bot wants to merge 1 commit into
masterfrom
pyup-update-sqlalchemy-0.9.7-to-2.0.54

Conversation

@pyup-bot

Copy link
Copy Markdown
Collaborator

This PR updates sqlalchemy from 0.9.7 to 2.0.54.

Changelog

2.0.54

:released: September 15, 2026

 .. change::
     :tags: bug, platform
     :tickets: 13592

     Fixed issue where the Cython extensions were compiled without the
     ``freethreading_compatible`` directive, so that they did not declare
     themselves as safe to run without the GIL.  On a free-threaded Python
     interpreter such as Python 3.13t or 3.14t, importing SQLAlchemy would
     cause the interpreter to re-enable the GIL, emitting a
     ``RuntimeWarning``.  The directive is now set when building for Python
     3.13 and above, and a test has been added which confirms that importing
     SQLAlchemy on a free-threaded build does not enable the GIL.

 .. change::
     :tags: change, platform

     Binary wheels are no longer built for Python 3.7.  PyPI now rejects wheel
     files whose filename does not begin with the normalized project name, and
     the packaging tools that can be installed on Python 3.7 do not produce
     such a filename.  As a result, SQLAlchemy 2.0.44 was the last release to
     publish Python 3.7 wheels to PyPI, and releases 2.0.45 and later have
     been available on Python 3.7 only as a source distribution; the wheel
     builds for Python 3.7 are now removed.  Python 3.7 remains supported by
     the 2.0 series.

.. changelog::

2.0.53

:released: September 14, 2026

 .. change::
     :tags: bug, mssql, reflection
     :tickets: 13451
     :versions: 2.1.0rc1

     Fixed issue in SQL Server reflection where ``TEXT`` and ``NTEXT`` columns
     would be reflected with a spurious length of 16 and 8, respectively.  These
     are unlengthed LOB datatypes; the value originates from the
     ``sys.columns.max_length`` column, which reports the size of the in-row LOB
     pointer rather than a character length for these types.  The reflected
     :class:`_mssql.TEXT` and :class:`_mssql.NTEXT` types now have a ``length``
     of ``None``, 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.

 .. change::
     :tags: bug, postgresql
     :tickets: 13472
     :versions: 2.1.0rc1

     Fixed bug in :meth:`_reflection.Inspector.get_schema_names` for
     PostgreSQL where the query used to exclude system schemas relied on
     ``NOT LIKE 'pg_%'``, which treats the underscore as a SQL ``LIKE``
     wildcard rather than a literal character. This caused user-created
     schemas that happen to start with "pg" followed by any other
     character, such as ``pgsql`` or ``pgstats``, to be silently excluded
     along with actual system schemas like ``pg_catalog``. Pull request
     courtesy Evan Rusackas.

 .. change::
     :tags: bug, installation
     :tickets: 13518
     :versions: 2.1.0rc1

     Added the ``AUTHORS`` file to the set of license files included in the
     built wheel, where previously only the ``LICENSE`` file was present. As
     the text of ``LICENSE`` refers to ``AUTHORS`` for the list of copyright
     holders, the reference would not resolve for tools that inspect an
     installed distribution.

 .. change::
     :tags: bug, tests
     :tickets: 13521
     :versions: 2.1.0rc1

     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.

 .. change::
     :tags: bug, mysql
     :tickets: 13523
     :versions: 2.1.0rc1

     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.

 .. change::
     :tags: bug, schema
     :tickets: 13525

     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 raise :class:`.ArgumentError` and fail the reflection of the entire
     table.  As :class:`.ForeignKeyConstraint` has 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.

 .. change::
     :tags: bug, sqlite, reflection
     :tickets: 13528
     :versions: 2.1.0rc1

     Fixed issue in SQLite reflection where the name of a ``PRIMARY KEY``,
     ``UNIQUE`` or ``FOREIGN KEY`` constraint would be reflected as ``None`` if
     the ``CONSTRAINT <name>`` clause were separated from the keyword that
     follows it by a newline rather than by spaces.  As SQLite stores the
     ``CREATE TABLE`` statement 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 the
     ``ON UPDATE`` / ``ON DELETE``, ``DEFERRABLE`` and ``INITIALLY`` options of
     a foreign key constraint, now accept any whitespace between tokens.

 .. change::
     :tags: bug, sqlite, reflection
     :tickets: 13530
     :versions: 2.1.0rc2

     Reworked the regular expression that parses ``FOREIGN KEY`` constraints
     during SQLite ``CREATE TABLE`` reflection so that the referred column list
     is matched unambiguously avoiding potential exponential backtracking.
     Pull request courtesy of Javid Khan.

 .. change::
     :tags: usecase, sqlite, reflection
     :tickets: 13543
     :versions: 2.1.0rc2

     Implemented :meth:`_engine.Inspector.get_table_options` for the SQLite
     dialect, which previously raised ``NotImplementedError``.  The method
     returns the ``sqlite_with_rowid`` and ``sqlite_strict`` dialect options
     for a table that was created using the ``WITHOUT ROWID`` and / or
     ``STRICT`` keywords.  As a result, these keywords are now also present in
     :attr:`_schema.Table.kwargs` for a :class:`_schema.Table` that 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.

 .. change::
     :tags: bug, engine, pool, asyncio
     :tickets: 13548
     :versions: 2.1.0rc1

     Fixed issue where a DBAPI connection would be left open and unreachable
     if an exception were raised within the :meth:`_events.PoolEvents.connect`
     or :meth:`_events.PoolEvents.first_connect` event handlers, which is
     where :meth:`.Dialect.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.

 .. change::
     :tags: bug, orm
     :tickets: 13560
     :versions: 2.1.0rc2

     Fixed issue where an expression passed to :func:`_orm.with_expression`
     that embedded a :func:`_sql.select`, such as a correlated
     :func:`_sql.exists`, would fail to populate the attribute correctly on
     the second and subsequent executions of an otherwise identical
     statement, when the :func:`_orm.query_expression` attribute was loaded
     by a relationship loader that emits a second query, i.e.
     :func:`_orm.selectinload`, :func:`_orm.lazyload` or
     :func:`_orm.immediateload`.

 .. change::
     :tags: bug, orm
     :tickets: 13566
     :versions: 2.1.0rc2

     Fixed memory issue where mapped classes, along with their
     :class:`.Table` and :class:`_orm.Mapper` objects, would not be garbage
     collected after the :class:`_orm.registry` in which they were mapped had
     been disposed and dereferenced.  The issue would occur for mappings that
     made use of :func:`_orm.relationship` together with constructs such as an
     :class:`.Index` established against an ORM-annotated expression.

 .. change::
     :tags: bug, orm
     :tickets: 13574
     :versions: 2.1.0

     Fixed issue where pickling an ORM object that had an instance level lazy
     loader established, such as when the :func:`_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.

 .. change::
     :tags: usecase, oracle
     :tickets: 13578
     :versions: 2.1.0

     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.

 .. change::
     :tags: bug, orm
     :tickets: 13583, 13584
     :versions: 2.1.0

     Fixed issue where calling :func:`_orm.aliased` against an existing
     :func:`_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 :func:`_orm.aliased` against a :func:`_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 the ``innerjoin`` and ``selectable`` parameters of
     :func:`_orm.with_polymorphic` take effect, and subclass columns are loaded
     up front.  The SQL rendered for these constructs now includes the
     polymorphic selectable.

 .. change::
     :tags: bug, sql
     :tickets: 13583
     :versions: 2.1.0

     Fixed issue where calling :meth:`_sql.CTE.alias` on a :class:`_sql.CTE`
     that was itself produced by :meth:`_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.

 .. change::
     :tags: bug, orm
     :tickets: 13583
     :versions: 2.1.0

     Fixed issue where using :func:`_orm.aliased` with both the
     :paramref:`_orm.aliased.name` and :paramref:`_orm.aliased.flat`
     parameters, 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.

.. changelog::

2.0.52

:released: August 11, 2026

 .. change::
     :tags: bug, postgresql, reflection
     :tickets: 13157
     :versions: 2.1.0rc1

     Fixed reflection of PostgreSQL CHECK constraints where an expression made
     up of multiple parenthesized sub-expressions, such as ``(x IS NULL OR y IS
     NULL) AND (x IS NULL OR y IS NULL)``, would have its leading and trailing
     parentheses incorrectly stripped, producing an unbalanced and
     syntactically invalid reflected expression.  Pull request courtesy
     Shaurya Singh.

 .. change::
     :tags: bug, mssql
     :tickets: 13380
     :versions: 2.1.0b3

     Tightened the construction of the ODBC connection string in the pyodbc
     connector (as well as the mssql-python connector in 2.1) so that the
     driver name, the names of pass-through connection parameters, and values
     containing ``}`` are brace-quoted.  Previously a ``}`` in the driver name
     or in a pass-through value, or a ``;`` in the name of a pass-through
     parameter, could close the surrounding token early and allow the
     remainder of the string to be interpreted as additional connection
     attributes.  Pull request courtesy dxbjavid.

 .. change::
   :tags: bug, orm declarative
   :tickets: 13386
   :versions: 2.1.0b3

   Fixed issue where using :pep:`593` ``Annotated`` wrapping a :pep:`695`
   ``type`` alias, such as ``Annotated[SomeTypeAlias, mapped_column()]``,
   would crash with ``AttributeError: __value__``. The internal
   ``is_pep695()`` check incorrectly identified the ``Annotated`` type as a
   PEP 695 type alias due to a quirk in ``Annotated.__origin__`` returning
   the first type argument rather than ``Annotated`` itself.

 .. change::
     :tags: bug, tests
     :tickets: 13392
     :versions: 2.1.0b3

     Fixed class-scoped pytest fixtures that were defined as instance methods
     using ``self``, which is deprecated as of pytest 9.1 and will be removed in
     pytest 10. Fixtures are now decorated with a compatibility ``classmethod``
     decorator and use ``cls`` as the first parameter.

 .. change::
     :tags: bug, sql
     :tickets: 13396
     :versions: 2.1.0b3

     Fixed issue where :meth:`_sql.Select.get_final_froms` would emit a
     deprecation warning when the statement made use of the PostgreSQL-specific
     expression argument to :meth:`_sql.Select.distinct`; the same spurious
     warning would be emitted when stringifying such a statement without
     explicitly using a PostgreSQL dialect.  The fix ensures that this 1.4-era
     warning is suppressed under both 2.0 and 2.1.

     Note that under SQLAlchemy 2.1, passing an expression to
     :meth:`_sql.Select.distinct` is deprecated overall, and is replaced by a
     new PostgreSQL-specific construct (see :ticket:`12342`).

 .. change::
     :tags: bug, sqlite
     :tickets: 13419
     :versions: 2.1.0rc1

     Reworked the regular expression that detects inline ``UNIQUE`` column
     constraints during SQLite ``CREATE TABLE`` reflection so that the
     whitespace separating a column's type from a following clause is matched
     unambiguously.  The previous pattern had three overlapping quantifiers
     that could each consume a space character, so a column definition
     carrying a long run of whitespace in the stored schema made
     :meth:`_reflection.Inspector.get_unique_constraints` spend cubic time
     backtracking before returning.  Fix courtesy of Javid Khan.

 .. change::
     :tags: bug, sql
     :tickets: 13424
     :versions: 2.1.0rc1

     Fixed an issue in :class:`.Numeric` where the
     :paramref:`.Numeric.decimal_return_scale` parameter was ignored when the
     DBAPI does not support native decimal objects (i.e.
     ``dialect.supports_native_decimal`` is ``False``).  In this path the result
     processor was computing the conversion scale from
     :paramref:`.Numeric.scale` directly, bypassing
     :paramref:`.Numeric.decimal_return_scale` entirely.  The behavior now
     matches :class:`.Float`, which already used the correct
     ``_effective_decimal_return_scale`` property. Pull request courtesy Kadir
     Can Ozden.

 .. change::
     :tags: bug, postgresql
     :tickets: 13429
     :versions: 2.1.0rc1

     Fixed bug in the PostgreSQL dialect where a single quote in a sequence,
     table, or schema name, such as one supplied via a ``schema_translate_map``
     or an explicit :class:`.Sequence`, could result in a malformed
     ``nextval()`` statement. The quote is now properly escaped. Pull request
     courtesy dxbjavid.

 .. change::
     :tags: bug, orm
     :tickets: 13439
     :versions: 2.1.0rc1

     Fixed a result-column misalignment bug in ORM-enabled UPDATE statements
     where ``synchronize_session="fetch"`` is in use, either explicitly or
     because the statement uses constructs such as CTEs that implicitly select
     for it.  Columns in rows returned by ``.returning()`` could be returned
     under incorrect keys (e.g. ``row[SomeClass.a]`` returning the value of
     a different column), a problem most likely to manifest under concurrent
     workloads.  ORM DELETE statements were not affected.

 .. change::
     :tags: bug, sql
     :tickets: 13448
     :versions: 2.1.0rc1

     Added auditing to the test suite which exercises the literal execute
     processors across all datatypes and dialects to ensure that string input is
     either appropriately rejected or correctly escaped.  Literal execute
     processors are invoked when the :paramref:`.bindparam.literal_execute`
     parameter is used with an explicit :func:`.bindparam` object, which
     overrides DBAPI-native bind handling to render the value inline with the
     statement instead. Datatypes that were updated include the originally
     reported SQL Server ``Uuid`` / ``UNIQUEIDENTIFIER`` rendering which now
     escapes properly, the :class:`.JSONPATH` type that's currently
     PostgreSQL-only, and a full family of numeric types stemming from the
     :class:`_types.Float` and :class:`_types.Numeric` bases which now coerce
     the value to a number, rejecting non-numeric input.  Thanks to Javid Khan
     for helping to identify the issue.

 .. change::
     :tags: bug, platform
     :tickets: 13477
     :versions: 2.1.0rc1

     Python 3.15 support has been added and tested, including minimal changes
     for full compatibility.

 .. change::
     :tags: bug, schema
     :tickets: 13481
     :versions: 2.1.0rc1

     Fixed an issue where :meth:`_schema.Table.to_metadata` reused column
     default and on-update objects, causing the defaults on the original
     columns to refer to the copied columns. Default generators, including
     sequences, and server-side defaults are now copied and remain associated
     with their respective columns and metadata collections. Applications that
     inspected these objects will now see distinct defaults on the copied table
     instead of the objects owned by the original table.  Pull request courtesy
     Goutam Adwant.

 .. change::
     :tags: bug, orm
     :tickets: 13485
     :versions: 2.1.0rc1

     Fixed bug where a failed :meth:`_orm.Session.bulk_insert_mappings`,
     :meth:`_orm.Session.bulk_update_mappings` or
     :meth:`_orm.Session.bulk_save_objects` call could leave the
     :class:`_orm.Session` permanently in a "flushing" state, such as when the
     transaction could not be begun because a previous flush had left it
     needing a rollback.  Unlike :meth:`_orm.Session.flush`, the bulk methods
     set the internal flushing flag and began the transaction outside of the
     ``try``/``finally`` block that resets it, so that neither
     :meth:`_orm.Session.rollback` nor :meth:`_orm.Session.close` would clear
     it, and every subsequent flush would raise ``InvalidRequestError: Session
     is already flushing``.  Pull request courtesy Hamody We.

 .. change::
     :tags: bug, orm
     :tickets: 13493
     :versions: 2.1.0rc1

     Fixed issue where unpickling an ORM object that were loaded using loader
     options making use of wildcard tokens, such as :func:`_orm.load_only` or
     :func:`_orm.raiseload` with ``"*"``, would fail with ``KeyError`` or
     ``IndexError`` if the process doing the unpickling had not yet constructed
     a loader path making use of that same token.  This would typically be
     observed when the object were unpickled in a separate process, such as
     with the ``spawn`` or ``forkserver`` multiprocessing start methods, the
     latter of which became the default on POSIX platforms as of Python 3.14.
     The internal collection of these tokens is now established up front, so
     that it is identical in every process.

 .. change::
     :tags: bug, orm
     :tickets: 13493
     :versions: 2.1.0rc1

     Fixed issue where a string ending in ``"*"`` passed to a
     :class:`_orm.Load` strategy method, such as
     ``Load(A).joinedload("bs.*")``, would bypass the check which rejects
     string attribute names in loader options, silently producing a loader
     path that matched nothing.  Such a string now raises
     :class:`.ArgumentError` with the same message given for any other
     string attribute name.  The bare wildcard ``"*"``, as in
     ``Load(A).lazyload("*")``, continues to be accepted.

 .. change::
     :tags: bug, orm
     :tickets: 6274
     :versions: 2.1.0rc1

     Calling :func:`_orm.aliased` against a :func:`_sql.select` or
     :func:`_sql.union` / :class:`_sql.CompoundSelect` construct, which
     previously failed with an obscure ``AttributeError`` regarding a missing
     ``.mapper`` attribute, now raises when using SQLAlchemy 2.1, and emits a
     deprecation warning under SQLAlchemy 2.0 as it coerces the construct into a
     subquery instead.  This matches the behavior of other similar implicit
     SELECT-to-FROM coercions.  Pull request courtesy Rens Groothuijsen.

.. changelog::

2.0.51

:released: June 15, 2026

 .. change::
     :tags: bug, sql
     :tickets: 10827
     :versions: 2.1.0b3

     Fixed issue where :class:`_sql.StatementLambdaElement` would proxy
     attribute access through the cached "expected" expression rather than the
     resolved expression, causing stale closure-bound parameter values to be
     used when a lambda statement was extended with non-lambda criteria such as
     an additional ``.where()`` clause.  Courtesy cjc0013.

 .. change::
     :tags: bug, orm
     :tickets: 13207
     :versions: 2.1.0b3

     Fixed issue where :func:`_orm.subqueryload` combined with
     :meth:`.PropComparator.of_type` and :meth:`.PropComparator.and_` would
     silently drop the additional filter criteria, causing all related objects
     to be loaded instead of only those matching the filter.  The
     :class:`.LoaderCriteriaOption` was being constructed against the base
     entity rather than the effective entity indicated by
     :meth:`.PropComparator.of_type`.  Pull request courtesy Arya Rizky.

 .. change::
     :tags: bug, postgresql
     :tickets: 13355
     :versions: 2.1.0b3

     Repaired bug introduced in :ticket:`13229` where a two-phase
     transaction recovery would not return the correct transaction
     identifier when generating the identifiers using the ``xid()``
     method of the psycopg connection.

 .. change::
     :tags: bug, orm
     :tickets: 13356
     :versions: 2.1.0b3

     Fixed bug where a failure during ``tpc_prepare()`` within
     :meth:`_orm.Session.commit` for a two-phase session would raise
     :class:`.IllegalStateChangeError` instead of the original database
     exception.  The internal ``_prepare_impl()`` method's error handler
     was unable to invoke :meth:`_orm.SessionTransaction.rollback` due
     to a state-change guard, preventing proper cleanup and masking the
     underlying error.

 .. change::
     :tags: bug, postgresql
     :tickets: 13370
     :versions: 2.1.0b3

     Fixed regular expression in the pure Python hstore result processor,
     used when ``use_native_hstore=False`` is set, which could hang on
     malformed hstore text containing unterminated quoted segments with
     backslashes.  Pull request courtesy dxbjavid.

 .. change::
     :tags: bug, engine
     :tickets: 9427
     :versions: 2.1.0b3

     Fixed issue where :meth:`.Result.freeze` would lose track of ambiguous
     column names present in the original :class:`.CursorResult`, causing
     key-based access on the thawed result to silently return a value instead of
     raising :class:`.InvalidRequestError`.  The
     :class:`.SimpleResultMetaData` now accepts and propagates ambiguous key
     information so that frozen, thawed, and pickled results raise consistently
     for duplicate column names.  Pull request courtesy Saurabh Kohli.

.. changelog::

2.0.50

:released: May 24, 2026

 .. change::
     :tags: bug, sql
     :tickets: 10528
     :versions: 2.1.0b3

     Fixed issue where floor division (``//``) between a :class:`.Float` or
     :class:`.Numeric` numerator and an :class:`.Integer` denominator would omit
     the ``FLOOR()`` SQL wrapper on dialects where
     :attr:`.Dialect.div_is_floordiv` is ``True`` (the default, including
     PostgreSQL and SQLite).  ``FLOOR()`` is now applied if either the
     denominator or the numerator is a non-integer, so that expressions such as
     ``float_col // int_col`` render as ``FLOOR(float_col / int_col)`` instead
     of the incorrect ``float_col / int_col``.  Pull request courtesy r266-tech.

 .. change::
     :tags: bug, orm
     :tickets: 13203
     :versions: 2.1.0b3

     Fixed issue where using :func:`_orm.joinedload` with
     :meth:`.PropComparator.of_type` targeting a joined-table subclass combined
     with :meth:`.PropComparator.and_` referencing a column on that subclass
     would generate invalid SQL, where the subclass column was not adapted to
     the subquery alias.  Pull request courtesy Joaquin Hui Gomez.

 .. change::
     :tags: postgresql, bug
     :tickets: 13229
     :versions: 2.1.0b2

     Improve handling of two phase transaction identifiers for PostgreSQL
     when the identifier is provided by the user.
     As part of this change the psycopg dialect was updated to use the DBAPI
     two phase transaction API instead of executing the SQL directly.

 .. change::
     :tags: bug, sqlite
     :tickets: 13230
     :versions: 2.1.0b2

     Escape key and pragma values when utilizing the pysqlcipher dialect.

 .. change::
     :tags: bug, postgresql
     :tickets: 13241
     :versions: 2.1.0b3

     Fixed issue where the asyncpg driver could throw an insufficiently-handled
     exception ``InternalClientError`` under some circumstances, leading to
     connections not being properly marked as invalidated.



 .. change::
     :tags: bug, mysql, reflection
     :tickets: 13243
     :versions: 2.1.0b3

     Narrowed the scope of the internal workaround for MySQL bugs `88718
     <https://bugs.mysql.com/bug.php?id=88718>`_ and `#96365
     <https://bugs.mysql.com/bug.php?id=96365>`_ so that it is only applied
     where needed: MySQL 8.0.1 through 8.0.13 (where bug 88718 is present), and
     on systems with ``lower_case_table_names=2`` (where bug 96365 applies,
     typically macOS).  Previously the workaround was applied unconditionally
     for all MySQL 8.0+ versions, which caused a ``KeyError`` during foreign key
     reflection when the database user lacked SELECT privileges on referred
     tables.

 .. change::
     :tags: bug, orm
     :tickets: 13301
     :versions: 2.1.0b3

     Fixed issue where the presence of a :meth:`.SessionEvents.do_orm_execute`
     event hook would cause internal execution options such as ``yield_per`` and
     loader-specific state from the first ``orm_pre_session_exec`` pass to leak
     into the second pass, leading to errors when using relationship loaders
     such as :func:`.selectinload` and :func:`.immediateload`.  The execution
     options passed to the second compilation pass are now based on the original
     options plus only the explicit updates made via
     :meth:`.ORMExecuteState.update_execution_options` within the event hook.


 .. change::
     :tags: bug, mysql
     :tickets: 13306
     :versions: 2.1.0b3

     Fixed issue in aiomysql and asyncmy dialects that appears as of using
     pymysql 1.2.0; the dialects were not properly taking into account logic
     that detects the argument signature of pymysql's ``ping()`` method which
     was added as part of :ticket:`10492`.




 .. change::
     :tags: bug, postgresql
     :tickets: 13317
     :versions: 2.1.0b3

     Fixed issue where the :class:`.ExcludeConstraint` construct did not
     correctly forward the :paramref:`.ExcludeConstraint.info` parameter to
     the superclass, causing user-defined metadata to be lost. Pull request
     courtesy Wiktor Byrka.


 .. change::
     :tags: bug, orm
     :tickets: 13319
     :versions: 2.1.0b3

     Fixed issue where using :func:`_orm.with_polymorphic` on a leaf class (a
     subclass with no further descendants) or a non-inherited class would fail
     with an ``AttributeError`` when used in an ORM statement, due to
     :func:`_orm.configure_mappers` not being triggered implicitly. The fix
     ensures that :class:`.AliasedInsp` participates in the ``_post_inspect``
     hook, triggering mapper configuration during ORM statement compilation.


.. changelog::

2.0.49

:released: April 3, 2026

 .. change::
     :tags: postgresql, bug
     :tickets: 10902
     :versions: 2.1.0b2

     Fixed regular expression used when reflecting foreign keys in PostgreSQL to
     support escaped quotes in table names.
     Pull request courtesy of Austin Graham

 .. change::
     :tags: bug, oracle
     :tickets: 13150
     :versions: 2.1.0b2

     Fixed issue in Oracle dialect where the :class:`_oracle.RAW` datatype would
     not reflect the length parameter.   Pull request courtesy Daniel Sullivan.


 .. change::
     :tags: usecase, mssql
     :tickets: 13152
     :versions: 2.1.0b2

     Enhanced the ``aioodbc`` dialect to expose the ``fast_executemany``
     attribute of the pyodbc cursor.   This allows the ``fast_executemany``
     parameter to work with the ``mssql+aioodbc`` dialect.   Pull request
     courtesy Georg Sieber.

 .. change::
     :tags: bug, typing
     :tickets: 13167
     :versions: 2.1.0b2

     Fixed a typing issue where the typed members of :data:`.func` would return
     the appropriate class of the same name, however this creates an issue for
     typecheckers such as Zuban and pyrefly that assume :pep:`749` style
     typechecking even if the file states that it's a :pep:`563` file; they see
     the returned name as indicating the method object and not the class object.
     These typecheckers are actually following along with an upcoming test
     harness that insists on :pep:`749` style name resolution for this case
     unconditionally.  Since :pep:`749` is the way of the future regardless,
     differently-named type aliases have been added for these return types.


 .. change::
     :tags: bug, orm
     :tickets: 13176
     :versions: 2.1.0b2

     Fixed issue where :meth:`_orm.Session.get` would bypass the identity map
     and emit unnecessary SQL when ``with_for_update=False`` was passed,
     rather than treating it equivalently to the default of ``None``.
     Pull request courtesy of Joshua Swanson.

 .. change::
     :tags: bug, mssql, reflection
     :tickets: 13181, 13182
     :versions: 2.1.0b2

     Fixed regression from version 2.0.42 caused by :ticket:`12654` where the
     updated column reflection query would receive SQL Server "type alias" names
     for special types such as ``sysname``, whereas previously the base name
     would be received (e.g. ``nvarchar`` for ``sysname``), leading to warnings
     that such types could not be reflected and resulting in :class:`.NullType`,
     rather than the expected :class:`_mssql.NVARCHAR` for a type like ``sysname``.
     The column reflection query now joins ``sys.types`` a second time to look
     up the base type when the user type name is not present in
     :attr:`.MSDialect.ischema_names`, and both names are checked in
     :attr:`.MSDialect.ischema_names` for a match. Pull request courtesy Carlos
     Serrano.

 .. change::
     :tags: mssql, usecase
     :tickets: 13185
     :versions: 2.1.0b2

     Remove warning for SQL Server dialect when a new version is detected.
     The warning was originally added more than 15 years ago due to an unexpected
     value returned when using an old version of FreeTDS.
     The assumption is that since then the issue has been resolved, so make the
     SQL Server dialect behave like the other ones that don't have an upper bound
     check on the version number.

 .. change::
     :tags: bug, orm
     :tickets: 13193
     :versions: 2.1.0b2

     Fixed issue where chained :func:`_orm.joinedload` options would not be
     applied correctly when the final relationship in the chain is declared on a
     base mapper and accessed through a subclass mapper in a
     :func:`_orm.with_polymorphic` query. The path registry now correctly
     computes the natural path when a property declared on a base class is
     accessed through a path containing a subclass mapper, ensuring the loader
     option can be located during query compilation.

 .. change::
     :tags: bug, orm, inheritance
     :tickets: 13202
     :versions: 2.1.0b2

     Fixed issue where using :meth:`_orm.Load.options` to apply a chained loader
     option such as :func:`_orm.joinedload` or :func:`_orm.selectinload` with
     :meth:`_orm.PropComparator.of_type` for a polymorphic relationship would
     not generate the necessary clauses for the polymorphic subclasses. The
     polymorphic loading strategy is now correctly propagated when using a call
     such as ``joinedload(A.b).options(joinedload(B.c.of_type(poly)))`` to match
     the behavior of direct chaining e.g.
     ``joinedload(A.b).joinedload(B.c.of_type(poly))``.

 .. change::
     :tags: bug, orm, inheritance
     :tickets: 13209
     :versions: 2.1.0b2

     Fixed issue where using chained loader options such as
     :func:`_orm.selectinload` after :func:`_orm.joinedload` with
     :meth:`_orm.PropComparator.of_type` for a polymorphic relationship would
     not properly apply the chained loader option. The loader option is now
     correctly applied when using a call such as
     ``joinedload(A.b.of_type(poly)).selectinload(poly.SubClass.c)`` to eagerly
     load related objects.

.. changelog::

2.0.48

:released: March 2, 2026

 .. change::
     :tags: bug, engine
     :tickets: 13144
     :versions: 2.1.0b2

     Fixed a critical issue in :class:`.Engine` where connections created in
     conjunction with the :meth:`.DialectEvents.do_connect` event listeners
     would receive shared, mutable collections for the connection arguments,
     leading to a variety of potential issues including unlimited growth of the
     argument list as well as elements within the parameter dictionary being
     shared among concurrent connection calls.  In particular this could impact
     do_connect routines making use of complex mutable authentication
     structures.

.. changelog::

2.0.47

:released: February 24, 2026

 .. change::
     :tags: bug, orm
     :tickets: 13104
     :versions: 2.1.0b2

     Fixed issue when using ORM mappings with Python 3.14's :pep:`649` feature
     that no longer requires "future annotations", where the ORM's introspection
     of the ``__init__`` method of mapped classes would fail if non-present
     identifiers in annotations were present.  The vendored ``getfullargspec()``
     method has been amended to use ``Format.FORWARDREF`` under Python 3.14 to
     prevent resolution of names that aren't present.


 .. change::
     :tags: bug, postgresql
     :tickets: 13105
     :versions: 2.1.0b2

     Fixed an issue in the PostgreSQL dialect where foreign key constraint
     reflection would incorrectly swap or fail to capture ``onupdate`` and
     ``ondelete`` values when these clauses appeared in a different order than
     expected in the constraint definition. This issue primarily affected
     PostgreSQL-compatible databases such as CockroachDB, which may return ``ON
     DELETE`` before ``ON UPDATE`` in the constraint definition string. The
     reflection logic now correctly parses both clauses regardless of their
     ordering.

 .. change::
     :tags: bug, postgresql
     :tickets: 13107
     :versions: 2.1.0b2

     Fixed issue in the :ref:`engine_insertmanyvalues` feature where using
     PostgreSQL's ``ON CONFLICT`` clause with
     :paramref:`_dml.Insert.returning.sort_by_parameter_order` enabled would
     generate invalid SQL when the insert used an implicit sentinel (server-side
     autoincrement primary key). The generated SQL would incorrectly declare a
     sentinel counter column in the ``imp_sen`` table alias without providing
     corresponding values in the ``VALUES`` clause, leading to a
     ``ProgrammingError`` indicating column count mismatch. The fix allows batch
     execution mode when ``embed_values_counter`` is active, as the embedded
     counter provides the ordering capability needed even with upsert behaviors,
     rather than unnecessarily downgrading to row-at-a-time execution.

 .. change::
     :tags: bug, postgresql
     :tickets: 13110
     :versions: 2.1.0b2

     Fixed issue where :meth:`_postgresql.Insert.on_conflict_do_update`
     parameters were not respecting compilation options such as
     ``literal_binds=True``.  Pull request courtesy Loïc Simon.


 .. change::
     :tags: bug, sqlite
     :tickets: 13110
     :versions: 2.1.0b2

     Fixed issue where :meth:`_sqlite.Insert.on_conflict_do_update`
     parameters were not respecting compilation options such as
     ``literal_binds=True``.  Pull request courtesy Loïc Simon.

 .. change::
     :tags: usecase, engine
     :tickets: 13116
     :versions: 2.1.0b2

     The connection object returned by :meth:`_engine.Engine.raw_connection`
     now supports the context manager protocol, automatically returning the
     connection to the pool when exiting the context.

 .. change::
     :tags: bug, postgresql
     :tickets: 13130
     :versions: 2.1.0b2

     Fixed issue where :meth:`_postgresql.Insert.on_conflict_do_update`
     using parametrized bound parameters in the ``set_`` clause would fail
     when used with executemany batching. For dialects that use the
     ``use_insertmanyvalues_wo_returning`` optimization (psycopg2),
     insertmanyvalues is now disabled when there is an ON CONFLICT clause.
     For cases with RETURNING, row-at-a-time mode is used when the SET
     clause contains parametrized bindparams (bindparams that receive
     values from the parameters dict), ensuring each row's parameters are
     correctly applied. ON CONFLICT statements using expressions like
     ``excluded.<column>`` continue to batch normally.


 .. change::
     :tags: bug, sqlite
     :tickets: 13130
     :versions: 2.1.0b2

     Fixed issue where :meth:`_sqlite.Insert.on_conflict_do_update`
     using parametrized bound parameters in the ``set_`` clause would fail
     when used with executemany batching. Row-at-a-time mode is now used
     for ON CONFLICT statements with RETURNING that contain parametrized
     bindparams, ensuring each row's parameters are correctly applied. ON
     CONFLICT statements using expressions like ``excluded.<column>``
     continue to batch normally.

 .. change::
     :tags: bug, mysql
     :tickets: 13134
     :versions: 2.1.0b2

     Fixed issue where DDL compilation options were registered to the hard-coded
     dialect name ``mysql``. This made it awkward for MySQL-derived dialects
     like MariaDB, StarRocks, etc. to work with such options when different sets
     of options exist for different platforms. Options are now registered under
     the actual dialect name, and a fallback was added to help avoid errors when
     an option does not exist for that dialect.

     To maintain backwards compatibility, when using the MariaDB dialect with
     the options ``mysql_with_parser`` or ``mysql_using`` without also specifying
     the corresponding ``mariadb_`` prefixed options, a deprecation warning will
     be emitted. The ``mysql_`` prefixed options will continue to work during
     the deprecation period. Users should update their code to additionally
     specify ``mariadb_with_parser`` and ``mariadb_using`` when using the
     ``mariadb://`` dialect, or specify both options to support both dialects.

     Pull request courtesy Tiansu Yu.

.. changelog::

2.0.46

:released: January 21, 2026

 .. change::
     :tags: bug, sqlite
     :tickets: 13039
     :versions: 2.1.0b1

     Fixed issue in the aiosqlite driver where SQLAlchemy's setting of
     aiosqlite's worker thread to "daemon" stopped working because the aiosqlite
     architecture moved the location of the worker thread in version 0.22.0.
     This "daemon" flag is necessary so that a program is able to exit if the
     SQLite connection itself was not explicitly closed, which is particularly
     likely with SQLAlchemy as it maintains SQLite connections in a connection
     pool.  While it's perfectly fine to call :meth:`.AsyncEngine.dispose`
     before program exit, this is not historically or technically necessary for
     any driver of any known backend, since a primary feature of relational
     databases is durability.  The change also implements support for
     "terminate" with aiosqlite when using version version 0.22.1 or greater,
     which implements a sync ``.stop()`` method.

 .. change::
     :tags: usecase, mssql
     :tickets: 13045
     :versions: 2.1.0b1

     Added support for the ``IF EXISTS`` clause when dropping indexes on SQL
     Server 2016 (13.x) and later versions. The :paramref:`.DropIndex.if_exists`
     parameter is now honored by the SQL Server dialect, allowing conditional
     index drops that will not raise an error if the index does not exist.
     Pull request courtesy Edgar Ramírez Mondragón.

 .. change::
     :tags: bug, postgresql
     :tickets: 13059
     :versions: 2.1.0b1

     Fixed issue where PostgreSQL JSONB operators
     :meth:`_postgresql.JSONB.Comparator.path_match` and
     :meth:`_postgresql.JSONB.Comparator.path_exists` were applying incorrect
     ``VARCHAR`` casts to the right-hand side operand when used with newer
     PostgreSQL drivers such as psycopg. The operators now indicate the
     right-hand type as ``JSONPATH``, which currently results in no casting
     taking place, but is also compatible with explicit casts if the
     implementation were require it at a later point.



 .. change::
     :tags: bug, postgresql
     :tickets: 13067
     :versions: 2.1.0b1

     Fixed regression in PostgreSQL dialect where JSONB subscription syntax
     would generate incorrect SQL for :func:`.cast` expressions returning JSONB,
     causing syntax errors. The dialect now properly wraps cast expressions in
     parentheses when using the ``[]`` subscription syntax, generating
     ``(CAST(...))[index]`` instead of ``CAST(...)[index]`` to comply with
     PostgreSQL syntax requirements. This extends the fix from :ticket:`12778`
     which addressed the same issue for function calls.

 .. change::
     :tags: bug, mariadb
     :tickets: 13070
     :versions: 2.1.0b1

     Fixed the SQL compilation for the mariadb sequence "NOCYCLE" keyword that
     is to be emitted when the :paramref:`.Sequence.cycle` parameter is set to
     False on a :class:`.Sequence`.  Pull request courtesy Diego Dupin.

 .. change::
     :tags: bug, typing
     :tickets: 13075
     :versions: 2.1.0b1

     Fixed typing issues where ORM mapped classes and aliased entities could not
     be used as keys in result row mappings or as join targets in select
     statements. Patterns such as ``row._mapping[User]``,
     ``row._mapping[aliased(User)]``, ``row._mapping[with_polymorphic(...)]``
     (rejected by both mypy and Pylance), and ``.join(aliased(User))``
     (rejected by Pylance) are documented and fully supported at runtime but
     were previously rejected by type checkers. The type definitions for
     :class:`._KeyType` and :class:`._FromClauseArgument` have been updated to
     accept these ORM entity types.

 .. change::
     :tags: bug, postgresql
     :versions: 2.1.0b1

     Improved the foreign key reflection regular expression pattern used by the
     PostgreSQL dialect to be more permissive in matching identifier characters,
     allowing it to correctly handle unicode characters in table and column
     names. This change improves compatibility with PostgreSQL variants such as
     CockroachDB that may use different quoting patterns in combination with
     unicode characters in their identifiers.  Pull request courtesy Gord
     Thompson.

.. changelog::

2.0.45

:released: December 9, 2025

 .. change::
     :tags: bug, typing
     :tickets: 12730

     Fixed typing issue where :meth:`.Select.with_for_update` would not support
     lists of ORM entities or other FROM clauses in the
     :paramref:`.Select.with_for_update.of` parameter. Pull request courtesy
     Shamil.

 .. change::
     :tags: bug, orm
     :tickets: 12858

     Fixed issue where calling :meth:`.Mapper.add_property` within mapper event
     hooks such as :meth:`.MapperEvents.instrument_class`,
     :meth:`.MapperEvents.after_mapper_constructed`, or
     :meth:`.MapperEvents.before_mapper_configured` would raise an
     ``AttributeError`` because the mapper's internal property collections were
     not yet initialized. The :meth:`.Mapper.add_property` method now handles
     early-stage property additions correctly, allowing properties including
     column properties, deferred columns, and relationships to be added during
     mapper initialization events.  Pull request courtesy G Allajmi.

 .. change::
     :tags: bug, postgresql
     :tickets: 12867

     Fixed issue where PostgreSQL dialect options such as ``postgresql_include``
     on :class:`.PrimaryKeyConstraint` and :class:`.UniqueConstraint` were
     rendered in the wrong position when combined with constraint deferrability
     options like ``deferrable=True``. Pull request courtesy G Allajmi.

 .. change::
     :tags: bug, sql
     :tickets: 12915

     Some improvements to the :meth:`_sql.ClauseElement.params` method to
     replace bound parameters in a query were made, however the ultimate issue
     in :ticket:`12915` involving ORM :func:`_orm.aliased` cannot be fixed fully
     until 2.1, where the method is being rewritten to work without relying on
     Core cloned traversal.

 .. change::
     :tags: bug, sqlite, reflection
     :tickets: 12924

     A series of improvements have been made for reflection of CHECK constraints
     on SQLite. The reflection logic now correctly handles table names
     containing the strings "CHECK" or "CONSTRAINT", properly supports all four
     SQLite identifier quoting styles (double quotes, single quotes, brackets,
     and backticks) for constraint names, and accurately parses CHECK constraint
     expressions containing parentheses within string literals using balanced
     parenthesis matching with string context tracking.    Big thanks to
     GruzdevAV for new test cases and implementation ideas.

 .. change::
     :tags: bug, orm
     :tickets: 12952

     Fixed issue in Python 3.14 where dataclass transformation would fail when
     a mapped class using :class:`.MappedAsDataclass` included a
     :func:`.relationship` referencing a class that was not available at
     runtime (e.g., within a ``TYPE_CHECKING`` block). This occurred when using
     Python 3.14's :pep:`649` deferred annotations feature, which is the
     default behavior without a ``from __future__ import annotations``
     directive.

 .. change::
     :tags: bug, sqlite
     :tickets: 12954

     Fixed issue where SQLite dialect would fail to reflect constraint names
     that contained uppercase letters or other characters requiring quoting. The
     regular expressions used to parse primary key, foreign key, and unique
     constraint names from the ``CREATE TABLE`` statement have been updated to
     properly handle both quoted and unquoted constraint names.

 .. change::
     :tags: bug, typing

     Fixed typing issue where :class:`.coalesce` would not return the correct
     return type when a nullable form of that argument were passed, even though
     this function is meant to select the non-null entry among possibly null
     arguments.  Pull request courtesy Yannick PÉROUX.


 .. change::
     :tags: usecase, mysql
     :tickets: 12964

     Added support for MySQL 8.0.1 + ``FOR SHARE`` to be emitted for the
     :meth:`.Select.with_for_update` method, which offers compatibility with
     ``NOWAIT`` and ``SKIP LOCKED``.  The new syntax is used only for MySQL when
     version 8.0.1 or higher is detected. Pull request courtesy JetDrag.

 .. change::
     :tags: bug, sql
     :tickets: 12987

     Fixed issue where using the :meth:`.ColumnOperators.in_` operator with a
     nested :class:`.CompoundSelect` statement (e.g. an ``INTERSECT`` of
     ``UNION`` queries) would raise a :class:`NotImplementedError` when the
     nested compound select was the first argument to the outer compound select.
     The ``_scalar_type()`` internal method now properly handles nested compound
     selects.

 .. change::
     :tags: bug, postgresql
     :tickets: 13015

     Fixed the structure of the SQL string used for the
     :ref:`engine_insertmanyvalues` feature when an explicit sequence with
     ``nextval()`` is used. The SQL function invocation for the sequence has
     been moved from being rendered inline within each tuple inside of VALUES to
     being rendered once in the SELECT that reads from VALUES. This change
     ensures the function is invoked in the correct order as rows are processed,
     rather than assuming PostgreSQL will execute inline function calls within
     VALUES in a particular order. While current PostgreSQL versions appear to
     handle the previous approach correctly, the database does not guarantee
     this behavior for future versions.

 .. change::
     :tags: usecase, postgresql
     :tickets: 6511

     Added support for reflection of collation in types for PostgreSQL.
     The ``collation`` will be set only if different from the default
     one for the type.
     Pull request courtesy Denis Laxalde.

 .. change::
     :tags: bug, examples

     Fixed the "short_selects" performance example where the cache was being
     used in all the examples, making it impossible to compare performance with
     and without the cache.   Less important comparisons like "lambdas" and
     "baked queries" have been removed.


 .. change::
     :tags: change, tests

     A noxfile.py has been added to allow testing with nox.  This is a direct
     port of 2.1's move to nox, however leaves the tox.ini file in place and
     retains all test documentation in terms of tox.   Version 2.1 will move to
     nox fully, including deprecation warnings for tox and new testing
     documentation.

.. changelog::

2.0.44

:released: October 10, 2025

 .. change::
     :tags: bug, sql
     :tickets: 12271

     Improved the implementation of :meth:`.UpdateBase.returning` to use more
     robust logic in setting up the ``.c`` collection of a derived statement
     such as a CTE.  This fixes issues related to RETURNING clauses that feature
     expressions based on returned columns with or without qualifying labels.

 .. change::
     :tags: usecase, asyncio
     :tickets: 12273

     Generalize the terminate logic employed by the asyncpg dialect to reuse
     it in the aiomysql and asyncmy dialect implementation.

 .. change::
     :tags: bug, mssql
     :tickets: 12798

     Improved the base implementation of the asyncio cursor such that it
     includes the option for the underlying driver's cursor to be actively
     closed in those cases where it requires ``await`` in order to complete the
     close sequence, rather than relying on garbage collection to "close" it,
     when a plain :class:`.Result` is returned that does not use ``await`` for
     any of its methods.  The previous approach of relying on gc was fine for
     MySQL and SQLite dialects but has caused problems with the aioodbc
     implementation on top of SQL Server.   The new option is enabled
     for those dialects which have an "awaitable" ``cursor.close()``, which
     includes the aioodbc, aiomysql, and asyncmy dialects (aiosqlite is also
     modified for 2.1 only).

 .. change::
     :tags: bug, ext
     :tickets: 12802

     Fixed issue caused by an unwanted functional change while typing
     the :class:`.MutableList` class.
     This change also reverts all other functional changes done in
     the same change.

 .. change::
     :tags: bug, typing
     :tickets: 12813

     Fixed typing bug where the :meth:`.Session.execute` method advertised that
     it would return a :class:`.CursorResult` if given an insert/update/delete
     statement.  This is not the general case as several flavors of ORM
     insert/update do not actually yield a :class:`.CursorResult` which cannot
     be differentiated at the typing overload level, so the method now yields
     :class:`.Result` in all cases.  For those cases where
     :class:`.CursorResult` is known to be returned and the ``.rowcount``
     attribute is required, please use ``typing.cast()``.

 .. change::
     :tags: usecase, orm
     :tickets: 12829

     The way ORM Annotated Declarative interprets Python :pep:`695` type aliases
     in ``Mapped[]`` annotations has been refined to expand the lookup scheme. A
     :pep:`695` type can now be resolved based on either its direct presence in
     :paramref:`_orm.registry.type_annotation_map` or its immediate resolved
     value, as long as a recursive lookup across multiple :pep:`695` types is
     not required for it to resolve. This change reverses part of the
     restrictions introduced in 2.0.37 as part of :ticket:`11955`, which
     deprecated (and disallowed in 2.1) the ability to resolve any :pep:`695`
     type that was not explicitly present in
     :paramref:`_orm.registry.type_annotation_map`. Recursive lookups of
     :pep:`695` types remains deprecated in 2.0 and disallowed in version 2.1,
     as do implicit lookups of ``NewType`` types without an entry in
     :paramref:`_orm.registry.type_annotation_map`.

     Additionally, new support has been added for generic :pep:`695` aliases that
     refer to :pep:`593` ``Annotated`` constructs containing
     :func:`_orm.mapped_column` configurations. See the sections below for
     examples.

     .. seealso::

         :ref:`orm_declarative_type_map_pep695_types`

         :ref:`orm_declarative_mapped_column_generic_pep593`

 .. change::
     :tags: bug, postgresql
     :tickets: 12847

     Fixed issue where selecting an enum array column containing NULL values
     would fail to parse properly in the PostgreSQL dialect. The
     :func:`._split_enum_values` function now correctly handles NULL entries by
     converting them to Python ``None`` values.

 .. change::
     :tags: bug, typing
     :tickets: 12855

     Added new decorator :func:`_orm.mapped_as_dataclass`, which is a function
     based form of :meth:`_orm.registry.mapped_as_dataclass`; the method form
     :meth:`_orm.registry.mapped_as_dataclass` does not seem to be correctly
     recognized within the scope of :pep:`681` in recent mypy versions.

 .. change::
     :tags: bug, sqlite
     :tickets: 12864

     Fixed issue where SQLite table reflection would fail for tables using
     ``WITHOUT ROWID`` and/or ``STRICT`` table options when the table contained
     generated columns. The regular expression used to parse ``CREATE TABLE``
     statements for generated column detection has been updated to properly
     handle these SQLite table options that appear after the column definitions.
     Pull request courtesy Tip ten Brink.

 .. change::
     :tags: bug, postgresql
     :tickets: 12874

     Fixed issue where the :func:`_sql.any_` and :func:`_sql.all_` aggregation
     operators would not correctly coerce the datatype of the compared value, in
     those cases where the compared value were not a simple int/str etc., such
     as a Python ``Enum`` or other custom value.   This would lead to execution
     time errors for these values.  This issue is essentially the same as
     :ticket:`6515` which was for the now-legacy :meth:`.ARRAY.any` and
     :meth:`.ARRAY.all` methods.

 .. change::
     :tags: bug, engine
     :tickets: 12881

     Implemented initial support for free-threaded Python by adding new tests
     and reworking the test harness to include Python 3.13t and Python 3.14t in
     test runs. Two concurrency issues have been identified and fixed: the first
     involves initialization of the ``.c`` collection on a ``FromClause``, a
     continuation of :ticket:`12302`, where an optional mutex under
     free-threading is added; the second involves synchronization of the pool
     "first_connect" event, which first received thread synchronization in
     :ticket:`2964`, however under free-threading the creation of the mutex
     itself runs under the same free-threading mutex. Support for free-threaded
     wheels on Pypi is implemented as well within the 2.1 series only.  Initial
     pull request and test suite courtesy Lysandros Nikolaou.

 .. change::
     :tags: bug, schema
     :tickets: 12884

     Fixed issue where :meth:`_schema.MetaData.reflect` did not forward
     dialect-specific keyword arguments to the :class:`_engine.Inspector`
     methods, causing options like ``oracle_resolve_synonyms`` to be ignored
     during reflection. The method now ensures that all extra kwargs passed to
     :meth:`_schema.MetaData.reflect` are forwarded to
     :meth:`_engine.Inspector.get_table_names` and related reflection methods.
     Pull request courtesy Lukáš Kožušník.

 .. change::
     :tags: bug, mssql
     :tickets: 12894

     Fixed issue where the index reflection for SQL Server would
     not correctly return the order of the column inside an index
     when the order of the columns in the index did not match the
     order of the columns in the table.
     Pull request courtesy of Allen Chen.

 .. change::
     :tags: bug, orm
     :tickets: 12905

     Fixed a caching issue where :func:`_orm.with_loader_criteria` would
     incorrectly reuse cached bound parameter values when used with
     :class:`_sql.CompoundSelect` constructs such as :func:`_sql.union`. The
     issue was caused by the cache key for compound selects not including the
     execution options that are part of the :class:`_sql.Executable` base class,
     which :func:`_orm.with_loader_criteria` uses to apply its criteria
     dynamically. The fix ensures that compound selects and other executable
     constructs properly include execution options in their cache key traversal.

 .. change::
     :tags: bug, mssql, reflection
     :tickets: 12907

     Fixed issue in the MSSQL dialect's foreign key reflection query where
     duplicate rows could be returned when a foreign key column and its
     referenced primary key column have the same name, and both the referencing
     and referenced tables have indexes with the same name. This resulted in an
     "ForeignKeyConstraint with duplicate source column references are not
     supported" error when attempting to reflect such tables. The query has been
     corrected to exclude indexes on the child table when looking for unique
     indexes referenced by foreign keys.

 .. change::
     :tags: bug, platform

     Unblocked automatic greenlet installation for Python 3.14 now that
     there are greenlet wheels on pypi for python 3.14.

.. changelog::

2.0.43

:released: August 11, 2025

 .. change::
     :tags: usecase, oracle
     :tickets: 12711

     Extended :class:`_oracle.VECTOR` to support sparse vectors. This update
     introduces :class:`_oracle.VectorStorageType` to specify sparse or dense
     storage and added :class:`_oracle.SparseVector`. Pull request courtesy
     Suraj Shaw.

 .. change::
     :tags: bug, orm
     :tickets: 12748

     Fixed issue where using the ``post_update`` feature would apply incorrect
     "pre-fetched" values to the ORM objects after a multi-row UPDATE process
     completed.  These "pre-fetched" values would come from any column that had
     an :paramref:`.Column.onupdate` callable or a version id generator used by
     :paramref:`.orm.Mapper.version_id_generator`; for a version id generator
     that delivered random identifiers like timestamps or UUIDs, this incorrect
     data would lead to a DELETE statement against those same rows to fail in
     the next step.


 .. change::
     :tags: bug, postgresql
     :tickets: 12778

     Fixed regression in PostgreSQL dialect where JSONB subscription syntax
     would generate incorrect SQL for JSONB-returning functions, causing syntax
     errors. The dialect now properly wraps function calls and expressions in
     parentheses when using the ``[]`` subscription syntax, generating
     ``(function_call)[index]`` instead of ``function_call[index]`` to comply
     with PostgreSQL syntax requirements.

 .. change::
     :tags: usecase, engine
     :tickets: 12784

     Added new parameter :paramref:`.create_engine.skip_autocommit_rollback`
     which provides for a per-dialect feature of preventing the DBAPI
     ``.rollback()`` from being called under a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant