SqlAlchemy 2.0 中文文档(五十九)(5)https://developer.aliyun.com/article/1563151
1.4.6
Released: April 6, 2021
orm
- [orm] [bug] [regression]
Fixed regression where a deprecated form ofQuery.join()
were used, passing a series of entities to join from without any ON clause in a singleQuery.join()
call, would fail to function correctly.
References: #6203 - [orm] [bug] [regression]
Fixed critical regression where theQuery.yield_per()
method in the ORM would set up the internalResult
to yield chunks at a time, however made use of the newResult.unique()
method which uniques across the entire result. This would lead to lost rows since the ORM is usingid(obj)
as the uniquing function, which leads to repeated identifiers for new objects as already-seen objects are garbage collected. 1.3’s behavior here was to “unique” across each chunk, which does not actually produce “uniqued” results when results are yielded in chunks. As theQuery.yield_per()
method is already explicitly disallowed when joined eager loading is in place, which is the primary rationale for the “uniquing” feature, the “uniquing” feature is now turned off entirely whenQuery.yield_per()
is used.
This regression only applies to the legacyQuery
object; when using 2.0 style execution, “uniquing” is not automatically applied. To prevent the issue from arising from explicit use ofResult.unique()
, an error is now raised if rows are fetched from a “uniqued” ORM-levelResult
if any yield per API is also in use, as the purpose ofyield_per
is to allow for arbitrarily large numbers of rows, which cannot be uniqued in memory without growing the number of entries to fit the complete result size.
References: #6206
sql
- [sql] [bug] [mssql] [oracle] [regression]
Fixed further regressions in the same area as that of #6173 released in 1.4.5, where a “postcompile” parameter, again most typically those used for LIMIT/OFFSET rendering in Oracle and SQL Server, would fail to be processed correctly if the same parameter rendered in multiple places in the statement.
References: #6202 - [sql] [bug]
Executing aSubquery
usingConnection.execute()
is deprecated and will emit a deprecation warning; this use case was an oversight that should have been removed from 1.4. The operation will now execute the underlyingSelect
object directly for backwards compatibility. Similarly, theCTE
class is also not appropriate for execution. In 1.3, attempting to execute a CTE would result in an invalid “blank” SQL statement being executed; since this use case was not working it now raisesObjectNotExecutableError
. Previously, 1.4 was attempting to execute the CTE as a statement however it was working only erratically.
References: #6204
schema
- [schema] [bug]
TheTable
object now raises an informative error message if it is instantiated without passing at least theTable.name
andTable.metadata
arguments positionally. Previously, if these were passed as keyword arguments, the object would silently fail to initialize correctly.
This change is also backported to: 1.3.25
References: #6135
mypy
- [mypy] [bug]
Applied a series of refactorings and fixes to accommodate for Mypy “incremental” mode across multiple files, which previously was not taken into account. In this mode the Mypy plugin has to accommodate Python datatypes expressed in other files coming in with less information than they have on a direct run.
Additionally, a new decoratordeclarative_mixin()
is added, which is necessary for the Mypy plugin to be able to definifitely identify a Declarative mixin class that is otherwise not used inside a particular Python file.
See also
Using @declared_attr and Declarative Mixins
References: #6147 - [mypy] [bug]
Fixed issue where the Mypy plugin would fail to interpret the “collection_class” of a relationship if it were a callable and not a class. Also improved type matching and error reporting for collection-oriented relationships.
References: #6205
asyncio
- [asyncio] [usecase] [postgresql]
Added accessors.sqlstate
and synonym.pgcode
to the.orig
attribute of the SQLAlchemy exception class raised by the asyncpg DBAPI adapter, that is, the intermediary exception object that wraps on top of that raised by the asyncpg library itself, but below the level of the SQLAlchemy dialect.
References: #6199
1.4.5
Released: April 2, 2021
orm
- [orm] [bug] [regression]
Fixed regression where thejoinedload()
loader strategy would not successfully joinedload to a mapper that is mapper against aCTE
construct.
References: #6172 - [orm] [bug] [regression]
Scaled back the warning message added in #5171 to not warn for overlapping columns in an inheritance scenario where a particular relationship is local to a subclass and therefore does not represent an overlap.
References: #6171
sql
- [sql] [bug] [postgresql]
Fixed bug in newFunctionElement.render_derived()
feature where column names rendered out explicitly in the alias SQL would not have proper quoting applied for case sensitive names and other non-alphanumeric names.
References: #6183 - [sql] [bug] [regression]
Fixed regression where use of theOperators.in_()
method with aSelect
object against a non-table-bound column would produce anAttributeError
, or more generally using aScalarSelect
that has no datatype in a binary expression would produce invalid state.
References: #6181 - [sql] [bug]
Added a new flag to theDialect
class calledDialect.supports_statement_cache
. This flag now needs to be present directly on a dialect class in order for SQLAlchemy’s query cache to take effect for that dialect. The rationale is based on discovered issues such as #6173 revealing that dialects which hardcode literal values from the compiled statement, often the numerical parameters used for LIMIT / OFFSET, will not be compatible with caching until these dialects are revised to use the parameters present in the statement only. For third party dialects where this flag is not applied, the SQL logging will show the message “dialect does not support caching”, indicating the dialect should seek to apply this flag once they have verified that no per-statement literal values are being rendered within the compilation phase.
See also
Caching for Third Party Dialects
References: #6184
schema
- [schema] [bug]
Introduce a new parameterEnum.omit_aliases
inEnum
type allow filtering aliases when using a pep435 Enum. Previous versions of SQLAlchemy kept aliases in all cases, creating database enum type with additional states, meaning that they were treated as different values in the db. For backward compatibility this flag defaults toFalse
in the 1.4 series, but will be switched toTrue
in a future version. A deprecation warning is raise if this flag is not specified and the passed enum contains aliases.
References: #6146
mypy
- [mypy] [bug]
Fixed issue in mypy plugin where newly added support foras_declarative()
needed to more fully add theDeclarativeMeta
class to the mypy interpreter’s state so that it does not result in a name not found error; additionally improves how global names are setup for the plugin including theMapped
name.
References: #sqlalchemy/sqlalchemy2-stubs/#14
asyncio
- [asyncio] [bug]
Fixed issue where the asyncio extension could not be loaded if running Python 3.6 with the backport library ofcontextvars
installed.
References: #6166
postgresql
- [postgresql] [bug] [regression]
Fixed regression caused by #6023 where the PostgreSQL cast operator applied to elements within anARRAY
when using psycopg2 would fail to use the correct type in the case that the datatype were also embedded within an instance of theVariant
adapter.
Additionally, repairs support for the correct CREATE TYPE to be emitted when using aVariant(ARRAY(some_schema_type))
.
This change is also backported to: 1.3.25
References: #6182 - [postgresql] [bug]
Fixed typo in the fix for #6099 released in 1.4.4 that completely prevented this change from working correctly, i.e. the error message did not match what was actually emitted by pg8000.
References: #6099 - [postgresql] [bug]
Fixed issue where the PostgreSQLPGInspector
, when generated against anEngine
, would fail for.get_enums()
,.get_view_names()
,.get_foreign_table_names()
and.get_table_oid()
when used against a “future” style engine and not the connection directly.
References: #6170
mysql
- [mysql] [bug] [regression]
Fixed regression in the MySQL dialect where the reflection query used to detect if a table exists would fail on very old MySQL 5.0 and 5.1 versions.
References: #6163
mssql
- [mssql] [bug]
Fixed a regression in MSSQL 2012+ that prevented the order by clause to be rendered whenoffset=0
is used in a subquery.
References: #6163
oracle
- [oracle] [bug] [regression]
Fixed critical regression where the Oracle compiler would not maintain the correct parameter values in the LIMIT/OFFSET for a select due to a caching issue.
References: #6173
1.4.4
Released: March 30, 2021
orm
- [orm] [bug]
Fixed critical issue in the newPropComparator.and_()
feature where loader strategies that emit secondary SELECT statements such asselectinload()
andlazyload()
would fail to accommodate for bound parameters in the user-defined criteria in terms of the current statement being executed, as opposed to the cached statement, causing stale bound values to be used.
This also adds a warning for the case where an object that useslazyload()
in conjunction withPropComparator.and_()
is attempted to be serialized; the loader criteria cannot reliably be serialized and deserialized and eager loading should be used for this case.
References: #6139 - [orm] [bug] [regression]
Fixed missing methodSession.get()
from theScopedSession
interface.
References: #6144
engine
- [engine] [usecase]
Modified the context manager used byTransaction
so that an “already detached” warning is not emitted by the ending of the context manager itself, if the transaction were already manually rolled back inside the block. This applies to regular transactions, savepoint transactions, and legacy “marker” transactions. A warning is still emitted if the.rollback()
method is called explicitly more than once.
References: #6155 - [engine] [bug]
Repair wrong arguments to exception handling method in CursorResult.
References: #6138
postgresql
- [postgresql] [bug] [reflection]
Fixed issue in PostgreSQL reflection where a column expressing “NOT NULL” will supersede the nullability of a corresponding domain.
This change is also backported to: 1.3.24
References: #6161 - [postgresql] [bug]
Modified theis_disconnect()
handler for the pg8000 dialect, which now accommodates for a newInterfaceError
emitted by pg8000 1.19.0. Pull request courtesy Hamdi Burak Usul.
References: #6099
misc
- [misc] [bug]
Adjusted the usage of theimportlib_metadata
library for loading setuptools entrypoints in order to accommodate for some deprecation changes.
1.4.3
Released: March 25, 2021
orm
- [orm] [bug]
Fixed a bug where python 2.7.5 (default on CentOS 7) wasn’t able to import sqlalchemy, because on this version of Pythonexec "statement"
andexec("statement")
do not behave the same way. The compatibilityexec_()
function was used instead.
References: #6069 - [orm] [bug]
Fixed bug where ORM queries using a correlated subquery in conjunction withcolumn_property()
would fail to correlate correctly to an enclosing subquery or to a CTE whenSelect.correlate_except()
were used in the property to control correlation, in cases where the subquery contained the same selectables as ones within the correlated subquery that were intended to not be correlated.
References: #6060 - [orm] [bug]
Fixed bug where combinations of the new “relationship with criteria” feature could fail in conjunction with features that make use of the new “lambda SQL” feature, including loader strategies such as selectinload and lazyload, for more complicated scenarios such as polymorphic loading.
References: #6131 - [orm] [bug]
Repaired support so that theClauseElement.params()
method can work correctly with aSelect
object that includes joins across ORM relationship structures, which is a new feature in 1.4.
References: #6124 - [orm] [bug]
Fixed issue where a “removed in 2.0” warning were generated internally by the relationship loader mechanics.
References: #6115
orm declarative
- [orm] [declarative] [bug] [regression]
Fixed regression where the.metadata
attribute on a per class level would not be honored, breaking the use case of per-class-hierarchyMetaData
for abstract declarative classes and mixins.
See also
metadata
References: #6128
engine
- [engine] [bug] [regression]
Restored theResultProxy
name back to thesqlalchemy.engine
namespace. This name refers to theLegacyCursorResult
object.
References: #6119
schema
- [schema] [bug]
Adjusted the logic that emits DROP statements forSequence
objects among the dropping of multiple tables, such that allSequence
objects are dropped after all tables, even if the givenSequence
is related only to aTable
object and not directly to the overallMetaData
object. The use case supports the sameSequence
being associated with more than oneTable
at a time.
This change is also backported to: 1.3.24
References: #6071
mypy
- [mypy] [bug]
Added support for the Mypy extension to correctly interpret a declarative base class that’s generated using theas_declarative()
function as well as theregistry.as_declarative_base()
method. - [mypy] [bug]
Fixed bug in Mypy plugin where the Python type detection for theBoolean
column type would produce an exception; additionally implemented support forEnum
, including detection of a string-based enum vs. use of Pythonenum.Enum
.
References: #6109
postgresql
- [postgresql] [bug] [types]
Adjusted the psycopg2 dialect to emit an explicit PostgreSQL-style cast for bound parameters that contain ARRAY elements. This allows the full range of datatypes to function correctly within arrays. The asyncpg dialect already generated these internal casts in the final statement. This also includes support for array slice updates as well as the PostgreSQL-specificARRAY.contains()
method.
This change is also backported to: 1.3.24
References: #6023 - [postgresql] [bug] [reflection]
Fixed reflection of identity columns in tables with mixed case names in PostgreSQL.
References: #6129
sqlite
- [sqlite] [feature] [asyncio]
Added support for the aiosqlite database driver for use with the SQLAlchemy asyncio extension.
See also
Aiosqlite
References: #5920 - [sqlite] [bug] [regression]
Repaired thepysqlcipher
dialect to connect correctly which had regressed in 1.4, and added test + CI support to maintain the driver in working condition. The dialect now imports thesqlcipher3
module for Python 3 by default before falling back topysqlcipher3
which is documented as now being unmaintained.
See also
Pysqlcipher
References: #5848
1.4.2
Released: March 19, 2021
orm
- [orm] [usecase] [dataclasses]
Added support for thedeclared_attr
object to work in the context of dataclass fields.
See also
Using Declarative Mixins with pre-existing dataclasses
References: #6100 - [orm] [bug] [dataclasses]
Fixed issue in new ORM dataclasses functionality where dataclass fields on an abstract base or mixin that contained column or other mapping constructs would not be mapped if they also included a “default” key within the dataclasses.field() object.
References: #6093 - [orm] [bug] [regression]
Fixed regression where theQuery.selectable
accessor, which is a synonym forQuery.__clause_element__()
, got removed, it’s now restored.
References: #6088 - [orm] [bug] [regression]
Fixed regression where use of an unnamed SQL expression such as a SQL function would raise a column targeting error if the query itself were using joinedload for an entity and was also being wrapped in a subquery by the joinedload eager loading process.
References: #6086 - [orm] [bug] [regression]
Fixed regression where theQuery.filter_by()
method would fail to locate the correct source entity if theQuery.join()
method had been used targeting an entity without any kind of ON clause.
References: #6092 - [orm] [bug] [regression]
Fixed regression where the SQL compilation of aFunction
would not work correctly if the object had been “annotated”, which is an internal memoization process used mostly by the ORM. In particular it could affect ORM lazy loads which make greater use of this feature in 1.4.
References: #6095 - [orm] [bug]
Fixed regression where theConcreteBase
would fail to map at all when a mapped column name overlapped with the discriminator column name, producing an assertion error. The use case here did not function correctly in 1.3 as the polymorphic union would produce a query that ignored the discriminator column entirely, while emitting duplicate column warnings. As 1.4’s architecture cannot easily reproduce this essentially broken behavior of 1.3 at theselect()
level right now, the use case now raises an informative error message instructing the user to use the.ConcreteBase._concrete_discriminator_name
attribute to resolve the conflict. To assist with this configuration,.ConcreteBase._concrete_discriminator_name
may be placed on the base class only where it will be automatically used by subclasses; previously this was not the case.
References: #6090
engine
- [engine] [bug] [regression]
Restored top level import forsqlalchemy.engine.reflection
. This ensures that the baseInspector
class is properly registered so thatinspect()
works for third party dialects that don’t otherwise import this package.
sql
- [sql] [bug] [regression]
Fixed issue where using afunc
that includes dotted packagenames would fail to be cacheable by the SQL caching system due to a Python list of names that needed to be a tuple.
References: #6101 - [sql] [bug] [regression]
Fixed regression in thecase()
construct, where the “dictionary” form of argument specification failed to work correctly if it were passed positionally, rather than as a “whens” keyword argument.
References: #6097
mypy
- [mypy] [bug]
Fixed issue in MyPy extension which crashed on detecting the type of aColumn
if the type were given with a module prefix likesa.Integer()
.
References: #sqlalchemy/sqlalchemy2-stubs/2
postgresql
- [postgresql] [usecase]
Rename the column name used by a reflection query that used a reserved word in some postgresql compatible databases.
References: #6982
1.4.1
Released: March 17, 2021
orm
- [orm] [bug] [regression]
Fixed regression where producing a Core expression construct such asselect()
using ORM entities would eagerly configure the mappers, in an effort to maintain compatibility with theQuery
object which necessarily does this to support many backref-related legacy cases. However, coreselect()
constructs are also used in mapper configurations and such, and to that degree this eager configuration is more of an inconvenience, so eager configure has been disabled for theselect()
and other Core constructs in the absence of ORM loading types of functions such asLoad
.
The change maintains the behavior ofQuery
so that backwards compatibility is maintained. However, when using aselect()
in conjunction with ORM entities, a “backref” that isn’t explicitly placed on one of the classes until mapper configure time won’t be available unlessconfigure_mappers()
or the newerconfigure()
has been called elsewhere. Prefer usingrelationship.back_populates
for more explicit relationship configuration which does not have the eager configure requirement.
References: #6066 - [orm] [bug] [regression]
Fixed a critical regression in the relationship lazy loader where the SQL criteria used to fetch a related many-to-one object could go stale in relation to other memoized structures within the loader if the mapper had configuration changes, such as can occur when mappers are late configured or configured on demand, producing a comparison to None and returning no object. Huge thanks to Alan Hamlett for their help tracking this down late into the night.
References: #6055 - [orm] [bug] [regression]
Fixed regression where theQuery.exists()
method would fail to create an expression if the entity list of theQuery
were an arbitrary SQL column expression.
References: #6076 - [orm] [bug] [regression]
Fixed regression where calling uponQuery.count()
in conjunction with a loader option such asjoinedload()
would fail to ignore the loader option. This is a behavior that has always been very specific to theQuery.count()
method; an error is normally raised if a givenQuery
has options that don’t apply to what it is returning.
References: #6052 - [orm] [bug] [regression]
Fixed regression inSession.identity_key()
, including that the method and related methods were not covered by any unit test as well as that the method contained a typo preventing it from functioning correctly.
References: #6067
orm declarative
- [orm] [declarative] [bug] [regression]
Fixed bug where user-mapped classes that contained an attribute named “registry” would cause conflicts with the new registry-based mapping system when usingDeclarativeMeta
. While the attribute remains something that can be set explicitly on a declarative base to be consumed by the metaclass, once located it is placed under a private class variable so it does not conflict with future subclasses that use the same name for other purposes.
References: #6054
engine
- [engine] [bug] [regression]
The Pythonnamedtuple()
has the behavior such that the namescount
andindex
will be served as tuple values if the named tuple includes those names; if they are absent, then their behavior as methods ofcollections.abc.Sequence
is maintained. Therefore theRow
andLegacyRow
classes have been fixed so that they work in this same way, maintaining the expected behavior for database rows that have columns named “index” or “count”.
References: #6074
mssql
- [mssql] [bug] [regression]
Fixed regression where a new setinputsizes() API that’s available for pyodbc was enabled, which is apparently incompatible with pyodbc’s fast_executemany() mode in the absence of more accurate typing information, which as of yet is not fully implemented or tested. The pyodbc dialect and connector has been modified so that setinputsizes() is not used at all unless the parameteruse_setinputsizes
is passed to the dialect, e.g. viacreate_engine()
, at which point its behavior can be customized using theDialectEvents.do_setinputsizes()
hook.
See also
Setinputsizes Support
References: #6058
misc
- [bug] [regression]
Added backitems
andvalues
toColumnCollection
class. The regression was introduced while adding support for duplicate columns in from clauses and selectable in ticket #4753.
References: #6068
SqlAlchemy 2.0 中文文档(五十九)(7)https://developer.aliyun.com/article/1563153