:released: October 19, 2021
.. change::
:tags: orm
:tickets: 6284
Passing a :class:`.Query` object to :meth:`_orm.Session.execute` is not
the intended use of this object, and will now raise a deprecation warning.
.. change::
:tags: bug, postgresql
:tickets: 5387
Added a "disconnect" condition for the "SSL SYSCALL error: Bad address"
error message as reported by psycopg2. Pull request courtesy Zeke Brechtel.
.. change::
:tags: bug, orm
Improved the exception message generated when configuring a mapping with
joined table inheritance where the two tables either have no foreign key
relationships set up, or where they have multiple foreign key relationships
set up. The message is now ORM specific and includes context that the
:paramref:`_orm.Mapper.inherit_condition` parameter may be needed
particularly for the ambiguous foreign keys case.
.. change::
:tags: bug, sql
:tickets: 6520
Fixed issue where SQL queries using the
:meth:`_functions.FunctionElement.within_group` construct could not be
pickled, typically when using the ``sqlalchemy.ext.serializer`` extension
but also for general generic pickling.
.. change::
:tags: bug, orm
:tickets: 7189
Fixed issue with :func:`_orm.with_loader_criteria` feature where ON
criteria would not be added to a JOIN for a query of the form
``select(A).join(B)``, stating a target while making use of an implicit
ON clause.
.. change::
:tags: bug, orm
:tickets: 7205
Fixed bug where the ORM "plugin", necessary for features such as
:func:`_orm.with_loader_criteria` to work correctly, would not be applied
to a :func:`_sql.select` which queried from an ORM column expression if it
made use of the :meth:`_sql.ColumnElement.label` modifier.
.. change::
:tags: bug, mypy
:tickets: 6435
Fixed issue in mypy plugin to improve upon some issues detecting ``Enum()``
SQL types containing custom Python enumeration classes. Pull request
courtesy Hiroshi Ogawa.
.. change::
:tags: bug, mysql
:tickets: 7144
Fixed issue in MySQL :func:`_mysql.match` construct where passing a clause
expression such as :func:`_sql.bindparam` or other SQL expression for the
"against" parameter would fail. Pull request courtesy Anton Kovalevich.
.. change::
:tags: bug, mssql
:tickets: 7160
Fixed issue with :meth:`.Inspector.get_foreign_keys` where foreign
keys were omitted if they were established against a unique
index instead of a unique constraint.
.. change::
:tags: usecase, mssql
Added reflection support for SQL Server foreign key options, including
"ON UPDATE" and "ON DELETE" values of "CASCADE" and "SET NULL".
.. change::
:tags: bug, sql
:tickets: 4123
Repaired issue in new :paramref:`_sql.HasCTE.cte.nesting` parameter
introduced with :ticket:`4123` where a recursive :class:`_sql.CTE` using
:paramref:`_sql.HasCTE.cte.recursive` in typical conjunction with UNION
would not compile correctly. Additionally makes some adjustments so that
the :class:`_sql.CTE` construct creates a correct cache key.
Pull request courtesy Eric Masseran.
.. change::
:tags: bug, engine
:tickets: 7130
Fixed issue where the deprecation warning for the :class:`.URL` constructor
which indicates that the :meth:`.URL.create` method should be used would
not emit if a full positional argument list of seven arguments were passed;
additionally, validation of URL arguments will now occur if the constructor
is called in this way, which was being skipped previously.
.. change::
:tags: bug, orm
:tickets: 7103
Add missing methods added in :ticket:`6991` to
:class:`_scoping.scoped_session` and :func:`_asyncio.async_scoped_session`.
.. change::
:tags: bug, examples
:tickets: 7169
Repaired the examples in examples/versioned_rows to use SQLAlchemy 1.4 APIs
correctly; these examples had been missed when API changes like removing
"passive" from :meth:`_orm.Session.is_modified` were made as well as the
:meth:`_ormevents.SessionEvents.do_orm_execute()` event hook were added.
.. change::
:tags: bug, orm
:tickets: 6974, 6972
An extra layer of warning messages has been added to the functionality
of :meth:`_orm.Query.join` and the ORM version of
:meth:`_sql.Select.join`, where a few places where "automatic aliasing"
continues to occur will now be called out as a pattern to avoid, mostly
specific to the area of joined table inheritance where classes that share
common base tables are being joined together without using explicit aliases.
One case emits a legacy warning for a pattern that's not recommended,
the other case is fully deprecated.
The automatic aliasing within ORM join() which occurs for overlapping
mapped tables does not work consistently with all APIs such as
:func:`_orm.contains_eager()`, and rather than continue to try to make
these use cases work everywhere, replacing with a more user-explicit
pattern is clearer, less prone to bugs and simplifies SQLAlchemy's
internals further.
The warnings include links to the errors.rst page where each pattern is
demonstrated along with the recommended pattern to fix.
.. seealso::
:ref:`error_xaj1`
:ref:`error_xaj2`
.. change::
:tags: bug, sql
:tickets: 7061
Account for the :paramref:`_sql.table.schema` parameter passed to
the :func:`_sql.table` construct, such that it is taken into account
when accessing the :attr:`_sql.TableClause.fullname` attribute.
.. change::
:tags: bug, sql
:tickets: 7140
Fixed an inconsistency in the :meth:`_sql.ColumnOperators.any_` /
:meth:`_sql.ColumnOperators.all_` functions / methods where the special
behavior these functions have of "flipping" the expression such that the
"ANY" / "ALL" expression is always on the right side would not function if
the comparison were against the None value, that is, "column.any_() ==
None" should produce the same SQL expression as "null() == column.any_()".
Added more docs to clarify this as well, plus mentions that any_() / all_()
generally supersede the ARRAY version "any()" / "all()".
.. change::
:tags: engine, bug, postgresql
:tickets: 3247
The :meth:`_reflection.Inspector.reflect_table` method now supports
reflecting tables that do not have user defined columns. This allows
:meth:`_schema.MetaData.reflect` to properly complete reflection on
databases that contain such tables. Currently, only PostgreSQL is known to
support such a construct among the common database backends.
.. change::
:tags: sql, bug, regression
:tickets: 7177
Fixed issue where "expanding IN" would fail to function correctly with
datatypes that use the :meth:`_types.TypeEngine.bind_expression` method,
where the method would need to be applied to each element of the
IN expression rather than the overall IN expression itself.
.. change::
:tags: postgresql, bug, regression
:tickets: 7177
Fixed issue where IN expressions against a series of array elements, as can
be done with PostgreSQL, would fail to function correctly due to multiple
issues within the "expanding IN" feature of SQLAlchemy Core that was
standardized in version 1.4. The psycopg2 dialect now makes use of the
:meth:`_types.TypeEngine.bind_expression` method with :class:`_types.ARRAY`
to portably apply the correct casts to elements. The asyncpg dialect was
not affected by this issue as it applies bind-level casts at the driver
level rather than at the compiler level.
.. change::
:tags: bug, mysql
:tickets: 7204
Fixed installation issue where the ``sqlalchemy.dialects.mysql`` module
would not be importable if "greenlet" were not installed.
.. change::
:tags: bug, mssql
:tickets: 7168
Fixed issue with :meth:`.Inspector.has_table` where it would return False
if a local temp table with the same name from a different session happened
to be returned first when querying tempdb. This is a continuation of
:ticket:`6910` which accounted for the temp table existing only in the
alternate session and not the current one.
.. change::
:tags: bug, orm
:tickets: 7128
Fixed bug where iterating a :class:`_result.Result` from a :class:`_orm.Session`
after that :class:`_orm.Session` were closed would partially attach objects
to that session in an essentially invalid state. It now raises an exception
with a link to new documentation if an **un-buffered** result is iterated
from a :class:`_orm.Session` that was closed or otherwise had the
:meth:`_orm.Session.expunge_all` method called after that :class:`_result.Result`
was generated. The ``prebuffer_rows`` execution option, as is used
automatically by the asyncio extension for client-side result sets, may be
used to produce a :class:`_result.Result` where the ORM objects are prebuffered,
and in this case iterating the result will produce a series of detached
objects.
.. seealso::
:ref:`error_lkrp`
.. change::
:tags: bug, mssql, regression
:tickets: 7129
Fixed bug in SQL Server :class:`_mssql.DATETIMEOFFSET` datatype where the
ODBC implementation would not generate the correct DDL, for cases where the
type were converted using the ``dialect.type_descriptor()`` method, the
usage of which is illustrated in some documented examples for
:class:`.TypeDecorator`, though not necessary for most datatypes.
Regression was introduced by :ticket:`6366`. As part of this change, the
full list of SQL Server date types have been amended to return a "dialect
impl" that generates the same DDL name as the supertype.
.. change::
:tags: bug, sql
:tickets: 7153
Adjusted the "column disambiguation" logic that's new in 1.4, where the
same expression repeated gets an "extra anonymous" label, so that the logic
more aggressively deduplicates those labels when the repeated element
is the same Python expression object each time, as occurs in cases like
when using "singleton" values like :func:`_sql.null`. This is based on
the observation that at least some databases (e.g. MySQL, but not SQLite)
will raise an error if the same label is repeated inside of a subquery.
.. change::
:tags: bug, orm
:tickets: 7154
Related to :ticket:`7153`, fixed an issue where result column lookups would
fail for "adapted" SELECT statements that selected for "constant" value
expressions most typically the NULL expression, as would occur in such
places as joined eager loading in conjunction with limit/offset. This was
overall a regression due to issue :ticket:`6259` which removed all
"adaption" for constants like NULL, "true", and "false" when rewriting
expressions in a SQL statement, but this broke the case where the same
adaption logic were used to resolve the constant to a labeled expression
for the purposes of result set targeting.
.. change::
:tags: bug, orm, regression
:tickets: 7134
Fixed regression where ORM loaded objects could not be pickled in cases
where loader options making use of ``"*"`` were used in certain
combinations, such as combining the :func:`_orm.joinedload` loader strategy
with ``raiseload('*')`` of sub-elements.
.. change::
:tags: bug, engine
:tickets: 7077
Implemented proper ``__reduce__()`` methods for all SQLAlchemy exception
objects to ensure they all support clean round trips when pickling, as
exception objects are often serialized for the purposes of various
debugging tools.
.. change::
:tags: bug, orm, regression
:tickets: 7209
Fixed regression where the use of a :class:`_hybrid.hybrid_property`
attribute or a mapped :func:`_orm.composite` attribute as a key passed to
the :meth:`_dml.Update.values` method for an ORM-enabled
:class:`_dml.Update` statement, as well as when using it via the legacy
:meth:`_orm.Query.update` method, would be processed for incoming
ORM/hybrid/composite values within the compilation stage of the UPDATE
statement, which meant that in those cases where caching occurred,
subsequent invocations of the same statement would no longer receive the
correct values. This would include not only hybrids that use the
:meth:`_hybrid.hybrid_property.update_expression` method, but any use of a
plain hybrid attribute as well. For composites, the issue instead caused a
non-repeatable cache key to be generated, which would break caching and
could fill up the statement cache with repeated statements.
The :class:`_dml.Update` construct now handles the processing of key/value
pairs passed to :meth:`_dml.Update.values` and
:meth:`_dml.Update.ordered_values` up front when the construct is first
generated, before the cache key has been generated so that the key/value
pairs are processed each time, and so that the cache key is generated
against the individual column/value pairs that will ultimately be
used in the statement.
.. changelog::