SqlAlchemy 2.0 中文文档(五十九)(4)https://developer.aliyun.com/article/1563150
1.4.18
Released: June 10, 2021
orm
- [orm] [performance] [bug] [regression]
Fixed regression involving how the ORM would resolve a given mapped column to a result row, where under cases such as joined eager loading, a slightly more expensive “fallback” could take place to set up this resolution due to some logic that was removed since 1.3. The issue could also cause deprecation warnings involving column resolution to be emitted when using a 1.4 style query with joined eager loading.
References: #6596 - [orm] [bug]
Clarified the current purpose of therelationship.bake_queries
flag, which in 1.4 is to enable or disable “lambda caching” of statements within the “lazyload” and “selectinload” loader strategies; this is separate from the more foundational SQL query cache that is used for most statements. Additionally, the lazy loader no longer uses its own cache for many-to-one SQL queries, which was an implementation quirk that doesn’t exist for any other loader scenario. Finally, the “lru cache” warning that the lazyloader and selectinloader strategies could emit when handling a wide array of class/relationship combinations has been removed; based on analysis of some end-user cases, this warning doesn’t suggest any significant issue. While settingbake_queries=False
for such a relationship will remove this cache from being used, there’s no particular performance gain in this case as using no caching vs. using a cache that needs to refresh often likely still wins out on the caching being used side.
References: #6072, #6487 - [orm] [bug] [regression]
Adjusted the means by which classes such asscoped_session
andAsyncSession
are generated from the baseSession
class, such that customSession
subclasses such as that used by Flask-SQLAlchemy don’t need to implement positional arguments when they call into the superclass method, and can continue using the same argument styles as in previous releases.
References: #6285 - [orm] [bug] [regression]
Fixed issue where query production for joinedload against a complex left hand side involving joined-table inheritance could fail to produce a correct query, due to a clause adaption issue.
References: #6595 - [orm] [bug]
Fixed issue in experimental “select ORM objects from INSERT/UPDATE” use case where an error was raised if the statement were against a single-table-inheritance subclass.
References: #6591 - [orm] [bug]
The warning that’s emitted forrelationship()
when multiple relationships would overlap with each other as far as foreign key attributes written towards, now includes the specific “overlaps” argument to use for each warning in order to silence the warning without changing the mapping.
References: #6400
asyncio
- [asyncio] [usecase]
Implemented a new registry architecture that allows theAsync
version of an object, likeAsyncSession
,AsyncConnection
, etc., to be locatable given the proxied “sync” object, i.e.Session
,Connection
. Previously, to the degree such lookup functions were used, anAsync
object would be re-created each time, which was less than ideal as the identity and state of the “async” object would not be preserved across calls.
From there, new helper functionsasync_object_session()
,async_session()
as well as a newInstanceState
attributeInstanceState.async_session
have been added, which are used to retrieve the originalAsyncSession
associated with an ORM mapped object, aSession
associated with anAsyncSession
, and anAsyncSession
associated with anInstanceState
, respectively.
This patch also implements new methodsAsyncSession.in_nested_transaction()
,AsyncSession.get_transaction()
,AsyncSession.get_nested_transaction()
.
References: #6319 - [asyncio] [bug]
Fixed an issue that presented itself when using theNullPool
or theStaticPool
with an async engine. This mostly affected the aiosqlite dialect.
References: #6575 - [asyncio] [bug]
Addedasyncio.exceptions.TimeoutError
,asyncio.exceptions.CancelledError
as so-called “exit exceptions”, a class of exceptions that include things likeGreenletExit
andKeyboardInterrupt
, which are considered to be events that warrant considering a DBAPI connection to be in an unusable state where it should be recycled.
References: #6592
postgresql
- [postgresql] [bug] [regression]
Fixed regression where using the PostgreSQL “INSERT…ON CONFLICT” structure would fail to work with the psycopg2 driver if it were used in an “executemany” context along with bound parameters in the “SET” clause, due to the implicit use of the psycopg2 fast execution helpers which are not appropriate for this style of INSERT statement; as these helpers are the default in 1.4 this is effectively a regression. Additional checks to exclude this kind of statement from that particular extension have been added.
References: #6581
sqlite
- [sqlite] [bug]
Add note regarding encryption-related pragmas for pysqlcipher passed in the url.
This change is also backported to: 1.3.25
References: #6589 - [sqlite] [bug] [regression]
The fix for pysqlcipher released in version 1.4.3 #5848 was unfortunately non-working, in that the newon_connect_url
hook was erroneously not receiving aURL
object under normal usage ofcreate_engine()
and instead received a string that was unhandled; the test suite failed to fully set up the actual conditions under which this hook is called. This has been fixed.
References: #6586
1.4.17
Released: May 29, 2021
orm
- [orm] [bug] [regression]
Fixed regression caused by just-released performance fix mentioned in #6550 where a query.join() to a relationship could produce an AttributeError if the query were made against non-ORM structures only, a fairly unusual calling pattern.
References: #6558
1.4.16
Released: May 28, 2021
general
- [general] [bug]
Resolved various deprecation warnings which were appearing as of Python version 3.10.0b1.
References: #6540, #6543
orm
- [orm] [bug]
Fixed issue when usingrelationship.cascade_backrefs
parameter set toFalse
, which per cascade_backrefs behavior deprecated for removal in 2.0 is set to become the standard behavior in SQLAlchemy 2.0, where adding the item to a collection that uniquifies, such asset
ordict
would fail to fire a cascade event if the object were already associated in that collection via the backref. This fix represents a fundamental change in the collection mechanics by introducing a new event state which can fire off for a collection mutation even if there is no net change on the collection; the action is now suited using a new event hookAttributeEvents.append_wo_mutation()
.
References: #6471 - [orm] [bug] [regression]
Fixed regression involving clause adaption of labeled ORM compound elements, such as single-table inheritance discriminator expressions with conditionals or CASE expressions, which could cause aliased expressions such as those used in ORM join / joinedload operations to not be adapted correctly, such as referring to the wrong table in the ON clause in a join.
This change also improves a performance bump that was located within the process of invokingSelect.join()
given an ORM attribute as a target.
References: #6550 - [orm] [bug] [regression]
Fixed regression where the full combination of joined inheritance, global with_polymorphic, self-referential relationship and joined loading would fail to be able to produce a query with the scope of lazy loads and object refresh operations that also attempted to render the joined loader.
References: #6495 - [orm] [bug]
Enhanced the bind resolution rules forSession.execute()
so that when a non-ORM statement such as aninsert()
construct nonetheless is built against ORM objects, to the greatest degree possible the ORM entity will be used to resolve the bind, such as for aSession
that has a bind map set up on a common superclass without specific mappers or tables named in the map.
References: #6484
engine
- [engine] [bug]
Fixed issue where an@
sign in the database portion of a URL would not be interpreted correctly if the URL also had a username:password section.
References: #6482 - [engine] [bug]
Fixed a long-standing issue withURL
where query parameters following the question mark would not be parsed correctly if the URL did not contain a database portion with a backslash.
References: #6329
sql
- [sql] [bug] [regression]
Fixed regression in dynamic loader strategy andrelationship()
overall where therelationship.order_by
parameter were stored as a mutable list, which could then be mutated when combined with additional “order_by” methods used against the dynamic query object, causing the ORDER BY criteria to continue to grow repetitively.
References: #6549
mssql
- [mssql] [usecase]
Implemented support for aCTE
construct to be used directly as the target of adelete()
construct, i.e. “WITH … AS cte DELETE FROM cte”. This appears to be a useful feature of SQL Server.
References: #6464
misc
- [bug] [ext]
Fixed a deprecation warning that was emitted when usingautomap_base()
without passing an existingBase
.
References: #6529 - [bug] [pep484]
Remove pep484 types from the code. Current effort is around the stub package, and having typing in two places makes thing worse, since the types in the SQLAlchemy source were usually outdated compared to the version in the stubs.
References: #6461 - [bug] [ext] [regression]
Fixed regression in thesqlalchemy.ext.instrumentation
extension that prevented instrumentation disposal from working completely. This fix includes both a 1.4 regression fix as well as a fix for a related issue that existed in 1.3 also. As part of this change, thesqlalchemy.ext.instrumentation.InstrumentationManager
class now has a new methodunregister()
, which replaces the previous methoddispose()
, which was not called as of version 1.4.
References: #6390
1.4.15
Released: May 11, 2021
general
- [general] [feature]
A new approach has been applied to the warnings system in SQLAlchemy to accurately predict the appropriate stack level for each warning dynamically. This allows evaluating the source of SQLAlchemy-generated warnings and deprecation warnings to be more straightforward as the warning will indicate the source line within end-user code, rather than from an arbitrary level within SQLAlchemy’s own source code.
References: #6241
orm
- [orm] [bug] [regression]
Fixed additional regression caused by “eager loaders run on unexpire” feature #1763 where the feature would run for acontains_eager()
eagerload option in the case that thecontains_eager()
were chained to an additional eager loader option, which would then produce an incorrect query as the original query-bound join criteria were no longer present.
References: #6449 - [orm] [bug]
Fixed issue in subquery loader strategy which prevented caching from working correctly. This would have been seen in the logs as a “generated” message instead of “cached” for all subqueryload SQL emitted, which by saturating the cache with new keys would degrade overall performance; it also would produce “LRU size alert” warnings.
References: #6459
sql
- [sql] [bug]
Adjusted the logic added as part of #6397 in 1.4.12 so that internal mutation of theBindParameter
object occurs within the clause construction phase as it did before, rather than in the compilation phase. In the latter case, the mutation still produced side effects against the incoming construct and additionally could potentially interfere with other internal mutation routines.
References: #6460
mysql
- [mysql] [bug] [documentation]
Added support for thessl_check_hostname=
parameter in mysql connection URIs and updated the mysql dialect documentation regarding secure connections. Original pull request courtesy of Jerry Zhao.
References: #5397
1.4.14
Released: May 6, 2021
orm
- [orm] [bug] [regression]
Fixed regression involvinglazy='dynamic'
loader in conjunction with a detached object. The previous behavior was that the dynamic loader upon calling methods like.all()
returns empty lists for detached objects without error, this has been restored; however a warning is now emitted as this is not the correct result. Other dynamic loader scenarios correctly raiseDetachedInstanceError
.
References: #6426
engine
- [engine] [usecase] [orm]Applied consistent behavior to the use case of calling
.commit()
or.rollback()
inside of an existing.begin()
context manager, with the addition of potentially emitting SQL within the block subsequent to the commit or rollback. This change continues upon the change first added in #6155 where the use case of calling “rollback” inside of a.begin()
contextmanager block was proposed:
- calling
.commit()
or.rollback()
will now be allowed without error or warning within all scopes, including that of legacy and futureEngine
, ORMSession
, asyncioAsyncEngine
. Previously, theSession
disallowed this. - The remaining scope of the context manager is then closed; when the block ends, a check is emitted to see if the transaction was already ended, and if so the block returns without action.
- It will now raise an error if subsequent SQL of any kind is emitted within the block, after
.commit()
or.rollback()
is called. The block should be closed as the state of the executable object would otherwise be undefined in this state.
- References: #6288
- [engine] [bug] [regression]
Established a deprecation path for calling upon theCursorResult.keys()
method for a statement that returns no rows to provide support for legacy patterns used by the “records” package as well as any other non-migrated applications. Previously, this would raiseResourceClosedException
unconditionally in the same way as it does when attempting to fetch rows. While this is the correct behavior going forward, theLegacyCursorResult
object will now in this case return an empty list for.keys()
as it did in 1.3, while also emitting a 2.0 deprecation warning. The_cursor.CursorResult
, used when using a 2.0-style “future” engine, will continue to raise as it does now.
References: #6427
sql
- [sql] [bug] [regression]
Fixed regression caused by the “empty in” change just made in #6397 1.4.12 where the expression needs to be parenthesized for the “not in” use case, otherwise the condition will interfere with the other filtering criteria.
References: #6428 - [sql] [bug] [regression]
TheTypeDecorator
class will now emit a warning when used in SQL compilation with caching unless the.cache_ok
flag is set toTrue
orFalse
. A new class-level attributeTypeDecorator.cache_ok
may be set which will be used as an indication that all the parameters passed to the object are safe to be used as a cache key if set toTrue
,False
means they are not.
References: #6436
1.4.13
Released: May 3, 2021
orm
- [orm] [bug] [regression]
Fixed regression inselectinload
loader strategy that would cause it to cache its internal state incorrectly when handling relationships that join across more than one column, such as when using a composite foreign key. The invalid caching would then cause other unrelated loader operations to fail.
References: #6410 - [orm] [bug] [regression]
Fixed regression whereQuery.filter_by()
would not work if the lead entity were a SQL function or other expression derived from the primary entity in question, rather than a simple entity or column of that entity. Additionally, improved the behavior ofSelect.filter_by()
overall to work with column expressions even in a non-ORM context.
References: #6414 - [orm] [bug] [regression]
Fixed regression where usingselectinload()
andsubqueryload()
to load a two-level-deep path would lead to an attribute error.
References: #6419 - [orm] [bug] [regression]
Fixed regression where using thenoload()
loader strategy in conjunction with a “dynamic” relationship would lead to an attribute error as the noload strategy would attempt to apply itself to the dynamic loader.
References: #6420
engine
- [engine] [bug] [regression]
Restored a legacy transactional behavior that was inadvertently removed from theConnection
as it was never tested as a known use case in previous versions, where calling upon theConnection.begin_nested()
method, when no transaction is present, does not create a SAVEPOINT at all and instead starts an outer transaction, returning aRootTransaction
object instead of aNestedTransaction
object. ThisRootTransaction
then will emit a real COMMIT on the database connection when committed. Previously, the 2.0 style behavior was present in all cases that would autobegin a transaction but not commit it, which is a behavioral change.
When using a 2.0 style connection object, the behavior is unchanged from previous 1.4 versions; callingConnection.begin_nested()
will “autobegin” the outer transaction if not already present, and then as instructed emit a SAVEPOINT, returning theNestedTransaction
object. The outer transaction is committed by calling uponConnection.commit()
, as is “commit-as-you-go” style usage.
In non-“future” mode, while the old behavior is restored, it also emits a 2.0 deprecation warning as this is a legacy behavior.
References: #6408
asyncio
- [asyncio] [bug] [regression]
Fixed a regression introduced by #6337 that would create anasyncio.Lock
which could be attached to the wrong loop when instantiating the async engine before any asyncio loop was started, leading to an asyncio error message when attempting to use the engine under certain circumstances.
References: #6409
postgresql
- [postgresql] [usecase]
Add support for server side cursors in the pg8000 dialect for PostgreSQL. This allows use of theConnection.execution_options.stream_results
option.
References: #6198
1.4.12
Released: April 29, 2021
orm
- [orm] [bug]
Fixed issue inSession.bulk_save_objects()
when used with persistent objects which would fail to track the primary key of mappings where the column name of the primary key were different than the attribute name.
This change is also backported to: 1.3.25
References: #6392 - [orm] [bug] [caching] [regression]
Fixed critical regression where bound parameter tracking as used in the SQL caching system could fail to track all parameters for the case where the same SQL expression containing a parameter were used in an ORM-related query using a feature such as class inheritance, which was then embedded in an enclosing expression which would make use of that same expression multiple times, such as a UNION. The ORM would individually copy the individual SELECT statements as part of compilation with class inheritance, which then embedded in the enclosing statement would fail to accommodate for all parameters. The logic that tracks this condition has been adjusted to work for multiple copies of a parameter.
References: #6391 - [orm] [bug]Fixed two distinct issues mostly affecting
hybrid_property
, which would come into play under common mis-configuration scenarios that were silently ignored in 1.3, and now failed in 1.4, where the “expression” implementation would return a nonClauseElement
such as a boolean value. For both issues, 1.3’s behavior was to silently ignore the mis-configuration and ultimately attempt to interpret the value as a SQL expression, which would lead to an incorrect query.
- Fixed issue regarding interaction of the attribute system with hybrid_property, where if the
__clause_element__()
method of the attribute returned a non-ClauseElement
object, an internalAttributeError
would lead the attribute to return theexpression
function on the hybrid_property itself, as the attribute error was against the name.expression
which would invoke the__getattr__()
method as a fallback. This now raises explicitly. In 1.3 the non-ClauseElement
was returned directly. - Fixed issue in SQL argument coercions system where passing the wrong kind of object to methods that expect column expressions would fail if the object were altogether not a SQLAlchemy object, such as a Python function, in cases where the object were not just coerced into a bound value. Again 1.3 did not have a comprehensive argument coercion system so this case would also pass silently.
- References: #6350
- [orm] [bug]
Fixed issue where using aSelect
as a subquery in an ORM context would modify theSelect
in place to disable eagerloads on that object, which would then cause that sameSelect
to not eagerload if it were then re-used in a top-level execution context.
References: #6378 - [orm] [bug] [regression]
Fixed issue where the new autobegin behavior failed to “autobegin” in the case where an existing persistent object has an attribute change, which would then impact the behavior ofSession.rollback()
in that no snapshot was created to be rolled back. The “attribute modify” mechanics have been updated to ensure “autobegin”, which does not perform any database work, does occur when persistent attributes change in the same manner as whenSession.add()
is called. This is a regression as in 1.3, the rollback() method always had a transaction to roll back and would expire every time.
References: #6359, #6360 - [orm] [bug] [regression]
Fixed regression in ORM where using hybrid property to indicate an expression from a different entity would confuse the column-labeling logic in the ORM and attempt to derive the name of the hybrid from that other class, leading to an attribute error. The owning class of the hybrid attribute is now tracked along with the name.
References: #6386 - [orm] [bug] [regression]
Fixed regression in hybrid_property where a hybrid against a SQL function would generate anAttributeError
when attempting to generate an entry for the.c
collection of a subquery in some cases; among other things this would impact its use in cases like that ofQuery.count()
.
References: #6401 - [orm] [bug] [dataclasses]
Adjusted the declarative scan for dataclasses so that the inheritance behavior ofdeclared_attr()
established on a mixin, when using the new form of having it inside of adataclasses.field()
construct and not actually a descriptor attribute on the class, correctly accommodates the case when the target class to be mapped is a subclass of an existing mapped class which has already mapped thatdeclared_attr()
, and therefore should not be re-applied to this class.
References: #6346 - [orm] [bug]
Fixed an issue with the (deprecated in 1.4)ForeignKeyConstraint.copy()
method that caused an error when invoked with theschema
argument.
References: #6353
engine
- [engine] [bug]
Fixed issue where usage of an explicitSequence
would produce inconsistent “inline” behavior for anInsert
construct that includes multiple values phrases; the first seq would be inline but subsequent ones would be “pre-execute”, leading to inconsistent sequence ordering. The sequence expressions are now fully inline.
References: #6361
sql
- [sql] [bug]
Revised the “EMPTY IN” expression to no longer rely upon using a subquery, as this was causing some compatibility and performance problems. The new approach for selected databases takes advantage of using a NULL-returning IN expression combined with the usual “1 != 1” or “1 = 1” expression appended by AND or OR. The expression is now the default for all backends other than SQLite, which still had some compatibility issues regarding tuple “IN” for older SQLite versions.
Third party dialects can still override how the “empty set” expression renders by implementing a new compiler methoddef visit_empty_set_op_expr(self, type_, expand_op)
, which takes precedence over the existingdef visit_empty_set_expr(self, element_types)
which remains in place.
References: #6258, #6397 - [sql] [bug] [regression]
Fixed regression where usage of thetext()
construct inside the columns clause of aSelect
construct, which is better handled by using aliteral_column()
construct, would nonetheless prevent constructs likeunion()
from working correctly. Other use cases, such as constructing subuqeries, continue to work the same as in prior versions where thetext()
construct is silently omitted from the collection of exported columns. Also repairs similar use within the ORM.
References: #6343 - [sql] [bug] [regression]
Fixed regression involving legacy methods such asSelect.append_column()
where internal assertions would fail.
References: #6261 - [sql] [bug] [regression]
Fixed regression caused by #5395 where tuning back the check for sequences inselect()
now caused failures when doing 2.0-style querying with a mapped class that also happens to have an__iter__()
method. Tuned the check some more to accommodate this as well as some other interesting__iter__()
scenarios.
References: #6300
schema
- [schema] [bug] [mariadb] [mysql] [oracle] [postgresql]
Ensure that the MySQL and MariaDB dialect ignore theIdentity
construct while rendering theAUTO_INCREMENT
keyword in a create table.
The Oracle and PostgreSQL compiler was updated to not renderIdentity
if the database version does not support it (Oracle < 12 and PostgreSQL < 10). Previously it was rendered regardless of the database version.
References: #6338
postgresql
- [postgresql] [bug]
Fixed very old issue where theEnum
datatype would not inherit theMetaData.schema
parameter of aMetaData
object when that object were passed to theEnum
usingEnum.metadata
.
References: #6373
sqlite
- [sqlite] [usecase]
Default to usingSingletonThreadPool
for in-memory SQLite databases created using URI filenames. Previously the default pool used was theNullPool
that precented sharing the same database between multiple engines.
References: #6379
mssql
- [mssql] [bug] [schema]
AddTypeEngine.as_generic()
support forsqlalchemy.dialects.mysql.BIT
columns, mapping them toBoolean
.
References: #6345 - [mssql] [bug] [regression]
Fixed regression caused by #6306 which added support forDateTime(timezone=True)
, where the previous behavior of the pyodbc driver of implicitly dropping the tzinfo from a timezone-aware date when INSERTing into a timezone-naive DATETIME column were lost, leading to a SQL Server error when inserting timezone-aware datetime objects into timezone-native database columns.
References: #6366
1.4.11
Released: April 21, 2021
orm declarative
- [orm] [declarative] [bug] [regression]
Fixed regression where recent changes to support Python dataclasses had the inadvertent effect that an ORM mapped class could not successfully override the__new__()
method.
References: #6331
engine
- [engine] [bug] [regression]
Fixed critical regression caused by the change in #5497 where the connection pool “init” phase no longer occurred within mutexed isolation, allowing other threads to proceed with the dialect uninitialized, which could then impact the compilation of SQL statements.
References: #6337
1.4.10
Released: April 20, 2021
orm
- [orm] [usecase]
Altered some of the behavior repaired in #6232 where theimmediateload
loader strategy no longer goes into recursive loops; the modification is that an eager load (joinedload, selectinload, or subqueryload) from A->bs->B which then statesimmediateload
for a simple manytoone B->a->A that’s in the identity map will populate the B->A, so that this attribute is back-populated when the collection of A/A.bs are loaded. This allows the objects to be functional when detached. - [orm] [bug]
Fixed bug in newwith_loader_criteria()
feature where using a mixin class withdeclared_attr()
on an attribute that were accessed inside the custom lambda would emit a warning regarding using an unmapped declared attr, when the lambda callable were first initialized. This warning is now prevented using special instrumentation for this lambda initialization step.
References: #6320 - [orm] [bug] [regression]
Fixed additional regression caused by the “eagerloaders on refresh” feature added in #1763 where the refresh operation historically would setpopulate_existing
, which given the new feature now overwrites pending changes on eagerly loaded objects when autoflush is false. The populate_existing flag has been turned off for this case and a more specific method used to ensure the correct attributes refreshed.
References: #6326 - [orm] [bug] [result]
Fixed an issue when using 2.0 style execution that prevented usingResult.scalar_one()
orResult.scalar_one_or_none()
after callingResult.unique()
, for the case where the ORM is returning a single-element row in any case.
References: #6299
sql
- [sql] [bug]
Fixed issue in SQL compiler where the bound parameters set up for aValues
construct wouldn’t be positionally tracked correctly if inside of aCTE
, affecting database drivers that support VALUES + ctes and use positional parameters such as SQL Server in particular as well as asyncpg. The fix also repairs support for compiler flags such asliteral_binds
.
References: #6327 - [sql] [bug]
Repaired and solidified issues regarding custom functions and other arbitrary expression constructs which within SQLAlchemy’s column labeling mechanics would seek to usestr(obj)
to get a string representation to use as an anonymous column name in the.c
collection of a subquery. This is a very legacy behavior that performs poorly and leads to lots of issues, so has been revised to no longer perform any compilation by establishing specific methods onFunctionElement
to handle this case, as SQL functions are the only use case that it came into play. An effect of this behavior is that an unlabeled column expression with no derivable name will be given an arbitrary label starting with the prefix"_no_label"
in the.c
collection of a subquery; these were previously being represented either as the generic stringification of that expression, or as an internal symbol.
References: #6256
schema
- [schema] [bug]
Fixed issue wherenext_value()
was not deriving its type from the correspondingSequence
, instead hardcoded toInteger
. The specific numeric type is now used.
References: #6287
mypy
- [mypy] [bug]
Fixed issue where mypy plugin would not correctly interpret an explicitMapped
annotation in conjunction with arelationship()
that refers to a class by string name; the correct annotation would be downgraded to a less specific one leading to typing errors.
References: #6255
mssql
- [mssql] [usecase]
TheDateTime.timezone
parameter when set toTrue
will now make use of theDATETIMEOFFSET
column type with SQL Server when used to emit DDL, rather thanDATETIME
where the flag was silently ignored.
References: #6306
misc
- [bug] [declarative] [regression]
Fixedinstrument_declarative()
that called a non existing registry method.
References: #6291
1.4.9
Released: April 17, 2021
orm
- [orm] [usecase]
Established support forsynoynm()
in conjunction with hybrid property, assocaitionproxy is set up completely, including that synonyms can be established linking to these constructs which work fully. This is a behavior that was semi-explicitly disallowed previously, however since it did not fail in every scenario, explicit support for assoc proxy and hybrids has been added.
References: #6267 - [orm] [performance] [bug] [regression] [sql]
Fixed a critical performance issue where the traversal of aselect()
construct would traverse a repetitive product of the represented FROM clauses as they were each referenced by columns in the columns clause; for a series of nested subqueries with lots of columns this could cause a large delay and significant memory growth. This traversal is used by a wide variety of SQL and ORM functions, including by the ORMSession
when it’s configured to have “table-per-bind”, which while this is not a common use case, it seems to be what Flask-SQLAlchemy is hardcoded as using, so the issue impacts Flask-SQLAlchemy users. The traversal has been repaired to uniqify on FROM clauses which was effectively what would happen implicitly with the pre-1.4 architecture.
References: #6304 - [orm] [bug] [regression]
Fixed regression where an attribute that is mapped to asynonym()
could not be used in column loader options such asload_only()
.
References: #6272
sql
- [sql] [bug] [regression]
Fixed regression where an empty in statement on a tuple would result in an error when compiled with the optionliteral_binds=True
.
References: #6290
postgresql
- [postgresql] [bug] [regression] [sql]
Fixed an argument error in the default and PostgreSQL compilers that would interfere with an UPDATE…FROM or DELETE…FROM…USING statement that was then SELECTed from as a CTE.
References: #6303
1.4.8
Released: April 15, 2021
orm
- [orm] [bug] [regression]
Fixed a cache leak involving thewith_expression()
loader option, where the given SQL expression would not be correctly considered as part of the cache key.
Additionally, fixed regression involving the correspondingquery_expression()
feature. While the bug technically exists in 1.3 as well, it was not exposed until 1.4. The “default expr” value ofnull()
would be rendered when not needed, and additionally was also not adapted correctly when the ORM rewrites statements such as when using joined eager loading. The fix ensures “singleton” expressions likeNULL
andtrue
aren’t “adapted” to refer to columns in ORM statements, and additionally ensures that aquery_expression()
with no default expression doesn’t render in the statement if awith_expression()
isn’t used.
References: #6259 - [orm] [bug]
Fixed issue in the new feature ofSession.refresh()
introduced by #1763 where eagerly loaded relationships are also refreshed, where thelazy="raise"
andlazy="raise_on_sql"
loader strategies would interfere with theimmediateload()
loader strategy, thus breaking the feature for relationships that were loaded withselectinload()
,subqueryload()
as well.
References: #6252
engine
- [engine] [bug]
TheDialect.has_table()
method now raises an informative exception if a non-Connection is passed to it, as this incorrect behavior seems to be common. This method is not intended for external use outside of a dialect. Please use theInspector.has_table()
method or for cross-compatibility with older SQLAlchemy versions, theEngine.has_table()
method.
sql
- [sql] [feature]
The tuple returned byCursorResult.inserted_primary_key
is now aRow
object with a named tuple interface on top of the existing tuple interface.
References: #3314 - [sql] [bug] [regression]
Fixed regression where theBindParameter
object would not properly render for an IN expression (i.e. using the “post compile” feature in 1.4) if the object were copied from either an internal cloning operation, or from a pickle operation, and the parameter name contained spaces or other special characters.
References: #6249 - [sql] [bug] [regression] [sqlite]
Fixed regression where the introduction of the INSERT syntax “INSERT… VALUES (DEFAULT)” was not supported on some backends that do however support “INSERT…DEFAULT VALUES”, including SQLite. The two syntaxes are now each individually supported or non-supported for each dialect, for example MySQL supports “VALUES (DEFAULT)” but not “DEFAULT VALUES”. Support for Oracle has also been enabled.
References: #6254
mypy
- [mypy] [change]
Updated Mypy plugin to only use the public plugin interface of the semantic analyzer. - [mypy] [bug]
Revised the fix forOrderingList
from version 1.4.7 which was testing against the incorrect API.
References: #6205
asyncio
- [asyncio] [bug]
Fix typo that prevented setting thebind
attribute of anAsyncSession
to the correct value.
References: #6220
mssql
- [mssql] [bug] [regression]
Fixed an additional regression in the same area as that of #6173, #6184, where using a value of 0 for OFFSET in conjunction with LIMIT with SQL Server would create a statement using “TOP”, as was the behavior in 1.3, however due to caching would then fail to respond accordingly to other values of OFFSET. If the “0” wasn’t first, then it would be fine. For the fix, the “TOP” syntax is now only emitted if the OFFSET value is omitted entirely, that is,Select.offset()
is not used. Note that this change now requires that if the “with_ties” or “percent” modifiers are used, the statement can’t specify an OFFSET of zero, it now needs to be omitted entirely.
References: #6265
1.4.7
Released: April 9, 2021
orm
- [orm] [bug] [regression]
Fixed regression where thesubqueryload()
loader strategy would fail to correctly accommodate sub-options, such as adefer()
option on a column, if the “path” of the subqueryload were more than one level deep.
References: #6221 - [orm] [bug] [regression]
Fixed regression where themerge_frozen_result()
function relied upon by the dogpile.caching example was not included in tests and began failing due to incorrect internal arguments.
References: #6211 - [orm] [bug] [regression]
Fixed critical regression where theSession
could fail to “autobegin” a new transaction when a flush occurred without an existing transaction in place, implicitly placing theSession
into legacy autocommit mode which commit the transaction. TheSession
now has a check that will prevent this condition from occurring, in addition to repairing the flush issue.
Additionally, scaled back part of the change made as part of #5226 which can run autoflush during an unexpire operation, to not actually do this in the case of aSession
using legacySession.autocommit
mode, as this incurs a commit within a refresh operation.
References: #6233 - [orm] [bug] [regression]
Fixed regression where the ORM compilation scheme would assume the function name of a hybrid property would be the same as the attribute name in such a way that anAttributeError
would be raised, when it would attempt to determine the correct name for each element in a result tuple. A similar issue exists in 1.3 but only impacts the names of tuple rows. The fix here adds a check that the hybrid’s function name is actually present in the__dict__
of the class or its superclasses before assigning this name; otherwise, the hybrid is considered to be “unnamed” and ORM result tuples will use the naming scheme of the underlying expression.
References: #6215 - [orm] [bug] [regression]
Fixed critical regression caused by the new feature added as part of #1763, eager loaders are invoked on unexpire operations. The new feature makes use of the “immediateload” eager loader strategy as a substitute for a collection loading strategy, which unlike the other “post-load” strategies was not accommodating for recursive invocations between mutually-dependent relationships, leading to recursion overflow errors.
References: #6232
engine
- [engine] [bug] [regression]
Fixed up the behavior of theRow
object when dictionary access is used upon it, meaning converting to a dict viadict(row)
or accessing members using strings or other objects i.e.row["some_key"]
works as it would with a dictionary, rather than raisingTypeError
as would be the case with a tuple, whether or not the C extensions are in place. This was originally supposed to emit a 2.0 deprecation warning for the “non-future” case usingLegacyRow
, and was to raiseTypeError
for the “future”Row
class. However, the C version ofRow
was failing to raise thisTypeError
, and to complicate matters, theSession.execute()
method now returnsRow
in all cases to maintain consistency with the ORM result case, so users who didn’t have C extensions installed would see different behavior in this one case for existing pre-1.4 style code.
Therefore, in order to soften the overall upgrade scheme as most users have not been exposed to the more strict behavior ofRow
up through 1.4.6,LegacyRow
andRow
both provide for string-key access as well as support fordict(row)
, in all cases emitting the 2.0 deprecation warning whenSQLALCHEMY_WARN_20
is enabled. TheRow
object still uses tuple-like behavior for__contains__
, which is probably the only noticeable behavioral change compared toLegacyRow
, other than the removal of dictionary-style methodsvalues()
anditems()
.
References: #6218
sql
- [sql] [bug] [regression]
Enhanced the “expanding” feature used forColumnOperators.in_()
operations to infer the type of expression from the right hand list of elements, if the left hand side does not have any explicit type set up. This allows the expression to support stringification among other things. In 1.3, “expanding” was not automatically used forColumnOperators.in_()
expressions, so in that sense this change fixes a behavioral regression.
References: #6222 - [sql] [bug]
Fixed the “stringify” compiler to support a basic stringification of a “multirow” INSERT statement, i.e. one with multiple tuples following the VALUES keyword.
schema
- [schema] [bug] [regression]
Fixed regression where usage of a token in theConnection.execution_options.schema_translate_map
dictionary which contained special characters such as braces would fail to be substituted properly. Use of square bracket characters[]
is now explicitly disallowed as these are used as a delimiter character in the current implementation.
References: #6216
mypy
- [mypy] [bug]
Fixed issue in Mypy plugin where the plugin wasn’t inferring the correct type for columns of subclasses that don’t directly descend fromTypeEngine
, in particular that ofTypeDecorator
andUserDefinedType
.
tests
- [tests] [change]
Added a new flag toDefaultDialect
calledsupports_schemas
; third party dialects may set this flag toFalse
to disable SQLAlchemy’s schema-level tests when running the test suite for a third party dialect.
SqlAlchemy 2.0 中文文档(五十九)(6)https://developer.aliyun.com/article/1563152