Released: June 29, 2018
[bug] [mysql] Fixed percent-sign doubling in mysql-connector-python dialect, which does
not require de-doubling of percent signs. Additionally, the mysql-
connector-python driver is inconsistent in how it passes the column names
in cursor.description, so a workaround decoder has been added to
conditionally decode these randomly-sometimes-bytes values to unicode only
if needed. Also improved test support for mysql-connector-python, however
it should be noted that this driver still has issues with unicode that
continue to be unresolved as of yet.
[bug] [mssql] Fixed bug in MSSQL reflection where when two same-named tables in different
schemas had same-named primary key constraints, foreign key constraints
referring to one of the tables would have their columns doubled, causing
errors. Pull request courtesy Sean Dunn.
[bug] [sql] Fixed regression in 1.2 due to #4147 where a
has had some of its indexed columns redefined with new ones, as would occur
when overriding columns during reflection or when using
Table.extend_existing, such that the
method would fail when attempting to copy those indexes as they still
referred to the replaced column. The copy logic now accommodates for this
[bug] [mysql] Fixed bug in index reflection where on MySQL 8.0 an index that includes
ASC or DESC in an indexed column specification would not be correctly
reflected, as MySQL 8.0 introduces support for returning this information
in a table definition string.
[bug] [orm] Fixed issue where chaining multiple join elements inside of
Query.join()might not correctly adapt to the previous left-hand
side, when chaining joined inheritance classes that share the same base
[bug] [orm] Fixed bug in cache key generation for baked queries which could cause a
too-short cache key to be generated for the case of eager loads across
subclasses. This could in turn cause the eagerload query to be cached in
place of a non-eagerload query, or vice versa, for a polymorhic "selectin"
load, or possibly for lazy loads or selectin loads as well.
[bug] [sqlite] Fixed issue in test suite where SQLite 3.24 added a new reserved word that
conflicted with a usage in TypeReflectionTest. Pull request courtesy Nils
[feature] [oracle] Added a new event currently used only by the cx_Oracle dialect,
DialectEvents.setiputsizes(). The event passes a dictionary of
BindParameterobjects to DBAPI-specific type objects that will be
passed, after conversion to parameter names, to the cx_Oracle
cursor.setinputsizes()method. This allows both visibility into the
setinputsizes process as well as the ability to alter the behavior of what
datatypes are passed to this method.
[bug] [orm] Fixed bug in new polymorphic selectin loading where the BakedQuery used
internally would be mutated by the given loader options, which would both
inappropriately mutate the subclass query as well as carry over the effect
to subsequent queries.
[bug] [py3k] Replaced the usage of inspect.formatargspec() with a vendored version
copied from the Python standard library, as inspect.formatargspec()
is deprecated and as of Python 3.7.0 is emitting a warning.
[ext] [feature] Added new attribute
Query.lazy_loaded_fromwhich is populated
InstanceStatethat is using this
order to lazy load a relationship. The rationale for this is that
it serves as a hint for the horizontal sharding feature to use, such that
the identity token of the state can be used as the default identity token
to use for the query within id_chooser().
[bug] [mysql] Fixed bug in MySQLdb dialect and variants such as PyMySQL where an
additional "unicode returns" check upon connection makes explicit use of
the "utf8" character set, which in MySQL 8.0 emits a warning that utf8mb4
should be used. This is now replaced with a utf8mb4 equivalent.
Documentation is also updated for the MySQL dialect to specify utf8mb4 in
all examples. Additional changes have been made to the test suite to use
utf8mb3 charsets and databases (there seem to be collation issues in some
edge cases with utf8mb4), and to support configuration default changes made
in MySQL 8.0 such as explicit_defaults_for_timestamp as well as new errors
raised for invalid MyISAM indexes.
[bug] [mysql] The
Updateconstruct now accommodates a
as supported by MySQL for UPDATE..FROM. As the construct already
accepted an alias object for a similar purpose, the feature of UPDATE
against a non-table was already implied so this has been added.
[bug] [mssql] [py3k] Fixed issue within the SQL Server dialect under Python 3 where when running
against a non-standard SQL server database that does not contain either the
"sys.dm_exec_sessions" or "sys.dm_pdw_nodes_exec_sessions" views, leading
to a failure to fetch the isolation level, the error raise would fail due
to an UnboundLocalError.
[bug] [orm] Fixed regression caused by #4256 (itself a regression fix for
#4228) which breaks an undocumented behavior which converted for a
non-sequence of entities passed directly to the
into a single-element sequence. While this behavior was never supported or
documented, it's already in use so has been added as a behavioral contract
[bug] [orm] Fixed an issue that was both a performance regression in 1.2 as well as an
incorrect result regarding the "baked" lazy loader, involving the
generation of cache keys from the original
options. If the loader options were built up in a "branched" style using
common base elements for multiple options, the same options would be
rendered into the cache key repeatedly, causing both a performance issue as
well as generating the wrong cache key. This is fixed, along with a
performance improvement when such "branched" options are applied via
Query.options()to prevent the same option objects from being
[bug] [mysql] [oracle] Fixed INSERT FROM SELECT with CTEs for the Oracle and MySQL dialects, where
the CTE was being placed above the entire statement as is typical with
other databases, however Oracle and MariaDB 10.2 wants the CTE underneath
the "INSERT" segment. Note that the Oracle and MySQL dialects don't yet
work when a CTE is applied to a subquery inside of an UPDATE or DELETE
statement, as the CTE is still applied to the top rather than inside the