Changelog
### 2.0.21
```
:released: September 18, 2023
.. change::
:tags: bug, sql
:tickets: 9610
Adjusted the operator precedence for the string concatenation operator to
be equal to that of string matching operators, such as
:meth:`.ColumnElement.like`, :meth:`.ColumnElement.regexp_match`,
:meth:`.ColumnElement.match`, etc., as well as plain ``==`` which has the
same precedence as string comparison operators, so that parenthesis will be
applied to a string concatenation expression that follows a string match
operator. This provides for backends such as PostgreSQL where the "regexp
match" operator is apparently of higher precedence than the string
concatenation operator.
.. change::
:tags: bug, sql
:tickets: 10342
Qualified the use of ``hashlib.md5()`` within the DDL compiler, which is
used to generate deterministic four-character suffixes for long index and
constraint names in DDL statements, to include the Python 3.9+
``usedforsecurity=False`` parameter so that Python interpreters built for
restricted environments such as FIPS do not consider this call to be
related to security concerns.
.. change::
:tags: bug, postgresql
:tickets: 10226
Fixed regression which appeared in 2.0 due to :ticket:`8491` where the
revised "ping" used for PostgreSQL dialects when the
:paramref:`_sa.create_engine.pool_pre_ping` parameter is in use would
interfere with the use of asyncpg with PGBouncer "transaction" mode, as the
multiple PostgreSQL commands emitted by asnycpg could be broken out among
multiple connections leading to errors, due to the lack of any transaction
around this newly revised "ping". The ping is now invoked within a
transaction, in the same way that is implicit with all other backends that
are based on the pep-249 DBAPI; this guarantees that the series of PG
commands sent by asyncpg for this command are invoked on the same backend
connection without it jumping to a different connection mid-command. The
transaction is not used if the asyncpg dialect is used in "AUTOCOMMIT"
mode, which remains incompatible with pgbouncer transaction mode.
.. change::
:tags: bug, orm
:tickets: 10279
Adjusted the ORM's interpretation of the "target" entity used within
:class:`.Update` and :class:`.Delete` to not interfere with the target
"from" object passed to the statement, such as when passing an ORM-mapped
:class:`_orm.aliased` construct that should be maintained within a phrase
like "UPDATE FROM". Cases like ORM session synchonize using "SELECT"
statements such as with MySQL/ MariaDB will still have issues with
UPDATE/DELETE of this form so it's best to disable synchonize_session when
using DML statements of this type.
.. change::
:tags: bug, orm
:tickets: 10348
Added new capability to the :func:`_orm.selectin_polymorphic` loader option
which allows other loader options to be bundled as siblings, referring to
one of its subclasses, within the sub-options of parent loader option.
Previously, this pattern was only supported if the
:func:`_orm.selectin_polymorphic` were at the top level of the options for
the query. See new documentation section for example.
As part of this change, improved the behavior of the
:meth:`_orm.Load.selectin_polymorphic` method / loader strategy so that the
subclass load does not load most already-loaded columns from the parent
table, when the option is used against a class that is already being
relationship-loaded. Previously, the logic to load only the subclass
columns worked only for a top level class load.
.. seealso::
:ref:`polymorphic_selectin_as_loader_option_target_plus_opts`
.. change::
:tags: bug, typing
:tickets: 10264, 9284
Fixed regression introduced in 2.0.20 via :ticket:`9600` fix which
attempted to add more formal typing to
:paramref:`_schema.MetaData.naming_convention`. This change prevented basic
naming convention dictionaries from passing typing and has been adjusted so
that a plain dictionary of strings for keys as well as dictionaries that
use constraint types as keys or a mix of both, are again accepted.
As part of this change, lesser used forms of the naming convention
dictionary are also typed, including that it currently allows for
``Constraint`` type objects as keys as well.
.. change::
:tags: usecase, typing
:tickets: 10288
Made the contained type for :class:`.Mapped` covariant; this is to allow
greater flexibility for end-user typing scenarios, such as the use of
protocols to represent particular mapped class structures that are passed
to other functions. As part of this change, the contained type was also
made covariant for dependent and related types such as
:class:`_orm.base.SQLORMOperations`, :class:`_orm.WriteOnlyMapped`, and
:class:`_sql.SQLColumnExpression`. Pull request courtesy Roméo Després.
.. change::
:tags: bug, engine
:tickets: 10275
Fixed a series of reflection issues affecting the PostgreSQL,
MySQL/MariaDB, and SQLite dialects when reflecting foreign key constraints
where the target column contained parenthesis in one or both of the table
name or column name.
.. change::
:tags: bug, sql
:tickets: 10280
The :class:`.Values` construct will now automatically create a proxy (i.e.
a copy) of a :class:`_sql.column` if the column were already associated
with an existing FROM clause. This allows that an expression like
``values_obj.c.colname`` will produce the correct FROM clause even in the
case that ``colname`` was passed as a :class:`_sql.column` that was already
used with a previous :class:`.Values` or other table construct.
Originally this was considered to be a candidate for an error condition,
however it's likely this pattern is already in widespread use so it's
now added to support.
.. change::
:tags: bug, setup
:tickets: 10321
Fixed very old issue where the full extent of SQLAlchemy modules, including
``sqlalchemy.testing.fixtures``, could not be imported outside of a pytest
run. This suits inspection utilities such as ``pkgutil`` that attempt to
import all installed modules in all packages.
.. change::
:tags: usecase, sql
:tickets: 10269
Adjusted the :class:`_types.Enum` datatype to accept an argument of
``None`` for the :paramref:`_types.Enum.length` parameter, resulting in a
VARCHAR or other textual type with no length in the resulting DDL. This
allows for new elements of any length to be added to the type after it
exists in the schema. Pull request courtesy Eugene Toder.
.. change::
:tags: bug, typing
:tickets: 9878
Fixed the type annotation for ``__class_getitem__()`` as applied to the
``Visitable`` class at the base of expression constructs to accept ``Any``
for a key, rather than ``str``, which helps with some IDEs such as PyCharm
when attempting to write typing annotations for SQL constructs which
include generic selectors. Pull request courtesy Jordan Macdonald.
.. change::
:tags: bug, typing
:tickets: 10353
Repaired the core "SQL element" class ``SQLCoreOperations`` to support the
``__hash__()`` method from a typing perspective, as objects like
:class:`.Column` and ORM :class:`.InstrumentedAttribute` are hashable and
are used as dictionary keys in the public API for the :class:`_dml.Update`
and :class:`_dml.Insert` constructs. Previously, type checkers were not
aware the root SQL element was hashable.
.. change::
:tags: bug, typing
:tickets: 10337
Fixed typing issue with :meth:`_sql.Existing.select_from` that
prevented its use with ORM classes.
.. change::
:tags: usecase, sql
:tickets: 9873
Added new generic SQL function :class:`_functions.aggregate_strings`, which
accepts a SQL expression and a decimeter, concatenating strings on multiple
rows into a single aggregate value. The function is compiled on a
per-backend basis, into functions such as ``group_concat(),``
``string_agg()``, or ``LISTAGG()``.
Pull request courtesy Joshua Morris.
.. change::
:tags: typing, bug
:tickets: 10131
Update type annotations for ORM loading options, restricting them to accept
only `"*"` instead of any string for string arguments. Pull request
courtesy Janek Nouvertné.
.. changelog::
```
### 2.0.20
```
:released: August 15, 2023
.. change::
:tags: bug, orm
:tickets: 10169
Fixed issue where the ORM's generation of a SELECT from a joined
inheritance model with same-named columns in superclass and subclass would
somehow not send the correct list of column names to the :class:`.CTE`
construct, when the RECURSIVE column list were generated.
.. change::
:tags: bug, typing
:tickets: 9185
Typing improvements:
* :class:`.CursorResult` is returned for some forms of
:meth:`_orm.Session.execute` where DML without RETURNING is used
* fixed type for :paramref:`_orm.Query.with_for_update.of` parameter within
:meth:`_orm.Query.with_for_update`
* improvements to ``_DMLColumnArgument`` type used by some DML methods to
pass column expressions
* Add overload to :func:`_sql.literal` so that it is inferred that the
return type is ``BindParameter[NullType]`` where
:paramref:`_sql.literal.type_` param is None
* Add overloads to :meth:`_sql.ColumnElement.op` so that the inferred
type when :paramref:`_sql.ColumnElement.op.return_type` is not provided
is ``Callable[[Any], BinaryExpression[Any]]``
* Add missing overload to :meth:`_sql.ColumnElement.__add__`
Pull request courtesy Mehdi Gmira.
.. change::
:tags: usecase, orm
:tickets: 10192
Implemented the "RETURNING '*'" use case for ORM enabled DML statements.
This will render in as many cases as possible and return the unfiltered
result set, however is not supported for multi-parameter "ORM bulk INSERT"
statements that have specific column rendering requirements.
.. change::
:tags: bug, typing
:tickets: 10182
Fixed issue in :class:`_orm.Session` and :class:`_asyncio.AsyncSession`
methods such as :meth:`_orm.Session.connection` where the
:paramref:`_orm.Session.connection.execution_options` parameter were
hardcoded to an internal type that is not user-facing.
.. change::
:tags: orm, bug
:tickets: 10231
Fixed fairly major issue where execution options passed to
:meth:`_orm.Session.execute`, as well as execution options local to the ORM
executed statement itself, would not be propagated along to eager loaders
such as that of :func:`_orm.selectinload`, :func:`_orm.immediateload`, and
:meth:`_orm.subqueryload`, making it impossible to do things such as
disabling the cache for a single statement or using
``schema_translate_map`` for a single statement, as well as the use of
user-custom execution options. A change has been made where **all**
user-facing execution options present for :meth:`_orm.Session.execute` will
be propagated along to additional loaders.
As part of this change, the warning for "excessively deep" eager loaders
leading to caching being disabled can be silenced on a per-statement
basis by sending ``execution_options={"compiled_cache": None}`` to
:meth:`_orm.Session.execute`, which will disable caching for the full
series of statements within that scope.
.. change::
:tags: usecase, asyncio
:tickets: 9698
Added new methods :meth:`_asyncio.AsyncConnection.aclose` as a synonym for
:meth:`_asyncio.AsyncConnection.close` and
:meth:`_asyncio.AsyncSession.aclose` as a synonym for
:meth:`_asyncio.AsyncSession.close` to the
:class:`_asyncio.AsyncConnection` and :class:`_asyncio.AsyncSession`
objects, to provide compatibility with Python standard library
``contextlib.aclosing`` construct. Pull request courtesy Grigoriev Semyon.
.. change::
:tags: bug, orm
:tickets: 10124
Fixed issue where internal cloning used by the ORM for expressions like
:meth:`_orm.relationship.Comparator.any` to produce correlated EXISTS
constructs would interfere with the "cartesian product warning" feature of
the SQL compiler, leading the SQL compiler to warn when all elements of the
statement were correctly joined.
.. change::
:tags: orm, bug
:tickets: 10139
Fixed issue where the ``lazy="immediateload"`` loader strategy would place
an internal loading token into the ORM mapped attribute under circumstances
where the load should not occur, such as in a recursive self-referential
load. As part of this change, the ``lazy="immediateload"`` strategy now
honors the :paramref:`_orm.relationship.join_depth` parameter for
self-referential eager loads in the same way as that of other eager
loaders, where leaving it unset or set at zero will lead to a
self-referential immediateload not occurring, setting it to a value of one
or greater will immediateload up until that given depth.
.. change::
:tags: bug, orm
:tickets: 10175
Fixed issue where dictionary-based collections such as
:func:`_orm.attribute_keyed_dict` did not fully pickle/unpickle correctly,
leading to issues when attempting to mutate such a collection after
unpickling.
.. change::
:tags: bug, orm
:tickets: 10125
Fixed issue where chaining :func:`_orm.load_only` or other wildcard use of
:func:`_orm.defer` from another eager loader using a :func:`_orm.aliased`
against a joined inheritance subclass would fail to take effect for columns
local to the superclass.
.. change::
:tags: bug, orm
:tickets: 10167
Fixed issue where an ORM-enabled :func:`_sql.select` construct would not
render any CTEs added only via the :meth:`_sql.Select.add_cte` method that
were not otherwise referenced in the statement.
.. change::
:tags: bug, examples
The dogpile_caching examples have been updated for 2.0 style queries.
Within the "caching query" logic itself there is one conditional added to
differentiate between ``Query`` and ``select()`` when performing an
invalidation operation.
.. change::
:tags: typing, usecase
:tickets: 10173
Added new typing only utility functions :func:`.Nullable` and
:func:`.NotNullable` to type a column or ORM class as, respectively,
nullable or not nullable.
These function are no-op at runtime, returning the input unchanged.
.. change::
:tags: bug, engine
:tickets: 10147
Fixed critical issue where setting
:paramref:`_sa.create_engine.isolation_level` to ``AUTOCOMMIT`` (as opposed
to using the :meth:`_engine.Engine.execution_options` method) would fail to
restore "autocommit" to a pooled connection if an alternate isolation level
were temporarily selected using
:paramref:`_engine.Connection.execution_options.isolation_level`.
.. changelog::
```
### 2.0.19
```
:released: July 15, 2023
.. change::
:tags: bug, orm
:tickets: 10089
Fixed issue where setting a relationship collection directly, where an
object in the new collection were already present, would not trigger a
cascade event for that object, leading to it not being added to the
:class:`_orm.Session` if it were not already present. This is similar in
nature to :ticket:`6471` and is a more apparent issue due to the removal of
``cascade_backrefs`` in the 2.0 series. The
:meth:`_orm.AttributeEvents.append_wo_mutation` event added as part of
:ticket:`6471` is now also emitted for existing members of a collection
that are present in a bulk set of that same collection.
.. change::
:tags: bug, engine
:tickets: 10093
Renamed :attr:`_result.Row.t` and :meth:`_result.Row.tuple` to
:attr:`_result.Row._t` and :meth:`_result.Row._tuple`; this is to suit the
policy that all methods and pre-defined attributes on :class:`.Row` should
be in the style of Python standard library ``namedtuple`` where all fixed
names have a leading underscore, to avoid name conflicts with existing
column names. The previous method/attribute is now deprecated and will
emit a deprecation warning.
.. change::
:tags: bug, postgresql
:tickets: 10069
Fixed regression caused by improvements to PostgreSQL URL parsing in
:ticket:`10004` where "host" query string arguments that had colons in
them, to support various third party proxy servers and/or dialects, would
not parse correctly as these were evaluted as ``host:port`` combinations.
Parsing has been updated to consider a colon as indicating a ``host:port``
value only if the hostname contains only alphanumeric characters with dots
or dashes only (e.g. no slashes), followed by exactly one colon followed by
an all-integer token of zero or more integers. In all other cases, the
full string is taken as a host.
.. change::
:tags: bug, engine
:tickets: 10079
Added detection for non-string, non-:class:`_engine.URL` objects to the
:func:`_engine.make_url` function, allowing ``ArgumentError`` to be thrown
immediately, rather than causing failures later on. Special logic ensures
that mock forms of :class:`_engine.URL` are allowed through. Pull request
courtesy Grigoriev Semyon.
.. change::
:tags: bug, orm
:tickets: 10090
Fixed issue where objects that were associated with an unloaded collection
via backref, but were not merged into the :class:`_orm.Session` due to the
removal of ``cascade_backrefs`` in the 2.0 series, would not emit a warning
that these objects were not being included in a flush, even though they
were pending members of the collection; in other such cases, a warning is
emitted when a collection being flushed contains non-attached objects which
will be essentially discarded. The addition of the warning for
backref-pending collection members establishes greater consistency with
collections that may be present or non-present and possibly flushed or not
flushed at different times based on different relationship loading
strategies.
.. change::
:tags: bug, postgresql
:tickets: 10096
Fixed issue where comparisons to the :class:`_postgresql.CITEXT` datatype
would cast the right side to ``VARCHAR``, leading to the right side not
being interpreted as a ``CITEXT`` datatype, for the asyncpg, psycopg3 and
pg80000 dialects. This led to the :class:`_postgresql.CITEXT` type being
essentially unusable for practical use; this is now fixed and the test
suite has been corrected to properly assert that expressions are rendered
correctly.
.. change::
:tags: bug, orm, regression
:tickets: 10098
Fixed additional regression caused by :ticket:`9805` where more aggressive
propagation of the "ORM" flag on statements could lead to an internal
attribute error when embedding an ORM :class:`.Query` construct that
nonetheless contained no ORM entities within a Core SQL statement, in this
case ORM-enabled UPDATE and DELETE statements.
.. changelog::
```
### 2.0.18
```
:released: July 5, 2023
.. change::
:tags: usecase, typing
:tickets: 10054
Improved typing when using standalone operator functions from
``sqlalchemy.sql.operators`` such as ``sqlalchemy.sql.operators.eq``.
.. change::
:tags: usecase, mariadb, reflection
:tickets: 10028
Allowed reflecting :class:`_types.UUID` columns from MariaDB. This allows
Alembic to properly detect the type of such columns in existing MariaDB
databases.
.. change::
:tags: bug, postgresql
:tickets: 9945
Added new parameter ``native_inet_types=False`` to all PostgreSQL
dialects, which indicates converters used by the DBAPI to
convert rows from PostgreSQL :class:`.INET` and :class:`.CIDR` columns
into Python ``ipaddress`` datatypes should be disabled, returning strings
instead. This allows code written to work with strings for these datatypes
to be migrated to asyncpg, psycopg, or pg8000 without code changes
other than adding this parameter to the :func:`_sa.create_engine`
or :func:`_asyncio.create_async_engine` function call.
.. seealso::
:ref:`postgresql_network_datatypes`
.. change::
:tags: usecase, extensions
:tickets: 10013
Added new option to :func:`.association_proxy`
:paramref:`.association_proxy.create_on_none_assignment`; when an
association proxy which refers to a scalar relationship is assigned the
value ``None``, and the referenced object is not present, a new object is
created via the creator. This was apparently an undefined behavior in the
1.2 series that was silently removed.
.. change::
:tags: bug, typing
:tickets: 10061
Fixed some of the typing within the :func:`_orm.aliased` construct to
correctly accept a :class:`.Table` object that's been aliased with
:meth:`.Table.alias`, as well as general support for :class:`.FromClause`
objects to be passed as the "selectable" argument, since this is all
supported.
.. change::
:tags: bug, engine
:tickets: 10025
Adjusted the :paramref:`_sa.create_engine.schema_translate_map` feature
such that **all** schema names in the statement are now tokenized,
regardless of whether or not a specific name is in the immediate schema
translate map given, and to fallback to substituting the original name when
the key is not in the actual schema translate map at execution time. These
two changes allow for repeated use of a compiled object with schema
schema_translate_maps that include or dont include various keys on each
run, allowing cached SQL constructs to continue to function at runtime when
schema translate maps with different sets of keys are used each time. In
addition, added detection of schema_translate_map dictionaries which gain
or lose a ``None`` key across calls for the same statement, which affects
compilation of the statement and is not compatible with caching; an
exception is raised for these scenarios.
.. change::
:tags: bug, mssql, sql
:tickets: 9932
Fixed issue where performing :class:`.Cast` to a string type with an
explicit collation would render the COLLATE clause inside the CAST
function, which resulted in a syntax error.
.. change::
:tags: usecase, mssql
:tickets: 7340
Added support for creation and reflection of COLUMNSTORE
indexes in MSSQL dialect. Can be specified on indexes
specifying ``mssql_columnstore=True``.
.. change::
:tags: usecase, postgresql
:tickets: 10004
Added multi-host support for the asyncpg dialect. General improvements and
error checking added to the PostgreSQL URL routines for the "multihost" use
case added as well. Pull request courtesy Ilia Dmitriev.
.. seealso::
:ref:`asyncpg_multihost`
.. changelog::
```
### 2.0.17
```
:released: June 23, 2023
.. change::
:tags: usecase, postgresql
:tickets: 9965
The pg8000 dialect now supports RANGE and MULTIRANGE datatypes, using the
existing RANGE API described at :ref:`postgresql_ranges`. Range and
multirange types are supported in the pg8000 driver from version 1.29.8.
Pull request courtesy Tony Locke.
.. change::
:tags: bug, orm, regression
:tickets: 9870
Fixed regression in the 2.0 series where a query that used
:func:`.undefer_group` with :func:`_orm.selectinload` or
:func:`_orm.subqueryload` would raise an ``AttributeError``. Pull request
courtesy of Matthew Martin.
.. change::
:tags: bug, orm
:tickets: 9957
Fixed issue in ORM Annotated Declarative which prevented a
:class:`_orm.declared_attr` from being used on a mixin which did not return
a :class:`.Mapped` datatype, and instead returned a supplemental ORM
datatype such as :class:`.AssociationProxy`. The Declarative runtime would
erroneously try to interpret this annotation as needing to be
:class:`.Mapped` and raise an error.
.. change::
:tags: bug, orm, typing
:tickets: 9957
Fixed typing issue where using the :class:`.AssociationProxy` return type
from a :class:`_orm.declared_attr` function was disallowed.
.. change::
:tags: bug, orm, regression
:tickets: 9936
Fixed regression introduced in 2.0.16 by :ticket:`9879` where passing a
callable to the :paramref:`_orm.mapped_column.default` parameter of
:class:`_orm.mapped_column` while also setting ``init=False`` would
interpret this value as a Dataclass default value which would be assigned
directly to new instances of the object directly, bypassing the default
generator taking place as the :paramref:`_schema.Column.default`
value generator on the underlying :class:`_schema.Column`. This condition
is now detected so that the previous behavior is maintained, however a
deprecation warning for this ambiguous use is emitted; to populate the
default generator for a :class:`_schema.Column`, the
:paramref:`_orm.mapped_column.insert_default` parameter should be used,
which disambiguates from the :paramref:`_orm.mapped_column.default`
parameter whose name is fixed as per pep-681.
.. change::
:tags: bug, orm
:tickets: 9973
Additional hardening and documentation for the ORM :class:`_orm.Session`
"state change" system, which detects concurrent use of
:class:`_orm.Session` and :class:`_asyncio.AsyncSession` objects; an
additional check is added within the process to acquire connections from
the underlying engine, which is a critical section with regards to internal
connection management.
.. change::
:tags: bug, orm
:tickets: 10006
Fixed issue in ORM loader strategy logic which further allows for long
chains of :func:`_orm.contains_eager` loader options across complex
inheriting polymorphic / aliased / of_type() relationship chains to take
proper effect in queries.
.. change::
:tags: bug, orm, declarative
:tickets: 3532
A warning is emitted when an ORM :func:`_orm.relationship` and other
:class:`.MapperProperty` objects are assigned to two different class
attributes at once; only one of the attributes will be mapped. A warning
for this condition was already in place for :class:`_schema.Column` and
:class:`_orm.mapped_column` objects.
.. change::
:tags: bug, orm
:tickets: 9963
Fixed issue in support for the :class:`.Enum` datatype in the
:paramref:`_orm.registry.type_annotation_map` first added as part of
:ticket:`8859` where using a custom :class:`.Enum` with fixed configuration
in the map would fail to transfer the :paramref:`.Enum.name` parameter,
which among other issues would prevent PostgreSQL enums from working if the
enum values were passed as individual values. Logic has been updated so
that "name" is transferred over, but also that the default :class:`.Enum`
which is against the plain Python `enum.Enum` class or other "empty" enum
won't set a hardcoded name of ``"enum"`` either.
.. change::
:tags: bug, typing
:tickets: 9985
Fixed typing issue which prevented :class:`_orm.WriteOnlyMapped` and
:class:`_orm.DynamicMapped` attributes from being used fully within ORM
queries.
.. changelog::
```
### 2.0.16
```
:released: June 10, 2023
.. change::
:tags: usecase, postgresql, reflection
:tickets: 9838
Cast ``NAME`` columns to ``TEXT`` when using ``ARRAY_AGG`` in PostgreSQL
reflection. This seems to improve compatibility with some PostgreSQL
derivatives that may not support aggregations on the ``NAME`` type.
.. change::
:tags: bug, orm
:tickets: 9862
Fixed issue where :class:`.DeclarativeBaseNoMeta` declarative base class
would not function with non-mapped mixins or abstract classes, raising an
``AttributeError`` instead.
.. change::
:tags: usecase, orm
:tickets: 9828
Improved :meth:`.DeferredReflection.prepare` to accept arbitrary ``**kw``
arguments that are passed to :meth:`_schema.MetaData.reflect`, allowing use
cases such as reflection of views as well as dialect-specific arguments to
be passed. Additionally, modernized the
:paramref:`.DeferredReflection.prepare.bind` argument so that either an
:class:`.Engine` or :class:`.Connection` are accepted as the "bind"
argument.
.. change::
:tags: usecase, asyncio
:tickets: 8215
Added new :paramref:`_asyncio.create_async_engine.async_creator` parameter
to :func:`.create_async_engine`, which accomplishes the same purpose as the
:paramref:`.create_engine.creator` parameter of :func:`.create_engine`.
This is a no-argument callable that provides a new asyncio connection,
using the asyncio database driver directly. The
:func:`.create_async_engine` function will wrap the driver-level connection
in the appropriate structures. Pull request curtesy of Jack Wotherspoon.
.. change::
:tags: bug, orm, regression
:tickets: 9820
Fixed regression in the 2.0 series where the default value of
:paramref:`_orm.validates.include_backrefs` got changed to ``False`` for
the :func:`_orm.validates` function. This default is now restored to
``True``.
.. change::
:tags: bug, orm
:tickets: 9917
Fixed bug in new feature which allows a WHERE clause to be used in
conjunction with :ref:`orm_queryguide_bulk_update`, added in version 2.0.11
as part of :ticket:`9583`, where sending dictionaries that did not include
the primary key values for each row would run through the bulk process and
include "pk=NULL" for the rows, silently failing. An exception is now
raised if primary key values for bulk UPDATE are not supplied.
.. change::
:tags: bug, postgresql
:tickets: 9836
Use proper precedence on PostgreSQL specific operators, such as ``>``.
Previously the precedence was wrong, leading to wrong parenthesis when
rendering against and ``ANY`` or ``ALL`` construct.
.. change::
:tags: bug, orm, dataclasses
:tickets: 9879
Fixed an issue where generating dataclasses fields that specified a
``default`` value and set ``init=False`` would not work.
The dataclasses behavior in this case is to set the default
value on the class, that's not compatible with the descriptors used
by SQLAlchemy. To support this case the default is transformed to
a ``default_factory`` when generating the dataclass.
.. change::
:tags: bug, orm
:tickets: 9841
A deprecation warning is emitted whenever a property is added to a
:class:`_orm.Mapper` where an ORM mapped property were already configured,
or an attribute is already present on the class. Previously, there was a
non-deprecation warning for this case that did not emit consistently. The
logic for this warning has been improved so that it detects end-user
replacement of attribute while not having false positives for internal
Declarative and other cases where replacement of descriptors with new ones
is expected.
.. change::
:tags: bug, postgresql
:tickets: 9907
Fixed issue where the :paramref:`.ColumnOperators.like.escape` and similar
parameters did not allow an empty string as an argument that would be
passed through as the "escape" character; this is a supported syntax by
PostgreSQL. Pull requset courtesy Martin Caslavsky.
.. change::
:tags: bug, orm
:tickets: 9869
Improved the argument chacking on the
:paramref:`_orm.registry.map_imperatively.local_table` parameter of the
:meth:`_orm.registry.map_imperatively` method, ensuring only a
:class:`.Table` or other :class:`.FromClause` is passed, and not an
existing mapped class, which would lead to undefined behavior as the object
were further interpreted for a new mapping.
.. change::
:tags: usecase, postgresql
:tickets: 9041
Unified the custom PostgreSQL operator definitions, since they are
shared among multiple different data types.
.. change::
:tags: platform, usecase
Compatibility improvements allowing the complete test suite to pass
on Python 3.12.0b1.
.. change::
:tags: bug, orm
:tickets: 9913
The :attr:`_orm.InstanceState.unloaded_expirable` attribute is a synonym
for :attr:`_orm.InstanceState.unloaded`, and is now deprecated; this
attribute was always implementation-specific and should not have been
public.
.. change::
:tags: usecase, postgresql
:tickets: 8240
Added support for PostgreSQL 10 ``NULLS NOT DISTINCT`` feature of
unique indexes and unique constraint using the dialect option
``postgresql_nulls_not_distinct``.
Updated the reflection logic to also correctly take this option
into account.
Pull request courtesy of Pavel Siarchenia.
.. changelog::
```
### 2.0.15
```
:released: May 19, 2023
.. change::
:tags: bug, orm
:tickets: 9805
As more projects are using new-style "2.0" ORM querying, it's becoming
apparent that the conditional nature of "autoflush", being based on whether
or not the given statement refers to ORM entities, is becoming more of a
key behavior. Up until now, the "ORM" flag for a statement has been loosely
based around whether or not the statement returns rows that correspond to
ORM entities or columns; the original purpose of the "ORM" flag was to
enable ORM-entity fetching rules which apply post-processing to Core result
sets as well as ORM loader strategies to the statement. For statements
that don't build on rows that contain ORM entities, the "ORM" flag was
considered to be mostly unnecessary.
It still may be the case that "autoflush" would be better taking effect for
*all* usage of :meth:`_orm.Session.execute` and related methods, even for
purely Core SQL constructs. However, this still could impact legacy cases
where this is not expected and may be more of a 2.1 thing. For now however,
the rules for the "ORM-flag" have been opened up so that a statement that
includes ORM entities or attributes anywhere within, including in the WHERE
/ ORDER BY / GROUP BY clause alone, within scalar subqueries, etc. will
enable this flag. This will cause "autoflush" to occur for such statements
and also be visible via the :attr:`_orm.ORMExecuteState.is_orm_statement`
event-level attribute.
.. change::
:tags: bug, postgresql, regression
:tickets: 9808
Repaired the base :class:`.Uuid` datatype for the PostgreSQL dialect to
make full use of the PG-specific ``UUID`` dialect-specific datatype when
"native_uuid" is selected, so that PG driver behaviors are included. This
issue became apparent due to the insertmanyvalues improvement made as part
of :ticket:`9618`, where in a similar manner as that of :ticket:`9739`, the
asyncpg driver is very sensitive to datatype casts being present or not,
and the PostgreSQL driver-specific native ``UUID`` datatype must be invoked
when this generic type is used so that these casts take place.
.. changelog::
```
### 2.0.14
```
:released: May 18, 2023
.. change::
:tags: bug, sql
:tickets: 9772
Fixed issue in :func:`_sql.values` construct where an internal compilation
error would occur if the construct were used inside of a scalar subquery.
.. change::
:tags: usecase, sql
:tickets: 9752
Generalized the MSSQL :func:`_sql.try_cast` function into the
``sqlalchemy.`` import namespace so that it may be implemented by third
party dialects as well. Within SQLAlchemy, the :func:`_sql.try_cast`
function remains a SQL Server-only construct that will raise
:class:`.CompileError` if used with backends that don't support it.
:func:`_sql.try_cast` implements a CAST where un-castable conversions are
returned as NULL, instead of raising an error. Theoretically, the construct
could be implemented by third party dialects for Google BigQuery, DuckDB,
and Snowflake, and possibly others.
Pull request courtesy Nick Crews.
.. change::
:tags: bug, tests, pypy
:tickets: 9789
Fixed test that relied on the ``sys.getsizeof()`` function to not run on
pypy, where this function appears to have different behavior than it does
on cpython.
.. change::
:tags: bug, orm
:tickets: 9777
Modified the ``JoinedLoader`` implementation to use a simpler approach in
one particular area where it previously used a cached structure that would
be shared among threads. The rationale is to avoid a potential race
condition which is suspected of being the cause of a particular crash
that's been reported multiple times. The cached structure in question is
still ultimately "cached" via the compiled SQL cache, so a performance
degradation is not anticipated.
.. change::
:tags: bug, orm, regression
:tickets: 9767
Fixed regression where use of :func:`_dml.update` or :func:`_dml.delete`
within a :class:`_sql.CTE` construct, then used in a :func:`_sql.select`,
would raise a :class:`.CompileError` as a result of ORM related rules for
performing ORM-level update/delete statements.
.. change::
:tags: bug, orm
:tickets: 9766
Fixed issue in new ORM Annotated Declarative where using a
:class:`_schema.ForeignKey` (or other column-level constraint) inside of
:func:`_orm.mapped_column` which is then copied out to models via pep-593
``Annotated`` would apply duplicates of each constraint to the
:class:`_schema.Column` as produced in the target :class:`_schema.Table`,
leading to incorrect CREATE TABLE DDL as well as migration directives under
Alembic.
.. change::
:tags: bug, orm
:tickets: 9779
Fixed issue where using additional relationship criteria with the
:func:`_orm.joinedload` loader option, where the additional criteria itself
contained correlated subqueries that referred to the joined entities and
therefore also required "adaption" to aliased entities, would be excluded
from this adaption, producing the wrong ON clause for the joinedload.
.. change::
:tags: bug, postgresql
:tickets: 9773
Fixed apparently very old issue where the
:paramref:`_postgresql.ENUM.create_type` parameter, when set to its
non-default of ``False``, would not be propagated when the
:class:`_schema.Column` which it's a part of were copied, as is common when
using ORM Declarative mixins.
.. changelog::
```
### 2.0.13
```
:released: May 10, 2023
.. change::
:tags: usecase, asyncio
:tickets: 9731
Added a new helper mixin :class:`_asyncio.AsyncAttrs` that seeks to improve
the use of lazy-loader and other expired or deferred ORM attributes with
asyncio, providing a simple attribute accessor that provides an ``await``
interface to any ORM attribute, whether or not it needs to emit SQL.
.. seealso::
:class:`_asyncio.AsyncAttrs`
.. change::
:tags: bug, orm
:tickets: 9717
Fixed issue where ORM Annotated Declarative would not resolve forward
references correctly in all cases; in particular, when using
``from __future__ import annotations`` in combination with Pydantic
dataclasses.
.. change::
:tags: typing, sql
:tickets: 9656
Added type :data:`_sql.ColumnExpressionArgument` as a public-facing type
that indicates column-oriented arguments which are passed to SQLAlchemy
constructs, such as :meth:`_sql.Select.where`, :func:`_sql.and_` and
others. This may be used to add typing to end-user functions which call
these methods.
.. change::
:tags: bug, orm
:tickets: 9746
Fixed issue in new :ref:`orm_queryguide_upsert_returning` feature where the
``populate_existing`` execution option was not being propagated to the
loading option, preventing existing attributes from being refreshed
in-place.
.. change::
:tags: bug, sql
Fixed the base class for dialect-specific float/double types; Oracle
:class:`_oracle.BINARY_DOUBLE` now subclasses :class:`_sqltypes.Double`,
and internal types for :class:`_sqltypes.Float` for asyncpg and pg8000 now
correctly subclass :class:`_sqltypes.Float`.
.. change::
:tags: bug, ext
:tickets: 9676
Fixed issue in :class:`_mutable.Mutable` where event registration for ORM
mapped attributes would be called repeatedly for mapped inheritance
subclasses, leading to duplicate events being invoked in inheritance
hierarchies.
.. change::
:tags: bug, orm
:tickets: 9715
Fixed loader strategy pathing issues where eager loaders such as
:func:`_orm.joinedload` / :func:`_orm.selectinload` would fail to traverse
fully for many-levels deep following a load that had a
:func:`_orm.with_polymorphic` or similar construct as an interim member.
.. change::
:tags: usecase, sql
:tickets: 9721
Implemented the "cartesian product warning" for UPDATE and DELETE
statements, those which include multiple tables that are not correlated
together in some way.
.. change::
:tags: bug, sql
Fixed issue where :func:`_dml.update` construct that included multiple
tables and no VALUES clause would raise with an internal error. Current
behavior for :class:`_dml.Update` with no values is to generate a SQL
UPDATE statement with an empty "set" clause, so this has been made
consistent for this specific sub-case.
.. change::
:tags: oracle, reflection
:tickets: 9597
Added reflection support in the Oracle dialect to expression based indexes
and the ordering direction of index expressions.
.. change::
:tags: performance, schema
:tickets: 9597
Improved how table columns are added, avoiding unnecessary allocations,
significantly speeding up the creation of many table, like when reflecting
entire schemas.
.. change::
:tags: bug, typing
:tickets: 9762
Fixed typing for the :paramref:`_orm.Session.get.with_for_update` parameter
of :meth:`_orm.Session.get` and :meth:`_orm.Session.refresh` (as well as
corresponding methods on :class:`_asyncio.AsyncSession`) to accept boolean
``True`` and all other argument forms accepted by the parameter at runtime.
.. change::
:tags: bug, postgresql, regression
:tickets: 9739
Fixed another regression due to the "insertmanyvalues" change in 2.0.10 as
part of :ticket:`9618`, in a similar way as regression :ticket:`9701`, where
:class:`.LargeBinary` datatypes also need additional casts on when using the
asyncpg driver specifically in order to work with the new bulk INSERT
format.
.. change::
:tags: bug, orm
:tickets: 9630
Fixed issue in :func:`_orm.mapped_column` construct where the correct
warning for "column X named directly multiple times" would not be emitted
when ORM mapped attributes referred to the same :class:`_schema.Column`, if
the :func:`_orm.mapped_column` construct were involved, raising an internal
assertion instead.
.. change::
:tags: bug, asyncio
Fixed issue in semi-private ``await_only()`` and ``await_fallback()``
concurrency functions where the given awaitable would remain un-awaited if
the function threw a ``GreenletError``, which could cause "was not awaited"
warnings later on if the program continued. In this case, the given
awaitable is now cancelled before the exception is thrown.
.. changelog::
```
### 2.0.12
```
:released: April 30, 2023
.. change::
:tags: bug, mysql, mariadb
:tickets: 9722
Fixed issues regarding reflection of comments for :class:`_schema.Table`
and :class:`_schema.Column` objects, where the comments contained control
characters such as newlines. Additional testing support for these
characters as well as extended Unicode characters in table and column
comments (the latter of which aren't supported by MySQL/MariaDB) added to
testing overall.
.. changelog::
```
### 2.0.11
```
:released: April 26, 2023
.. change::
:tags: bug, engine, regression
:tickets: 9682
Fixed regression which prevented the :attr:`_engine.URL.normalized_query`
attribute of :class:`_engine.URL` from functioning.
.. change::
:tags: bug, postgresql, regression
:tickets: 9701
Fixed critical regression caused by :ticket:`9618`, which modified the
architecture of the :term:`insertmanyvalues` feature for 2.0.10, which
caused floating point values to lose all decimal places when being inserted
using the insertmanyvalues feature with either the psycopg2 or psycopg
drivers.
.. change::
:tags: bug, mssql
Implemented the :class:`_sqltypes.Double` type for SQL Server, where it
will render ``DOUBLE PRECISION`` at DDL time. This is implemented using
a new MSSQL datatype :class:`_mssql.DOUBLE_PRECISION` which also may
be used directly.
.. change::
:tags: bug, oracle
Fixed issue in Oracle dialects where ``Decimal`` returning types such as
:class:`_sqltypes.Numeric` would return floating point values, rather than
``Decimal`` objects, when these columns were used in the
:meth:`_dml.Insert.returning` clause to return INSERTed values.
.. change::
:tags: bug, orm
:tickets: 9583, 9595
Fixed 2.0 regression where use of :func:`_sql.bindparam()` inside of
:meth:`_dml.Insert.values` would fail to be interpreted correctly when
executing the :class:`_dml.Insert` statement using the ORM
:class:`_orm.Session`, due to the new
:ref:`ORM-enabled insert feature <orm_queryguide_bulk_insert>` not
implementing this use case.
.. change::
:tags: usecase, orm
:tickets: 9583, 9595
The :ref:`ORM bulk INSERT and UPDATE <orm_expression_update_delete>`
features now add these capabilities:
* The requirement that extra parameters aren't passed when using ORM
INSERT using the "orm" dml_strategy setting is lifted.
* The requirement that additional WHERE criteria is not passed when using
ORM UPDATE using the "bulk" dml_strategy setting is lifted. Note that
in this case, the check for expected row count is turned off.
.. change::
:tags: usecase, sql
:tickets: 8285
Added support for slice access with :class:`.ColumnCollection`, e.g.
``table.c[0:5]``, ``subquery.c[:-1]`` etc. Slice access returns a sub
:class:`.ColumnCollection` in the same way as passing a tuple of keys. This
is a natural continuation of the key-tuple access added for :ticket:`8285`,
where it appears to be an oversight that the slice access use case was
omitted.
.. change::
:tags: bug, typing
:tickets: 9644
Improved typing of :class:`_engine.RowMapping` to indicate that it
support also :class:`_schema.Column` as index objects, not only
string names. Pull request courtesy Andy Freeland.
.. change::
:tags: engine, performance
:tickets: 9678, 9680
A series of performance enhancements to :class:`_engine.Row`:
* ``__getattr__`` performance of the row's "named tuple" interface has
been improved; within this change, the :class:`_engine.Row`
implementation has been streamlined, removing constructs and logic
that were specific to the 1.4 and prior series of SQLAlchemy.
As part of this change, the serialization format of :class:`_engine.Row`
has been modified slightly, however rows which were pickled with previous
SQLAlchemy 2.0 releases will be recognized within the new format.
Pull request courtesy J. Nick Koston.
* Improved row processing performance for "binary" datatypes by making the
"bytes" handler conditional on a per driver basis. As a result, the
"bytes" result handler has been removed for nearly all drivers other than
psycopg2, all of which in modern forms support returning Python "bytes"
directly. Pull request courtesy J. Nick Koston.
* Additional refactorings inside of :class:`_engine.Row` to improve
performance by Federico Caselli.
.. changelog::
```
### 2.0.10
```
:released: April 21, 2023
.. change::
:tags: bug, typing
:tickets: 9650
Added typing information for recently added operators
:meth:`.ColumnOperators.icontains`, :meth:`.ColumnOperators.istartswith`,
:meth:`.ColumnOperators.iendswith`, and bitwise operators
:meth:`.ColumnOperators.bitwise_and`, :meth:`.ColumnOperators.bitwise_or`,
:meth:`.ColumnOperators.bitwise_xor`, :meth:`.ColumnOperators.bitwise_not`,
:meth:`.ColumnOperators.bitwise_lshift`
:meth:`.ColumnOperators.bitwise_rshift`. Pull request courtesy Martijn
Pieters.
.. change::
:tags: bug, oracle
Fixed issue where the :class:`_sqltypes.Uuid` datatype could not be used in
an INSERT..RETURNING clause with the Oracle dialect.
.. change::
:tags: usecase, engine
:tickets: 9613
Added :func:`_sa.create_pool_from_url` and
:func:`_asyncio.create_async_pool_from_url` to create
a :class:`_pool.Pool` instance from an input url passed as string
or :class:`_sa.URL`.
.. change::
:tags: bug, engine
:tickets: 9618, 9603
Repaired a major shortcoming which was identified in the
:ref:`engine_insertmanyvalues` performance optimization feature first
introduced in the 2.0 series. This was a continuation of the change in
2.0.9 which disabled the SQL Server version of the feature due to a
reliance in the ORM on apparent row ordering that is not guaranteed to take
place. The fix applies new logic to all "insertmanyvalues" operations,
which takes effect when a new parameter
:paramref:`_dml.Insert.returning.sort_by_parameter_order` on the
:meth:`_dml.Insert.returning` or :meth:`_dml.UpdateBase.return_defaults`
methods, that through a combination of alternate SQL forms, direct
correspondence of client side parameters, and in some cases downgrading to
running row-at-a-time, will apply sorting to each batch of returned rows
using correspondence to primary key or other unique values in each row
which can be correlated to the input data.
Performance impact is expected to be minimal as nearly all common primary
key scenarios are suitable for parameter-ordered batching to be
achieved for all backends other than SQLite, while "row-at-a-time"
mode operates with a bare minimum of Python overhead compared to the very
heavyweight approaches used in the 1.x series. For SQLite, there is no
difference in performance when "row-at-a-time" mode is used.
It's anticipated that with an efficient "row-at-a-time" INSERT with
RETURNING batching capability, the "insertmanyvalues" feature can be later
be more easily generalized to third party backends that include RETURNING
support but not necessarily easy ways to guarantee a correspondence
with parameter order.
.. seealso::
:ref:`engine_insertmanyvalues_returning_order`
.. change::
:tags: bug, mssql
:tickets: 9618, 9603
Restored the :term:`insertmanyvalues` feature for Microsoft SQL Server.
This feature was disabled in version 2.0.9 due to an apparent reliance
on the ordering of RETURNING that is not guaranteed. The architecture of
the "insertmanyvalues" feature has been reworked to accommodate for
specific organizations of INSERT statements and result row handling that
can guarantee the correspondence of returned rows to input records.
.. seealso::
:ref:`engine_insertmanyvalues_returning_order`
.. change::
:tags: usecase, postgresql
:tickets: 9608
Added ``prepared_statement_name_func`` connection argument option in the
asyncpg dialect. This option allows passing a callable used to customize
the name of the prepared statement that will be created by the driver
when executing queries. Pull request courtesy Pavel Sirotkin.
.. seealso::
:ref:`asyncpg_prepared_statement_name`
.. change::
:tags: typing, bug
Updates to the codebase to pass typing with Mypy 1.2.0.
.. change::
:tags: bug, typing
:tickets: 9669
Fixed typing issue where :meth:`_orm.PropComparator.and_` expressions would
not be correctly typed inside of loader options such as
:func:`_orm.selectinload`.
.. change::
:tags: bug, orm
:tickets: 9625
Fixed issue where the :meth:`_orm.declared_attr.directive` modifier was not
correctly honored for subclasses when applied to the ``__mapper_args__``
special method name, as opposed to direct use of
:class:`_orm.declared_attr`. The two constructs should have identical
runtime behaviors.
.. change::
:tags: bug, postgresql
:tickets: 9611
Restored the :paramref:`_postgresql.ENUM.name` parameter as optional in the
signature for :class:`_postgresql.ENUM`, as this is chosen automatically
from a given pep-435 ``Enum`` type.
.. change::
:tags: bug, postgresql
:tickets: 9621
Fixed issue where the comparison for :class:`_postgresql.ENUM` against a
plain string would cast that right-hand side type as VARCHAR, which due to
more explicit casting added to dialects such as asyncpg would produce a
PostgreSQL type mismatch error.
.. change::
:tags: bug, orm
:tickets: 9635
Made an improvement to the :func:`_orm.with_loader_criteria` loader option
to allow it to be indicated in the :meth:`.Executable.options` method of a
top-level statement that is not itself an ORM statement. Examples include
:func:`_sql.select` that's embedded in compound statements such as
:func:`_sql.union`, within an :meth:`_dml.Insert.from_select` construct, as
well as within CTE expressions that are not ORM related at the top level.
.. change::
:tags: bug, orm
:tickets: 9685
Fixed bug in ORM bulk insert feature where additional unnecessary columns
would be rendered in the INSERT statement if RETURNING of individual columns
were requested.
.. change::
:tags: bug, postgresql
:tickets: 9615
Fixed issue that prevented reflection of expression based indexes
with long expressions in PostgreSQL. The expression where erroneously
truncated to the identifier length (that's 63 bytes by default).
.. change::
:tags: usecase, postgresql
:tickets: 9509
Add missing :meth:`_postgresql.Range.intersection` method.
Pull request courtesy Yurii Karabas.
.. change::
:tags: bug, orm
:tickets: 9628
Fixed bug in ORM Declarative Dataclasses where the
:func:`_orm.query_expression` and :func:`_orm.column_property`
constructs, which are documented as read-only constructs in the context of
a Declarative mapping, could not be used with a
:class:`_orm.MappedAsDataclass` class without adding ``init=False``, which
in the case of :func:`_orm.query_expression` was not possible as no
``init`` parameter was included. These constructs have been modified from a
dataclass perspective to be assumed to be "read only", setting
``init=False`` by default and no longer including them in the pep-681
constructor. The dataclass parameters for :func:`_orm.column_property`
``init``, ``default``, ``default_factory``, ``kw_only`` are now deprecated;
these fields don't apply to :func:`_orm.column_property` as used in a
Declarative dataclasses configuration where the construct would be
read-only. Also added read-specific parameter
:paramref:`_orm.query_expression.compare` to
:func:`_orm.query_expression`; :paramref:`_orm.query_expression.repr`
was already present.
.. change::
:tags: bug, orm
Added missing :paramref:`_orm.mapped_column.active_history` parameter
to :func:`_orm.mapped_column` construct.
.. changelog::
```
### 2.0.9
```
:released: April 5, 2023
.. change::
:tags: bug, mssql
:tickets: 9603
The SQLAlchemy "insertmanyvalues" feature which allows fast INSERT of
many rows while also supporting RETURNING is temporarily disabled for
SQL Server. As the unit of work currently relies upon this feature such
that it matches existing ORM objects to returned primary key
identities, this particular use pattern does not work with SQL Server
in all cases as the order of rows returned by "OUTPUT inserted" may not
always match the order in which the tuples were sent, leading to
the ORM making the wrong decisions about these objects in subsequent
operations.
The feature will be re-enabled in an upcoming release and will again
take effect for multi-row INSERT statements, however the unit-of-work's
use of the feature will be disabled, possibly for all dialects, unless
ORM-mapped tables also include a "sentinel" column so that the
returned rows can be referenced back to the original data passed in.
.. change::
:tags: bug, mariadb
:tickets: 9588
Added ``row_number`` as reserved word in MariaDb.
.. change::
:tags: bug, mssql
:tickets: 9586
Changed the bulk INSERT strategy used for SQL Server "executemany" with
pyodbc when ``fast_executemany`` is set to ``True`` by using
``fast_executemany`` / ``cursor.executemany()`` for bulk INSERT that does
not include RETURNING, restoring the same behavior as was used in
SQLAlchemy 1.4 when this parameter is set.
New performance details from end users have shown that ``fast_executemany``
is still much faster for very large datasets as it uses ODBC commands that
can receive all rows in a single round trip, allowing for much larger
datasizes than the batches that can be sent by "insertmanyvalues"
as was implemented for SQL Server.
While this change was made such that "insertmanyvalues" continued to be
used for INSERT that includes RETURNING, as well as if ``fast_executemany``
were not set, due to :ticket:`9603`, the "insertmanyvalues" strategy has
been disabled for SQL Server across the board in any case.
.. changelog::
```
### 2.0.8
```
:released: March 31, 2023
.. change::
:tags: bug, orm
:tickets: 9553
Fixed issue in ORM Annotated Declarative where using a recursive type (e.g.
using a nested Dict type) would result in a recursion overflow in the ORM's
annotation resolution logic, even if this datatype were not necessary to
map the column.
.. change::
:tags: bug, examples
Fixed issue in "versioned history" example where using a declarative base
that is derived from :class:`_orm.DeclarativeBase` would fail to be mapped.
Additionally, repaired the given test suite so that the documented
instructions for running the example using Python unittest now work again.
.. change::
:tags: bug, orm
:tickets: 9550
Fixed issue where the :func:`_orm.mapped_column` construct would raise an
internal error if used on a Declarative mixin and included the
:paramref:`_orm.mapped_column.deferred` parameter.
.. change::
:tags: bug, mysql
:tickets: 9544
Fixed issue where string datatypes such as :class:`_sqltypes.CHAR`,
:class:`_sqltypes.VARCHAR`, :class:`_sqltypes.TEXT`, as
This PR updates SQLAlchemy from 1.2.7 to 2.0.21.
Changelog
### 2.0.21 ``` :released: September 18, 2023 .. change:: :tags: bug, sql :tickets: 9610 Adjusted the operator precedence for the string concatenation operator to be equal to that of string matching operators, such as :meth:`.ColumnElement.like`, :meth:`.ColumnElement.regexp_match`, :meth:`.ColumnElement.match`, etc., as well as plain ``==`` which has the same precedence as string comparison operators, so that parenthesis will be applied to a string concatenation expression that follows a string match operator. This provides for backends such as PostgreSQL where the "regexp match" operator is apparently of higher precedence than the string concatenation operator. .. change:: :tags: bug, sql :tickets: 10342 Qualified the use of ``hashlib.md5()`` within the DDL compiler, which is used to generate deterministic four-character suffixes for long index and constraint names in DDL statements, to include the Python 3.9+ ``usedforsecurity=False`` parameter so that Python interpreters built for restricted environments such as FIPS do not consider this call to be related to security concerns. .. change:: :tags: bug, postgresql :tickets: 10226 Fixed regression which appeared in 2.0 due to :ticket:`8491` where the revised "ping" used for PostgreSQL dialects when the :paramref:`_sa.create_engine.pool_pre_ping` parameter is in use would interfere with the use of asyncpg with PGBouncer "transaction" mode, as the multiple PostgreSQL commands emitted by asnycpg could be broken out among multiple connections leading to errors, due to the lack of any transaction around this newly revised "ping". The ping is now invoked within a transaction, in the same way that is implicit with all other backends that are based on the pep-249 DBAPI; this guarantees that the series of PG commands sent by asyncpg for this command are invoked on the same backend connection without it jumping to a different connection mid-command. The transaction is not used if the asyncpg dialect is used in "AUTOCOMMIT" mode, which remains incompatible with pgbouncer transaction mode. .. change:: :tags: bug, orm :tickets: 10279 Adjusted the ORM's interpretation of the "target" entity used within :class:`.Update` and :class:`.Delete` to not interfere with the target "from" object passed to the statement, such as when passing an ORM-mapped :class:`_orm.aliased` construct that should be maintained within a phrase like "UPDATE FROM". Cases like ORM session synchonize using "SELECT" statements such as with MySQL/ MariaDB will still have issues with UPDATE/DELETE of this form so it's best to disable synchonize_session when using DML statements of this type. .. change:: :tags: bug, orm :tickets: 10348 Added new capability to the :func:`_orm.selectin_polymorphic` loader option which allows other loader options to be bundled as siblings, referring to one of its subclasses, within the sub-options of parent loader option. Previously, this pattern was only supported if the :func:`_orm.selectin_polymorphic` were at the top level of the options for the query. See new documentation section for example. As part of this change, improved the behavior of the :meth:`_orm.Load.selectin_polymorphic` method / loader strategy so that the subclass load does not load most already-loaded columns from the parent table, when the option is used against a class that is already being relationship-loaded. Previously, the logic to load only the subclass columns worked only for a top level class load. .. seealso:: :ref:`polymorphic_selectin_as_loader_option_target_plus_opts` .. change:: :tags: bug, typing :tickets: 10264, 9284 Fixed regression introduced in 2.0.20 via :ticket:`9600` fix which attempted to add more formal typing to :paramref:`_schema.MetaData.naming_convention`. This change prevented basic naming convention dictionaries from passing typing and has been adjusted so that a plain dictionary of strings for keys as well as dictionaries that use constraint types as keys or a mix of both, are again accepted. As part of this change, lesser used forms of the naming convention dictionary are also typed, including that it currently allows for ``Constraint`` type objects as keys as well. .. change:: :tags: usecase, typing :tickets: 10288 Made the contained type for :class:`.Mapped` covariant; this is to allow greater flexibility for end-user typing scenarios, such as the use of protocols to represent particular mapped class structures that are passed to other functions. As part of this change, the contained type was also made covariant for dependent and related types such as :class:`_orm.base.SQLORMOperations`, :class:`_orm.WriteOnlyMapped`, and :class:`_sql.SQLColumnExpression`. Pull request courtesy Roméo Després. .. change:: :tags: bug, engine :tickets: 10275 Fixed a series of reflection issues affecting the PostgreSQL, MySQL/MariaDB, and SQLite dialects when reflecting foreign key constraints where the target column contained parenthesis in one or both of the table name or column name. .. change:: :tags: bug, sql :tickets: 10280 The :class:`.Values` construct will now automatically create a proxy (i.e. a copy) of a :class:`_sql.column` if the column were already associated with an existing FROM clause. This allows that an expression like ``values_obj.c.colname`` will produce the correct FROM clause even in the case that ``colname`` was passed as a :class:`_sql.column` that was already used with a previous :class:`.Values` or other table construct. Originally this was considered to be a candidate for an error condition, however it's likely this pattern is already in widespread use so it's now added to support. .. change:: :tags: bug, setup :tickets: 10321 Fixed very old issue where the full extent of SQLAlchemy modules, including ``sqlalchemy.testing.fixtures``, could not be imported outside of a pytest run. This suits inspection utilities such as ``pkgutil`` that attempt to import all installed modules in all packages. .. change:: :tags: usecase, sql :tickets: 10269 Adjusted the :class:`_types.Enum` datatype to accept an argument of ``None`` for the :paramref:`_types.Enum.length` parameter, resulting in a VARCHAR or other textual type with no length in the resulting DDL. This allows for new elements of any length to be added to the type after it exists in the schema. Pull request courtesy Eugene Toder. .. change:: :tags: bug, typing :tickets: 9878 Fixed the type annotation for ``__class_getitem__()`` as applied to the ``Visitable`` class at the base of expression constructs to accept ``Any`` for a key, rather than ``str``, which helps with some IDEs such as PyCharm when attempting to write typing annotations for SQL constructs which include generic selectors. Pull request courtesy Jordan Macdonald. .. change:: :tags: bug, typing :tickets: 10353 Repaired the core "SQL element" class ``SQLCoreOperations`` to support the ``__hash__()`` method from a typing perspective, as objects like :class:`.Column` and ORM :class:`.InstrumentedAttribute` are hashable and are used as dictionary keys in the public API for the :class:`_dml.Update` and :class:`_dml.Insert` constructs. Previously, type checkers were not aware the root SQL element was hashable. .. change:: :tags: bug, typing :tickets: 10337 Fixed typing issue with :meth:`_sql.Existing.select_from` that prevented its use with ORM classes. .. change:: :tags: usecase, sql :tickets: 9873 Added new generic SQL function :class:`_functions.aggregate_strings`, which accepts a SQL expression and a decimeter, concatenating strings on multiple rows into a single aggregate value. The function is compiled on a per-backend basis, into functions such as ``group_concat(),`` ``string_agg()``, or ``LISTAGG()``. Pull request courtesy Joshua Morris. .. change:: :tags: typing, bug :tickets: 10131 Update type annotations for ORM loading options, restricting them to accept only `"*"` instead of any string for string arguments. Pull request courtesy Janek Nouvertné. .. changelog:: ``` ### 2.0.20 ``` :released: August 15, 2023 .. change:: :tags: bug, orm :tickets: 10169 Fixed issue where the ORM's generation of a SELECT from a joined inheritance model with same-named columns in superclass and subclass would somehow not send the correct list of column names to the :class:`.CTE` construct, when the RECURSIVE column list were generated. .. change:: :tags: bug, typing :tickets: 9185 Typing improvements: * :class:`.CursorResult` is returned for some forms of :meth:`_orm.Session.execute` where DML without RETURNING is used * fixed type for :paramref:`_orm.Query.with_for_update.of` parameter within :meth:`_orm.Query.with_for_update` * improvements to ``_DMLColumnArgument`` type used by some DML methods to pass column expressions * Add overload to :func:`_sql.literal` so that it is inferred that the return type is ``BindParameter[NullType]`` where :paramref:`_sql.literal.type_` param is None * Add overloads to :meth:`_sql.ColumnElement.op` so that the inferred type when :paramref:`_sql.ColumnElement.op.return_type` is not provided is ``Callable[[Any], BinaryExpression[Any]]`` * Add missing overload to :meth:`_sql.ColumnElement.__add__` Pull request courtesy Mehdi Gmira. .. change:: :tags: usecase, orm :tickets: 10192 Implemented the "RETURNING '*'" use case for ORM enabled DML statements. This will render in as many cases as possible and return the unfiltered result set, however is not supported for multi-parameter "ORM bulk INSERT" statements that have specific column rendering requirements. .. change:: :tags: bug, typing :tickets: 10182 Fixed issue in :class:`_orm.Session` and :class:`_asyncio.AsyncSession` methods such as :meth:`_orm.Session.connection` where the :paramref:`_orm.Session.connection.execution_options` parameter were hardcoded to an internal type that is not user-facing. .. change:: :tags: orm, bug :tickets: 10231 Fixed fairly major issue where execution options passed to :meth:`_orm.Session.execute`, as well as execution options local to the ORM executed statement itself, would not be propagated along to eager loaders such as that of :func:`_orm.selectinload`, :func:`_orm.immediateload`, and :meth:`_orm.subqueryload`, making it impossible to do things such as disabling the cache for a single statement or using ``schema_translate_map`` for a single statement, as well as the use of user-custom execution options. A change has been made where **all** user-facing execution options present for :meth:`_orm.Session.execute` will be propagated along to additional loaders. As part of this change, the warning for "excessively deep" eager loaders leading to caching being disabled can be silenced on a per-statement basis by sending ``execution_options={"compiled_cache": None}`` to :meth:`_orm.Session.execute`, which will disable caching for the full series of statements within that scope. .. change:: :tags: usecase, asyncio :tickets: 9698 Added new methods :meth:`_asyncio.AsyncConnection.aclose` as a synonym for :meth:`_asyncio.AsyncConnection.close` and :meth:`_asyncio.AsyncSession.aclose` as a synonym for :meth:`_asyncio.AsyncSession.close` to the :class:`_asyncio.AsyncConnection` and :class:`_asyncio.AsyncSession` objects, to provide compatibility with Python standard library ``contextlib.aclosing`` construct. Pull request courtesy Grigoriev Semyon. .. change:: :tags: bug, orm :tickets: 10124 Fixed issue where internal cloning used by the ORM for expressions like :meth:`_orm.relationship.Comparator.any` to produce correlated EXISTS constructs would interfere with the "cartesian product warning" feature of the SQL compiler, leading the SQL compiler to warn when all elements of the statement were correctly joined. .. change:: :tags: orm, bug :tickets: 10139 Fixed issue where the ``lazy="immediateload"`` loader strategy would place an internal loading token into the ORM mapped attribute under circumstances where the load should not occur, such as in a recursive self-referential load. As part of this change, the ``lazy="immediateload"`` strategy now honors the :paramref:`_orm.relationship.join_depth` parameter for self-referential eager loads in the same way as that of other eager loaders, where leaving it unset or set at zero will lead to a self-referential immediateload not occurring, setting it to a value of one or greater will immediateload up until that given depth. .. change:: :tags: bug, orm :tickets: 10175 Fixed issue where dictionary-based collections such as :func:`_orm.attribute_keyed_dict` did not fully pickle/unpickle correctly, leading to issues when attempting to mutate such a collection after unpickling. .. change:: :tags: bug, orm :tickets: 10125 Fixed issue where chaining :func:`_orm.load_only` or other wildcard use of :func:`_orm.defer` from another eager loader using a :func:`_orm.aliased` against a joined inheritance subclass would fail to take effect for columns local to the superclass. .. change:: :tags: bug, orm :tickets: 10167 Fixed issue where an ORM-enabled :func:`_sql.select` construct would not render any CTEs added only via the :meth:`_sql.Select.add_cte` method that were not otherwise referenced in the statement. .. change:: :tags: bug, examples The dogpile_caching examples have been updated for 2.0 style queries. Within the "caching query" logic itself there is one conditional added to differentiate between ``Query`` and ``select()`` when performing an invalidation operation. .. change:: :tags: typing, usecase :tickets: 10173 Added new typing only utility functions :func:`.Nullable` and :func:`.NotNullable` to type a column or ORM class as, respectively, nullable or not nullable. These function are no-op at runtime, returning the input unchanged. .. change:: :tags: bug, engine :tickets: 10147 Fixed critical issue where setting :paramref:`_sa.create_engine.isolation_level` to ``AUTOCOMMIT`` (as opposed to using the :meth:`_engine.Engine.execution_options` method) would fail to restore "autocommit" to a pooled connection if an alternate isolation level were temporarily selected using :paramref:`_engine.Connection.execution_options.isolation_level`. .. changelog:: ``` ### 2.0.19 ``` :released: July 15, 2023 .. change:: :tags: bug, orm :tickets: 10089 Fixed issue where setting a relationship collection directly, where an object in the new collection were already present, would not trigger a cascade event for that object, leading to it not being added to the :class:`_orm.Session` if it were not already present. This is similar in nature to :ticket:`6471` and is a more apparent issue due to the removal of ``cascade_backrefs`` in the 2.0 series. The :meth:`_orm.AttributeEvents.append_wo_mutation` event added as part of :ticket:`6471` is now also emitted for existing members of a collection that are present in a bulk set of that same collection. .. change:: :tags: bug, engine :tickets: 10093 Renamed :attr:`_result.Row.t` and :meth:`_result.Row.tuple` to :attr:`_result.Row._t` and :meth:`_result.Row._tuple`; this is to suit the policy that all methods and pre-defined attributes on :class:`.Row` should be in the style of Python standard library ``namedtuple`` where all fixed names have a leading underscore, to avoid name conflicts with existing column names. The previous method/attribute is now deprecated and will emit a deprecation warning. .. change:: :tags: bug, postgresql :tickets: 10069 Fixed regression caused by improvements to PostgreSQL URL parsing in :ticket:`10004` where "host" query string arguments that had colons in them, to support various third party proxy servers and/or dialects, would not parse correctly as these were evaluted as ``host:port`` combinations. Parsing has been updated to consider a colon as indicating a ``host:port`` value only if the hostname contains only alphanumeric characters with dots or dashes only (e.g. no slashes), followed by exactly one colon followed by an all-integer token of zero or more integers. In all other cases, the full string is taken as a host. .. change:: :tags: bug, engine :tickets: 10079 Added detection for non-string, non-:class:`_engine.URL` objects to the :func:`_engine.make_url` function, allowing ``ArgumentError`` to be thrown immediately, rather than causing failures later on. Special logic ensures that mock forms of :class:`_engine.URL` are allowed through. Pull request courtesy Grigoriev Semyon. .. change:: :tags: bug, orm :tickets: 10090 Fixed issue where objects that were associated with an unloaded collection via backref, but were not merged into the :class:`_orm.Session` due to the removal of ``cascade_backrefs`` in the 2.0 series, would not emit a warning that these objects were not being included in a flush, even though they were pending members of the collection; in other such cases, a warning is emitted when a collection being flushed contains non-attached objects which will be essentially discarded. The addition of the warning for backref-pending collection members establishes greater consistency with collections that may be present or non-present and possibly flushed or not flushed at different times based on different relationship loading strategies. .. change:: :tags: bug, postgresql :tickets: 10096 Fixed issue where comparisons to the :class:`_postgresql.CITEXT` datatype would cast the right side to ``VARCHAR``, leading to the right side not being interpreted as a ``CITEXT`` datatype, for the asyncpg, psycopg3 and pg80000 dialects. This led to the :class:`_postgresql.CITEXT` type being essentially unusable for practical use; this is now fixed and the test suite has been corrected to properly assert that expressions are rendered correctly. .. change:: :tags: bug, orm, regression :tickets: 10098 Fixed additional regression caused by :ticket:`9805` where more aggressive propagation of the "ORM" flag on statements could lead to an internal attribute error when embedding an ORM :class:`.Query` construct that nonetheless contained no ORM entities within a Core SQL statement, in this case ORM-enabled UPDATE and DELETE statements. .. changelog:: ``` ### 2.0.18 ``` :released: July 5, 2023 .. change:: :tags: usecase, typing :tickets: 10054 Improved typing when using standalone operator functions from ``sqlalchemy.sql.operators`` such as ``sqlalchemy.sql.operators.eq``. .. change:: :tags: usecase, mariadb, reflection :tickets: 10028 Allowed reflecting :class:`_types.UUID` columns from MariaDB. This allows Alembic to properly detect the type of such columns in existing MariaDB databases. .. change:: :tags: bug, postgresql :tickets: 9945 Added new parameter ``native_inet_types=False`` to all PostgreSQL dialects, which indicates converters used by the DBAPI to convert rows from PostgreSQL :class:`.INET` and :class:`.CIDR` columns into Python ``ipaddress`` datatypes should be disabled, returning strings instead. This allows code written to work with strings for these datatypes to be migrated to asyncpg, psycopg, or pg8000 without code changes other than adding this parameter to the :func:`_sa.create_engine` or :func:`_asyncio.create_async_engine` function call. .. seealso:: :ref:`postgresql_network_datatypes` .. change:: :tags: usecase, extensions :tickets: 10013 Added new option to :func:`.association_proxy` :paramref:`.association_proxy.create_on_none_assignment`; when an association proxy which refers to a scalar relationship is assigned the value ``None``, and the referenced object is not present, a new object is created via the creator. This was apparently an undefined behavior in the 1.2 series that was silently removed. .. change:: :tags: bug, typing :tickets: 10061 Fixed some of the typing within the :func:`_orm.aliased` construct to correctly accept a :class:`.Table` object that's been aliased with :meth:`.Table.alias`, as well as general support for :class:`.FromClause` objects to be passed as the "selectable" argument, since this is all supported. .. change:: :tags: bug, engine :tickets: 10025 Adjusted the :paramref:`_sa.create_engine.schema_translate_map` feature such that **all** schema names in the statement are now tokenized, regardless of whether or not a specific name is in the immediate schema translate map given, and to fallback to substituting the original name when the key is not in the actual schema translate map at execution time. These two changes allow for repeated use of a compiled object with schema schema_translate_maps that include or dont include various keys on each run, allowing cached SQL constructs to continue to function at runtime when schema translate maps with different sets of keys are used each time. In addition, added detection of schema_translate_map dictionaries which gain or lose a ``None`` key across calls for the same statement, which affects compilation of the statement and is not compatible with caching; an exception is raised for these scenarios. .. change:: :tags: bug, mssql, sql :tickets: 9932 Fixed issue where performing :class:`.Cast` to a string type with an explicit collation would render the COLLATE clause inside the CAST function, which resulted in a syntax error. .. change:: :tags: usecase, mssql :tickets: 7340 Added support for creation and reflection of COLUMNSTORE indexes in MSSQL dialect. Can be specified on indexes specifying ``mssql_columnstore=True``. .. change:: :tags: usecase, postgresql :tickets: 10004 Added multi-host support for the asyncpg dialect. General improvements and error checking added to the PostgreSQL URL routines for the "multihost" use case added as well. Pull request courtesy Ilia Dmitriev. .. seealso:: :ref:`asyncpg_multihost` .. changelog:: ``` ### 2.0.17 ``` :released: June 23, 2023 .. change:: :tags: usecase, postgresql :tickets: 9965 The pg8000 dialect now supports RANGE and MULTIRANGE datatypes, using the existing RANGE API described at :ref:`postgresql_ranges`. Range and multirange types are supported in the pg8000 driver from version 1.29.8. Pull request courtesy Tony Locke. .. change:: :tags: bug, orm, regression :tickets: 9870 Fixed regression in the 2.0 series where a query that used :func:`.undefer_group` with :func:`_orm.selectinload` or :func:`_orm.subqueryload` would raise an ``AttributeError``. Pull request courtesy of Matthew Martin. .. change:: :tags: bug, orm :tickets: 9957 Fixed issue in ORM Annotated Declarative which prevented a :class:`_orm.declared_attr` from being used on a mixin which did not return a :class:`.Mapped` datatype, and instead returned a supplemental ORM datatype such as :class:`.AssociationProxy`. The Declarative runtime would erroneously try to interpret this annotation as needing to be :class:`.Mapped` and raise an error. .. change:: :tags: bug, orm, typing :tickets: 9957 Fixed typing issue where using the :class:`.AssociationProxy` return type from a :class:`_orm.declared_attr` function was disallowed. .. change:: :tags: bug, orm, regression :tickets: 9936 Fixed regression introduced in 2.0.16 by :ticket:`9879` where passing a callable to the :paramref:`_orm.mapped_column.default` parameter of :class:`_orm.mapped_column` while also setting ``init=False`` would interpret this value as a Dataclass default value which would be assigned directly to new instances of the object directly, bypassing the default generator taking place as the :paramref:`_schema.Column.default` value generator on the underlying :class:`_schema.Column`. This condition is now detected so that the previous behavior is maintained, however a deprecation warning for this ambiguous use is emitted; to populate the default generator for a :class:`_schema.Column`, the :paramref:`_orm.mapped_column.insert_default` parameter should be used, which disambiguates from the :paramref:`_orm.mapped_column.default` parameter whose name is fixed as per pep-681. .. change:: :tags: bug, orm :tickets: 9973 Additional hardening and documentation for the ORM :class:`_orm.Session` "state change" system, which detects concurrent use of :class:`_orm.Session` and :class:`_asyncio.AsyncSession` objects; an additional check is added within the process to acquire connections from the underlying engine, which is a critical section with regards to internal connection management. .. change:: :tags: bug, orm :tickets: 10006 Fixed issue in ORM loader strategy logic which further allows for long chains of :func:`_orm.contains_eager` loader options across complex inheriting polymorphic / aliased / of_type() relationship chains to take proper effect in queries. .. change:: :tags: bug, orm, declarative :tickets: 3532 A warning is emitted when an ORM :func:`_orm.relationship` and other :class:`.MapperProperty` objects are assigned to two different class attributes at once; only one of the attributes will be mapped. A warning for this condition was already in place for :class:`_schema.Column` and :class:`_orm.mapped_column` objects. .. change:: :tags: bug, orm :tickets: 9963 Fixed issue in support for the :class:`.Enum` datatype in the :paramref:`_orm.registry.type_annotation_map` first added as part of :ticket:`8859` where using a custom :class:`.Enum` with fixed configuration in the map would fail to transfer the :paramref:`.Enum.name` parameter, which among other issues would prevent PostgreSQL enums from working if the enum values were passed as individual values. Logic has been updated so that "name" is transferred over, but also that the default :class:`.Enum` which is against the plain Python `enum.Enum` class or other "empty" enum won't set a hardcoded name of ``"enum"`` either. .. change:: :tags: bug, typing :tickets: 9985 Fixed typing issue which prevented :class:`_orm.WriteOnlyMapped` and :class:`_orm.DynamicMapped` attributes from being used fully within ORM queries. .. changelog:: ``` ### 2.0.16 ``` :released: June 10, 2023 .. change:: :tags: usecase, postgresql, reflection :tickets: 9838 Cast ``NAME`` columns to ``TEXT`` when using ``ARRAY_AGG`` in PostgreSQL reflection. This seems to improve compatibility with some PostgreSQL derivatives that may not support aggregations on the ``NAME`` type. .. change:: :tags: bug, orm :tickets: 9862 Fixed issue where :class:`.DeclarativeBaseNoMeta` declarative base class would not function with non-mapped mixins or abstract classes, raising an ``AttributeError`` instead. .. change:: :tags: usecase, orm :tickets: 9828 Improved :meth:`.DeferredReflection.prepare` to accept arbitrary ``**kw`` arguments that are passed to :meth:`_schema.MetaData.reflect`, allowing use cases such as reflection of views as well as dialect-specific arguments to be passed. Additionally, modernized the :paramref:`.DeferredReflection.prepare.bind` argument so that either an :class:`.Engine` or :class:`.Connection` are accepted as the "bind" argument. .. change:: :tags: usecase, asyncio :tickets: 8215 Added new :paramref:`_asyncio.create_async_engine.async_creator` parameter to :func:`.create_async_engine`, which accomplishes the same purpose as the :paramref:`.create_engine.creator` parameter of :func:`.create_engine`. This is a no-argument callable that provides a new asyncio connection, using the asyncio database driver directly. The :func:`.create_async_engine` function will wrap the driver-level connection in the appropriate structures. Pull request curtesy of Jack Wotherspoon. .. change:: :tags: bug, orm, regression :tickets: 9820 Fixed regression in the 2.0 series where the default value of :paramref:`_orm.validates.include_backrefs` got changed to ``False`` for the :func:`_orm.validates` function. This default is now restored to ``True``. .. change:: :tags: bug, orm :tickets: 9917 Fixed bug in new feature which allows a WHERE clause to be used in conjunction with :ref:`orm_queryguide_bulk_update`, added in version 2.0.11 as part of :ticket:`9583`, where sending dictionaries that did not include the primary key values for each row would run through the bulk process and include "pk=NULL" for the rows, silently failing. An exception is now raised if primary key values for bulk UPDATE are not supplied. .. change:: :tags: bug, postgresql :tickets: 9836 Use proper precedence on PostgreSQL specific operators, such as ``>``. Previously the precedence was wrong, leading to wrong parenthesis when rendering against and ``ANY`` or ``ALL`` construct. .. change:: :tags: bug, orm, dataclasses :tickets: 9879 Fixed an issue where generating dataclasses fields that specified a ``default`` value and set ``init=False`` would not work. The dataclasses behavior in this case is to set the default value on the class, that's not compatible with the descriptors used by SQLAlchemy. To support this case the default is transformed to a ``default_factory`` when generating the dataclass. .. change:: :tags: bug, orm :tickets: 9841 A deprecation warning is emitted whenever a property is added to a :class:`_orm.Mapper` where an ORM mapped property were already configured, or an attribute is already present on the class. Previously, there was a non-deprecation warning for this case that did not emit consistently. The logic for this warning has been improved so that it detects end-user replacement of attribute while not having false positives for internal Declarative and other cases where replacement of descriptors with new ones is expected. .. change:: :tags: bug, postgresql :tickets: 9907 Fixed issue where the :paramref:`.ColumnOperators.like.escape` and similar parameters did not allow an empty string as an argument that would be passed through as the "escape" character; this is a supported syntax by PostgreSQL. Pull requset courtesy Martin Caslavsky. .. change:: :tags: bug, orm :tickets: 9869 Improved the argument chacking on the :paramref:`_orm.registry.map_imperatively.local_table` parameter of the :meth:`_orm.registry.map_imperatively` method, ensuring only a :class:`.Table` or other :class:`.FromClause` is passed, and not an existing mapped class, which would lead to undefined behavior as the object were further interpreted for a new mapping. .. change:: :tags: usecase, postgresql :tickets: 9041 Unified the custom PostgreSQL operator definitions, since they are shared among multiple different data types. .. change:: :tags: platform, usecase Compatibility improvements allowing the complete test suite to pass on Python 3.12.0b1. .. change:: :tags: bug, orm :tickets: 9913 The :attr:`_orm.InstanceState.unloaded_expirable` attribute is a synonym for :attr:`_orm.InstanceState.unloaded`, and is now deprecated; this attribute was always implementation-specific and should not have been public. .. change:: :tags: usecase, postgresql :tickets: 8240 Added support for PostgreSQL 10 ``NULLS NOT DISTINCT`` feature of unique indexes and unique constraint using the dialect option ``postgresql_nulls_not_distinct``. Updated the reflection logic to also correctly take this option into account. Pull request courtesy of Pavel Siarchenia. .. changelog:: ``` ### 2.0.15 ``` :released: May 19, 2023 .. change:: :tags: bug, orm :tickets: 9805 As more projects are using new-style "2.0" ORM querying, it's becoming apparent that the conditional nature of "autoflush", being based on whether or not the given statement refers to ORM entities, is becoming more of a key behavior. Up until now, the "ORM" flag for a statement has been loosely based around whether or not the statement returns rows that correspond to ORM entities or columns; the original purpose of the "ORM" flag was to enable ORM-entity fetching rules which apply post-processing to Core result sets as well as ORM loader strategies to the statement. For statements that don't build on rows that contain ORM entities, the "ORM" flag was considered to be mostly unnecessary. It still may be the case that "autoflush" would be better taking effect for *all* usage of :meth:`_orm.Session.execute` and related methods, even for purely Core SQL constructs. However, this still could impact legacy cases where this is not expected and may be more of a 2.1 thing. For now however, the rules for the "ORM-flag" have been opened up so that a statement that includes ORM entities or attributes anywhere within, including in the WHERE / ORDER BY / GROUP BY clause alone, within scalar subqueries, etc. will enable this flag. This will cause "autoflush" to occur for such statements and also be visible via the :attr:`_orm.ORMExecuteState.is_orm_statement` event-level attribute. .. change:: :tags: bug, postgresql, regression :tickets: 9808 Repaired the base :class:`.Uuid` datatype for the PostgreSQL dialect to make full use of the PG-specific ``UUID`` dialect-specific datatype when "native_uuid" is selected, so that PG driver behaviors are included. This issue became apparent due to the insertmanyvalues improvement made as part of :ticket:`9618`, where in a similar manner as that of :ticket:`9739`, the asyncpg driver is very sensitive to datatype casts being present or not, and the PostgreSQL driver-specific native ``UUID`` datatype must be invoked when this generic type is used so that these casts take place. .. changelog:: ``` ### 2.0.14 ``` :released: May 18, 2023 .. change:: :tags: bug, sql :tickets: 9772 Fixed issue in :func:`_sql.values` construct where an internal compilation error would occur if the construct were used inside of a scalar subquery. .. change:: :tags: usecase, sql :tickets: 9752 Generalized the MSSQL :func:`_sql.try_cast` function into the ``sqlalchemy.`` import namespace so that it may be implemented by third party dialects as well. Within SQLAlchemy, the :func:`_sql.try_cast` function remains a SQL Server-only construct that will raise :class:`.CompileError` if used with backends that don't support it. :func:`_sql.try_cast` implements a CAST where un-castable conversions are returned as NULL, instead of raising an error. Theoretically, the construct could be implemented by third party dialects for Google BigQuery, DuckDB, and Snowflake, and possibly others. Pull request courtesy Nick Crews. .. change:: :tags: bug, tests, pypy :tickets: 9789 Fixed test that relied on the ``sys.getsizeof()`` function to not run on pypy, where this function appears to have different behavior than it does on cpython. .. change:: :tags: bug, orm :tickets: 9777 Modified the ``JoinedLoader`` implementation to use a simpler approach in one particular area where it previously used a cached structure that would be shared among threads. The rationale is to avoid a potential race condition which is suspected of being the cause of a particular crash that's been reported multiple times. The cached structure in question is still ultimately "cached" via the compiled SQL cache, so a performance degradation is not anticipated. .. change:: :tags: bug, orm, regression :tickets: 9767 Fixed regression where use of :func:`_dml.update` or :func:`_dml.delete` within a :class:`_sql.CTE` construct, then used in a :func:`_sql.select`, would raise a :class:`.CompileError` as a result of ORM related rules for performing ORM-level update/delete statements. .. change:: :tags: bug, orm :tickets: 9766 Fixed issue in new ORM Annotated Declarative where using a :class:`_schema.ForeignKey` (or other column-level constraint) inside of :func:`_orm.mapped_column` which is then copied out to models via pep-593 ``Annotated`` would apply duplicates of each constraint to the :class:`_schema.Column` as produced in the target :class:`_schema.Table`, leading to incorrect CREATE TABLE DDL as well as migration directives under Alembic. .. change:: :tags: bug, orm :tickets: 9779 Fixed issue where using additional relationship criteria with the :func:`_orm.joinedload` loader option, where the additional criteria itself contained correlated subqueries that referred to the joined entities and therefore also required "adaption" to aliased entities, would be excluded from this adaption, producing the wrong ON clause for the joinedload. .. change:: :tags: bug, postgresql :tickets: 9773 Fixed apparently very old issue where the :paramref:`_postgresql.ENUM.create_type` parameter, when set to its non-default of ``False``, would not be propagated when the :class:`_schema.Column` which it's a part of were copied, as is common when using ORM Declarative mixins. .. changelog:: ``` ### 2.0.13 ``` :released: May 10, 2023 .. change:: :tags: usecase, asyncio :tickets: 9731 Added a new helper mixin :class:`_asyncio.AsyncAttrs` that seeks to improve the use of lazy-loader and other expired or deferred ORM attributes with asyncio, providing a simple attribute accessor that provides an ``await`` interface to any ORM attribute, whether or not it needs to emit SQL. .. seealso:: :class:`_asyncio.AsyncAttrs` .. change:: :tags: bug, orm :tickets: 9717 Fixed issue where ORM Annotated Declarative would not resolve forward references correctly in all cases; in particular, when using ``from __future__ import annotations`` in combination with Pydantic dataclasses. .. change:: :tags: typing, sql :tickets: 9656 Added type :data:`_sql.ColumnExpressionArgument` as a public-facing type that indicates column-oriented arguments which are passed to SQLAlchemy constructs, such as :meth:`_sql.Select.where`, :func:`_sql.and_` and others. This may be used to add typing to end-user functions which call these methods. .. change:: :tags: bug, orm :tickets: 9746 Fixed issue in new :ref:`orm_queryguide_upsert_returning` feature where the ``populate_existing`` execution option was not being propagated to the loading option, preventing existing attributes from being refreshed in-place. .. change:: :tags: bug, sql Fixed the base class for dialect-specific float/double types; Oracle :class:`_oracle.BINARY_DOUBLE` now subclasses :class:`_sqltypes.Double`, and internal types for :class:`_sqltypes.Float` for asyncpg and pg8000 now correctly subclass :class:`_sqltypes.Float`. .. change:: :tags: bug, ext :tickets: 9676 Fixed issue in :class:`_mutable.Mutable` where event registration for ORM mapped attributes would be called repeatedly for mapped inheritance subclasses, leading to duplicate events being invoked in inheritance hierarchies. .. change:: :tags: bug, orm :tickets: 9715 Fixed loader strategy pathing issues where eager loaders such as :func:`_orm.joinedload` / :func:`_orm.selectinload` would fail to traverse fully for many-levels deep following a load that had a :func:`_orm.with_polymorphic` or similar construct as an interim member. .. change:: :tags: usecase, sql :tickets: 9721 Implemented the "cartesian product warning" for UPDATE and DELETE statements, those which include multiple tables that are not correlated together in some way. .. change:: :tags: bug, sql Fixed issue where :func:`_dml.update` construct that included multiple tables and no VALUES clause would raise with an internal error. Current behavior for :class:`_dml.Update` with no values is to generate a SQL UPDATE statement with an empty "set" clause, so this has been made consistent for this specific sub-case. .. change:: :tags: oracle, reflection :tickets: 9597 Added reflection support in the Oracle dialect to expression based indexes and the ordering direction of index expressions. .. change:: :tags: performance, schema :tickets: 9597 Improved how table columns are added, avoiding unnecessary allocations, significantly speeding up the creation of many table, like when reflecting entire schemas. .. change:: :tags: bug, typing :tickets: 9762 Fixed typing for the :paramref:`_orm.Session.get.with_for_update` parameter of :meth:`_orm.Session.get` and :meth:`_orm.Session.refresh` (as well as corresponding methods on :class:`_asyncio.AsyncSession`) to accept boolean ``True`` and all other argument forms accepted by the parameter at runtime. .. change:: :tags: bug, postgresql, regression :tickets: 9739 Fixed another regression due to the "insertmanyvalues" change in 2.0.10 as part of :ticket:`9618`, in a similar way as regression :ticket:`9701`, where :class:`.LargeBinary` datatypes also need additional casts on when using the asyncpg driver specifically in order to work with the new bulk INSERT format. .. change:: :tags: bug, orm :tickets: 9630 Fixed issue in :func:`_orm.mapped_column` construct where the correct warning for "column X named directly multiple times" would not be emitted when ORM mapped attributes referred to the same :class:`_schema.Column`, if the :func:`_orm.mapped_column` construct were involved, raising an internal assertion instead. .. change:: :tags: bug, asyncio Fixed issue in semi-private ``await_only()`` and ``await_fallback()`` concurrency functions where the given awaitable would remain un-awaited if the function threw a ``GreenletError``, which could cause "was not awaited" warnings later on if the program continued. In this case, the given awaitable is now cancelled before the exception is thrown. .. changelog:: ``` ### 2.0.12 ``` :released: April 30, 2023 .. change:: :tags: bug, mysql, mariadb :tickets: 9722 Fixed issues regarding reflection of comments for :class:`_schema.Table` and :class:`_schema.Column` objects, where the comments contained control characters such as newlines. Additional testing support for these characters as well as extended Unicode characters in table and column comments (the latter of which aren't supported by MySQL/MariaDB) added to testing overall. .. changelog:: ``` ### 2.0.11 ``` :released: April 26, 2023 .. change:: :tags: bug, engine, regression :tickets: 9682 Fixed regression which prevented the :attr:`_engine.URL.normalized_query` attribute of :class:`_engine.URL` from functioning. .. change:: :tags: bug, postgresql, regression :tickets: 9701 Fixed critical regression caused by :ticket:`9618`, which modified the architecture of the :term:`insertmanyvalues` feature for 2.0.10, which caused floating point values to lose all decimal places when being inserted using the insertmanyvalues feature with either the psycopg2 or psycopg drivers. .. change:: :tags: bug, mssql Implemented the :class:`_sqltypes.Double` type for SQL Server, where it will render ``DOUBLE PRECISION`` at DDL time. This is implemented using a new MSSQL datatype :class:`_mssql.DOUBLE_PRECISION` which also may be used directly. .. change:: :tags: bug, oracle Fixed issue in Oracle dialects where ``Decimal`` returning types such as :class:`_sqltypes.Numeric` would return floating point values, rather than ``Decimal`` objects, when these columns were used in the :meth:`_dml.Insert.returning` clause to return INSERTed values. .. change:: :tags: bug, orm :tickets: 9583, 9595 Fixed 2.0 regression where use of :func:`_sql.bindparam()` inside of :meth:`_dml.Insert.values` would fail to be interpreted correctly when executing the :class:`_dml.Insert` statement using the ORM :class:`_orm.Session`, due to the new :ref:`ORM-enabled insert feature <orm_queryguide_bulk_insert>` not implementing this use case. .. change:: :tags: usecase, orm :tickets: 9583, 9595 The :ref:`ORM bulk INSERT and UPDATE <orm_expression_update_delete>` features now add these capabilities: * The requirement that extra parameters aren't passed when using ORM INSERT using the "orm" dml_strategy setting is lifted. * The requirement that additional WHERE criteria is not passed when using ORM UPDATE using the "bulk" dml_strategy setting is lifted. Note that in this case, the check for expected row count is turned off. .. change:: :tags: usecase, sql :tickets: 8285 Added support for slice access with :class:`.ColumnCollection`, e.g. ``table.c[0:5]``, ``subquery.c[:-1]`` etc. Slice access returns a sub :class:`.ColumnCollection` in the same way as passing a tuple of keys. This is a natural continuation of the key-tuple access added for :ticket:`8285`, where it appears to be an oversight that the slice access use case was omitted. .. change:: :tags: bug, typing :tickets: 9644 Improved typing of :class:`_engine.RowMapping` to indicate that it support also :class:`_schema.Column` as index objects, not only string names. Pull request courtesy Andy Freeland. .. change:: :tags: engine, performance :tickets: 9678, 9680 A series of performance enhancements to :class:`_engine.Row`: * ``__getattr__`` performance of the row's "named tuple" interface has been improved; within this change, the :class:`_engine.Row` implementation has been streamlined, removing constructs and logic that were specific to the 1.4 and prior series of SQLAlchemy. As part of this change, the serialization format of :class:`_engine.Row` has been modified slightly, however rows which were pickled with previous SQLAlchemy 2.0 releases will be recognized within the new format. Pull request courtesy J. Nick Koston. * Improved row processing performance for "binary" datatypes by making the "bytes" handler conditional on a per driver basis. As a result, the "bytes" result handler has been removed for nearly all drivers other than psycopg2, all of which in modern forms support returning Python "bytes" directly. Pull request courtesy J. Nick Koston. * Additional refactorings inside of :class:`_engine.Row` to improve performance by Federico Caselli. .. changelog:: ``` ### 2.0.10 ``` :released: April 21, 2023 .. change:: :tags: bug, typing :tickets: 9650 Added typing information for recently added operators :meth:`.ColumnOperators.icontains`, :meth:`.ColumnOperators.istartswith`, :meth:`.ColumnOperators.iendswith`, and bitwise operators :meth:`.ColumnOperators.bitwise_and`, :meth:`.ColumnOperators.bitwise_or`, :meth:`.ColumnOperators.bitwise_xor`, :meth:`.ColumnOperators.bitwise_not`, :meth:`.ColumnOperators.bitwise_lshift` :meth:`.ColumnOperators.bitwise_rshift`. Pull request courtesy Martijn Pieters. .. change:: :tags: bug, oracle Fixed issue where the :class:`_sqltypes.Uuid` datatype could not be used in an INSERT..RETURNING clause with the Oracle dialect. .. change:: :tags: usecase, engine :tickets: 9613 Added :func:`_sa.create_pool_from_url` and :func:`_asyncio.create_async_pool_from_url` to create a :class:`_pool.Pool` instance from an input url passed as string or :class:`_sa.URL`. .. change:: :tags: bug, engine :tickets: 9618, 9603 Repaired a major shortcoming which was identified in the :ref:`engine_insertmanyvalues` performance optimization feature first introduced in the 2.0 series. This was a continuation of the change in 2.0.9 which disabled the SQL Server version of the feature due to a reliance in the ORM on apparent row ordering that is not guaranteed to take place. The fix applies new logic to all "insertmanyvalues" operations, which takes effect when a new parameter :paramref:`_dml.Insert.returning.sort_by_parameter_order` on the :meth:`_dml.Insert.returning` or :meth:`_dml.UpdateBase.return_defaults` methods, that through a combination of alternate SQL forms, direct correspondence of client side parameters, and in some cases downgrading to running row-at-a-time, will apply sorting to each batch of returned rows using correspondence to primary key or other unique values in each row which can be correlated to the input data. Performance impact is expected to be minimal as nearly all common primary key scenarios are suitable for parameter-ordered batching to be achieved for all backends other than SQLite, while "row-at-a-time" mode operates with a bare minimum of Python overhead compared to the very heavyweight approaches used in the 1.x series. For SQLite, there is no difference in performance when "row-at-a-time" mode is used. It's anticipated that with an efficient "row-at-a-time" INSERT with RETURNING batching capability, the "insertmanyvalues" feature can be later be more easily generalized to third party backends that include RETURNING support but not necessarily easy ways to guarantee a correspondence with parameter order. .. seealso:: :ref:`engine_insertmanyvalues_returning_order` .. change:: :tags: bug, mssql :tickets: 9618, 9603 Restored the :term:`insertmanyvalues` feature for Microsoft SQL Server. This feature was disabled in version 2.0.9 due to an apparent reliance on the ordering of RETURNING that is not guaranteed. The architecture of the "insertmanyvalues" feature has been reworked to accommodate for specific organizations of INSERT statements and result row handling that can guarantee the correspondence of returned rows to input records. .. seealso:: :ref:`engine_insertmanyvalues_returning_order` .. change:: :tags: usecase, postgresql :tickets: 9608 Added ``prepared_statement_name_func`` connection argument option in the asyncpg dialect. This option allows passing a callable used to customize the name of the prepared statement that will be created by the driver when executing queries. Pull request courtesy Pavel Sirotkin. .. seealso:: :ref:`asyncpg_prepared_statement_name` .. change:: :tags: typing, bug Updates to the codebase to pass typing with Mypy 1.2.0. .. change:: :tags: bug, typing :tickets: 9669 Fixed typing issue where :meth:`_orm.PropComparator.and_` expressions would not be correctly typed inside of loader options such as :func:`_orm.selectinload`. .. change:: :tags: bug, orm :tickets: 9625 Fixed issue where the :meth:`_orm.declared_attr.directive` modifier was not correctly honored for subclasses when applied to the ``__mapper_args__`` special method name, as opposed to direct use of :class:`_orm.declared_attr`. The two constructs should have identical runtime behaviors. .. change:: :tags: bug, postgresql :tickets: 9611 Restored the :paramref:`_postgresql.ENUM.name` parameter as optional in the signature for :class:`_postgresql.ENUM`, as this is chosen automatically from a given pep-435 ``Enum`` type. .. change:: :tags: bug, postgresql :tickets: 9621 Fixed issue where the comparison for :class:`_postgresql.ENUM` against a plain string would cast that right-hand side type as VARCHAR, which due to more explicit casting added to dialects such as asyncpg would produce a PostgreSQL type mismatch error. .. change:: :tags: bug, orm :tickets: 9635 Made an improvement to the :func:`_orm.with_loader_criteria` loader option to allow it to be indicated in the :meth:`.Executable.options` method of a top-level statement that is not itself an ORM statement. Examples include :func:`_sql.select` that's embedded in compound statements such as :func:`_sql.union`, within an :meth:`_dml.Insert.from_select` construct, as well as within CTE expressions that are not ORM related at the top level. .. change:: :tags: bug, orm :tickets: 9685 Fixed bug in ORM bulk insert feature where additional unnecessary columns would be rendered in the INSERT statement if RETURNING of individual columns were requested. .. change:: :tags: bug, postgresql :tickets: 9615 Fixed issue that prevented reflection of expression based indexes with long expressions in PostgreSQL. The expression where erroneously truncated to the identifier length (that's 63 bytes by default). .. change:: :tags: usecase, postgresql :tickets: 9509 Add missing :meth:`_postgresql.Range.intersection` method. Pull request courtesy Yurii Karabas. .. change:: :tags: bug, orm :tickets: 9628 Fixed bug in ORM Declarative Dataclasses where the :func:`_orm.query_expression` and :func:`_orm.column_property` constructs, which are documented as read-only constructs in the context of a Declarative mapping, could not be used with a :class:`_orm.MappedAsDataclass` class without adding ``init=False``, which in the case of :func:`_orm.query_expression` was not possible as no ``init`` parameter was included. These constructs have been modified from a dataclass perspective to be assumed to be "read only", setting ``init=False`` by default and no longer including them in the pep-681 constructor. The dataclass parameters for :func:`_orm.column_property` ``init``, ``default``, ``default_factory``, ``kw_only`` are now deprecated; these fields don't apply to :func:`_orm.column_property` as used in a Declarative dataclasses configuration where the construct would be read-only. Also added read-specific parameter :paramref:`_orm.query_expression.compare` to :func:`_orm.query_expression`; :paramref:`_orm.query_expression.repr` was already present. .. change:: :tags: bug, orm Added missing :paramref:`_orm.mapped_column.active_history` parameter to :func:`_orm.mapped_column` construct. .. changelog:: ``` ### 2.0.9 ``` :released: April 5, 2023 .. change:: :tags: bug, mssql :tickets: 9603 The SQLAlchemy "insertmanyvalues" feature which allows fast INSERT of many rows while also supporting RETURNING is temporarily disabled for SQL Server. As the unit of work currently relies upon this feature such that it matches existing ORM objects to returned primary key identities, this particular use pattern does not work with SQL Server in all cases as the order of rows returned by "OUTPUT inserted" may not always match the order in which the tuples were sent, leading to the ORM making the wrong decisions about these objects in subsequent operations. The feature will be re-enabled in an upcoming release and will again take effect for multi-row INSERT statements, however the unit-of-work's use of the feature will be disabled, possibly for all dialects, unless ORM-mapped tables also include a "sentinel" column so that the returned rows can be referenced back to the original data passed in. .. change:: :tags: bug, mariadb :tickets: 9588 Added ``row_number`` as reserved word in MariaDb. .. change:: :tags: bug, mssql :tickets: 9586 Changed the bulk INSERT strategy used for SQL Server "executemany" with pyodbc when ``fast_executemany`` is set to ``True`` by using ``fast_executemany`` / ``cursor.executemany()`` for bulk INSERT that does not include RETURNING, restoring the same behavior as was used in SQLAlchemy 1.4 when this parameter is set. New performance details from end users have shown that ``fast_executemany`` is still much faster for very large datasets as it uses ODBC commands that can receive all rows in a single round trip, allowing for much larger datasizes than the batches that can be sent by "insertmanyvalues" as was implemented for SQL Server. While this change was made such that "insertmanyvalues" continued to be used for INSERT that includes RETURNING, as well as if ``fast_executemany`` were not set, due to :ticket:`9603`, the "insertmanyvalues" strategy has been disabled for SQL Server across the board in any case. .. changelog:: ``` ### 2.0.8 ``` :released: March 31, 2023 .. change:: :tags: bug, orm :tickets: 9553 Fixed issue in ORM Annotated Declarative where using a recursive type (e.g. using a nested Dict type) would result in a recursion overflow in the ORM's annotation resolution logic, even if this datatype were not necessary to map the column. .. change:: :tags: bug, examples Fixed issue in "versioned history" example where using a declarative base that is derived from :class:`_orm.DeclarativeBase` would fail to be mapped. Additionally, repaired the given test suite so that the documented instructions for running the example using Python unittest now work again. .. change:: :tags: bug, orm :tickets: 9550 Fixed issue where the :func:`_orm.mapped_column` construct would raise an internal error if used on a Declarative mixin and included the :paramref:`_orm.mapped_column.deferred` parameter. .. change:: :tags: bug, mysql :tickets: 9544 Fixed issue where string datatypes such as :class:`_sqltypes.CHAR`, :class:`_sqltypes.VARCHAR`, :class:`_sqltypes.TEXT`, as