1.3 Changelog
1.3.11
no release date
engine
- [engine] [bug]
Fixed bug where parameter repr as used in logging and error reporting needsadditional context in order to distinguish between a list of parameters fora single statement and a list of parameter lists, as the “list of lists”structure could also indicate a single parameter list where the firstparameter itself is a list, such as for an array parameter. Theengine/connection now passes in an additional boolean indicating how theparameters should be considered. The only SQLAlchemy backend that expectsarrays as parameters is that of psycopg2 which uses pyformat parameters,so this issue has not been too apparent, however as other drivers that usepositional gain more features it is important that this be supported. Italso eliminates the need for the parameter repr function to guess based onthe parameter structure passed.References: #4902
firebird
- [firebird] [bug]
Added additional “disconnect” message “Error writing data to theconnection” to Firebird disconnection detection. Pull request courtesylukens.References: #4903
1.3.10
Released: October 9, 2019
mssql
- [mssql] [bug]
Fixed bug in SQL Server dialect with new “max_identifier_length” featurewhere the mssql dialect already featured this flag, and the implementationdid not accommodate for the new initialization hook correctly.References: #4857
oracle
- [oracle] [bug]
Fixed regression in Oracle dialect that was inadvertently using maxidentifier length of 128 characters on Oracle server 12.2 and greater eventhough the stated contract for the remainder of the 1.3 series is thatthis value stays at 30 until version SQLAlchemy 1.4. Also repaired issueswith the retrieval of the “compatibility” version, and removed the warningemitted when the “v$parameter” view was not accessible as this was causinguser confusion.References: #4857, #4898
1.3.9
Released: October 4, 2019
orm
- [orm] [bug]
Fixed regression in selectinload loader strategy caused by #4775(released in version 1.3.6) where a many-to-one attribute of None would nolonger be populated by the loader. While this was usually not noticeabledue to the lazyloader populating None upon get, it would lead to a detachedinstance error if the object were detached.References: #4872
- [orm] [bug]
Passing a plain string expression to Session.query()
is deprecated,as all string coercions were removed in #4481 and this one shouldhave been included. The literal_column()
function may be used toproduce a textual column expression.References: #4873
- [orm] [bug]
A warning is emitted for a condition in which the Session
mayimplicitly swap an object out of the identity map for another one with thesame primary key, detaching the old one, which can be an observed result ofload operations which occur within the SessionEvents.after_flush()
hook. The warning is intended to notify the user that some specialcondition has caused this to happen and that the previous object may not bein the expected state.References: #4890
engine
- [engine] [usecase]
Added new create_engine()
parametercreate_engine.max_identifier_length
. This overrides thedialect-coded “max identifier length” in order to accommodate for databasesthat have recently changed this length and the SQLAlchemy dialect hasnot yet been adjusted to detect for that version. This parameter interactswith the existing create_engine.label_length
parameter in thatit establishes the maximum (and default) value for anonymously generatedlabels. Additionally, post-connection detection of max identifier lengthshas been added to the dialect system. This feature is first being usedby the Oracle dialect.
See also
Max Identifier Lengths - in the Oracle dialect documentation
References: #4857
sql
- [sql] [bug]
Characters that interfere with “pyformat” or “named” formats in boundparameters, namely %, (, )
and the space character, as well as a fewother typically undesirable characters, are stripped early for abindparam()
that is using an anonymized name, which is typicallygenerated automatically from a named column which itself includes thesecharacters in its name and does not use a .key
, so that they do notinterfere either with the SQLAlchemy compiler’s use of string formatting orwith the driver-level parsing of the parameter, both of which could bedemonstrated before the fix. The change only applies to anonymizedparameter names that are generated and consumed internally, not end-userdefined names, so the change should have no impact on any existing code.Applies in particular to the psycopg2 driver which does not otherwise quotespecial parameter names, but also strips leading underscores to suit Oracle(but not yet leading numbers, as some anon parameters are currentlyentirely numeric/underscore based); Oracle in any case continues to quoteparameter names that include special characters.References: #4837
- [sql] [usecase]
Added an explicit error message for the case when objects passed toTable
are not SchemaItem
objects, rather than resolvingto an attribute error.References: #4847
sqlite
- [sqlite] [usecase]
Added support for sqlite “URI” connections, which allow for sqlite-specificflags to be passed in the query string such as “read only” for Pythonsqlite3 drivers that support this.
See also
References: #4863
mssql
- [mssql] [bug]
Added identifier quoting to the schema name applied to the “use” statementwhich is invoked when a SQL Server multipart schema name is used within aTable
that is being reflected, as well as for Inspector
methods such as Inspector.get_table_names()
; this accommodates forspecial characters or spaces in the database name. Additionally, the “use”statement is not emitted if the current database matches the target ownerdatabase name being passed.References: #4883
oracle
- [oracle] [bug]
Restored adding cx_Oracle.DATETIME to the setinputsizes() call when aSQLAlchemy Date
, DateTime
or Time
datatype isused, as some complex queries require this to be present. This was removedin the 1.2 series for arbitrary reasons.References: #4886
- [oracle] [usecase]
The Oracle dialect now emits a warning if Oracle version 12.2 or greater isused, and the create_engine.max_identifier_length
parameter isnot set. The version in this specific case defaults to that of the“compatibility” version set in the Oracle server configuration, not theactual server version. In version 1.4, the default max_identifier_lengthfor 12.2 or greater will move to 128 characters. In order to maintainforwards compatibility, applications should setcreate_engine.max_identifier_length
to 30 in order to maintainthe same length behavior, or to 128 in order to test the upcoming behavior.This length determines among other things how generated constraint namesare truncated for statements like CREATE CONSTRAINT
and DROPCONSTRAINT
, which means a the new length may produce a name-mismatchagainst a name that was generated with the old length, impacting databasemigrations.
See also
Max Identifier Lengths - in the Oracle dialect documentation
References: #4857
misc
- [bug] [tests]
Fixed unit test regression released in 1.3.8 that would cause failure forOracle, SQL Server and other non-native ENUM platforms due to newenumeration tests added as part of #4285 enum sortability in theunit of work; the enumerations created constraints that were duplicated onname.References: #4285
1.3.8
Released: August 27, 2019
orm
- [orm] [bug]
Fixed bug where Load
objects were not pickleable due tomapper/relationship state in the internal context dictionary. Theseobjects are now converted to picklable using similar techniques as that ofother elements within the loader option system that have long beenserializable.References: #4823
- [orm] [usecase]
Added support for the use of an Enum
datatype using Pythonpep-435 enumeration objects as values for use as a primary key columnmapped by the ORM. As these values are not inherently sortable, asrequired by the ORM for primary keys, a newTypeEngine.sort_key_function
attribute is added to the typingsystem which allows any SQL type to implement a sorting for Python objectsof its type which is consulted by the unit of work. The Enum
type then defines this using the database value of a given enumeration.The sorting scheme can be also be redefined by passing a callable to theEnum.sort_key_function
parameter. Pull request courtesyNicolas Caniart.References: #4285
engine
- [engine] [feature]
Added new parameter create_engine.hide_parameters
which whenset to True will cause SQL parameters to no longer be logged, nor renderedin the string representation of a StatementError
object.References: #4815
- [engine] [bug]
Fixed an issue whereby if the dialect “initialize” process which occurs onfirst connect would encounter an unexpected exception, the initializeprocess would fail to complete and then no longer attempt on subsequentconnection attempts, leaving the dialect in an un-initialized, or partiallyinitialized state, within the scope of parameters that need to beestablished based on inspection of a live connection. The “invoke once”logic in the event system has been reworked to accommodate for thisoccurrence using new, private API features that establish an “exec once”hook that will continue to allow the initializer to fire off on subsequentconnections, until it completes without raising an exception. This does notimpact the behavior of the existing once=True
flag within the eventsystem.References: #4807
postgresql
- [postgresql] [bug]
Revised the approach for the just added support for the psycopg2“execute_values()” feature added in 1.3.7 for #4623. The approachrelied upon a regular expression that would fail to match for a morecomplex INSERT statement such as one which had subqueries involved. Thenew approach matches exactly the string that was rendered as the VALUESclause.References: #4623
- [postgresql] [bug]
Fixed bug where Postgresql operators such aspostgresql.ARRAY.Comparator.contains()
andpostgresql.ARRAY.Comparator.contained_by()
would fail to functioncorrectly for non-integer values when used against apostgresql.array
object, due to an erroneous assert statement.References: #4822
- [postgresql] [usecase]
Added support for reflection of CHECK constraints that include the specialPostgreSQL qualifier “NOT VALID”, which can be present for CHECKconstraints that were added to an exsiting table with the directive thatthey not be applied to existing data in the table. The PostgreSQLdictionary for CHECK constraints as returned byInspector.get_check_constraints()
may include an additional entrydialect_options
which within will contain an entry "not_valid":True
if this symbol is detected. Pull request courtesy Bill Finn.References: #4824
sqlite
- [sqlite] [bug] [reflection]
Fixed bug where a FOREIGN KEY that was set up to refer to the parent tableby table name only without the column names would not correctly bereflected as far as setting up the “referred columns”, since SQLite’sPRAGMA does not report on these columns if they weren’t given explicitly.For some reason this was harcoded to assume the name of the local column,which might work for some cases but is not correct. The new approachreflects the primary key of the referred table and uses the constraintcolumns list as the referred columns list, if the remote column(s) aren’tpresent in the reflected pragma directly.References: #4810
1.3.7
Released: August 14, 2019
orm
- [orm] [bug]
Fixed regression caused by new selectinload for many-to-one logic wherea primaryjoin condition not based on real foreign keys would causeKeyError if a related object did not exist for a given key value on theparent object.References: #4777
- [orm] [bug]
Fixed bug where using Query.first()
or a slice expression inconjunction with a query that has an expression based “offset” appliedwould raise TypeError, due to an “or” conditional against “offset” that didnot expect it to be a SQL expression as opposed to an integer or None.References: #4803
sql
- [sql] [bug]
Fixed issue where Index
object which contained a mixture offunctional expressions which were not resolvable to a particular column,in combination with string-based column names, would fail to initializeits internal state correctly leading to failures during DDL compilation.References: #4778
- [sql] [bug]
Fixed bug where TypeEngine.column_expression()
method would not beapplied to subsequent SELECT statements inside of a UNION or otherCompoundSelect
, even though the SELECT statements are rendered atthe topmost level of the statement. New logic now differentiates betweenrendering the column expression, which is needed for all SELECTs in thelist, vs. gathering the returned data type for the result row, which isneeded only for the first SELECT.References: #4787
- [sql] [bug]
Fixed issue where internal cloning of SELECT constructs could lead to a keyerror if the copy of the SELECT changed its state such that its list ofcolumns changed. This was observed to be occurring in some ORM scenarioswhich may be unique to 1.3 and above, so is partially a regression fix.References: #4780
postgresql
- [postgresql] [usecase]
Added new dialect flag for the psycopg2 dialect, executemany_mode
whichsupersedes the previous experimental use_batch_mode
flag.executemany_mode
supports both the “execute batch” and “execute values”functions provided by psycopg2, the latter which is used for compiledinsert()
constructs. Pull request courtesy Yuval Dinari.
See also
Psycopg2 Fast Execution Helpers
References: #4623
mysql
- [mysql] [bug]
The MySQL dialects will emit “SET NAMES” at the start of a connection whencharset is given to the MySQL driver, to appease an apparent behaviorobserved in MySQL 8.0 that raises a collation error when a UNION includesstring columns unioned against columns of the form CAST(NULL AS CHAR(..)),which is what SQLAlchemy’s polymorphic_union function does. The issueseems to have affected PyMySQL for at least a year, however has recentlyappeared as of mysqlclient 1.4.4 based on changes in how this DBAPI createsa connection. As the presence of this directive impacts three separateMySQL charset settings which each have intricate effects based on theirpresense, SQLAlchemy will now emit the directive on new connections toensure correct behavior.References: #4804
- [mysql] [bug]
Added another fix for an upstream MySQL 8 issue where a case sensitivetable name is reported incorrectly in foreign key constraint reflection,this is an extension of the fix first added for #4344 whichaffects a case sensitive column name. The new issue occurs through MySQL8.0.17, so the general logic of the 88718 fix remains in place.
See also
https://bugs.mysql.com/bug.php?id=96365 - upstream bug
References: #4751
- [mysql] [usecase]
Added reserved words ARRAY and MEMBER to the MySQL reserved words list, asMySQL 8.0 has now made these reserved.References: #4783
sqlite
- [sqlite] [bug]
The dialects that support json are supposed to take argumentsjson_serializer
and json_deserializer
at the create_engine() level,however the SQLite dialect calls them _json_serilizer
and_json_deserilalizer
. The names have been corrected, the old names areaccepted with a change warning, and these parameters are now documented ascreate_engine.json_serializer
andcreate_engine.json_deserializer
.References: #4798
- [sqlite] [bug]
Fixed bug where usage of “PRAGMA table_info” in SQLite dialect meant thatreflection features to detect for table existence, list of table columns,and list of foreign keys, would default to any table in any attacheddatabase, when no schema name was given and the table did not exist in thebase schema. The fix explicitly runs PRAGMA for the ‘main’ schema and thenthe ‘temp’ schema if the ‘main’ returned no rows, to maintain the behaviorof tables + temp tables in the “no schema” namespace, attached tables onlyin the “schema” namespace.References: #4793
mssql
- [mssql] [usecase]
Added new mssql.try_cast()
construct for SQL Server which emits“TRY_CAST” syntax. Pull request courtesy Leonel Atencio.References: #4782
misc
- [bug] [events]
Fixed issue in event system where using the once=True
flag withdynamically generated listener functions would cause event registration offuture events to fail if those listener functions were garbage collectedafter they were used, due to an assumption that a listened function isstrongly referenced. The “once” wrapped is now modified to stronglyreference the inner function persistently, and documentation is updatedthat using “once” does not imply automatic de-registration of listenerfunctions.References: #4794
1.3.6
Released: July 21, 2019
orm
- [orm] [feature]
Added new loader option method Load.options()
which allows loaderoptions to be constructed hierarchically, so that many sub-options can beapplied to a particular path without needing to call defaultload()
many times. Thanks to Alessio Bogon for the idea.References: #4736
- [orm] [bug]
Fixed regression caused by #4365 where a join from an entity toitself without using aliases no longer raises an informative error message,instead failing on an assertion. The informative error condition has beenrestored.References: #4773
- [orm] [bug]
Fixed an issue where the orm._ORMJoin.join()
method, which is anot-internally-used ORM-level method that exposes what is normally aninternal process of Query.join()
, did not propagate the full
andouterjoin
keyword arguments correctly. Pull request courtesy DenisKataev.References: #4713
- [orm] [bug]
Fixed bug where a many-to-one relationship that specified uselist=True
would fail to update correctly during a primary key change where a relatedcolumn needs to change.References: #4772
- [orm] [bug]
Fixed bug where the detection for many-to-one or one-to-one use with a“dynamic” relationship, which is an invalid configuration, would fail toraise if the relationship were configured with uselist=True
. Thecurrent fix is that it warns, instead of raises, as this would otherwise bebackwards incompatible, however in a future release it will be a raise.References: #4772
- [orm] [bug]
Fixed bug where a synonym created against a mapped attribute that does notexist yet, as is the case when it refers to backref before mappers areconfigured, would raise recursion errors when trying to test for attributeson it which ultimately don’t exist (as occurs when the classes are runthrough Sphinx autodoc), as the unconfigured state of the synonym would putit into an attribute not found loop.References: #4767
- [orm] [performance]
The optimization applied to selectin loading in #4340 where a JOINis not needed to eagerly load related items is now applied to many-to-onerelationships as well, so that only the related table is queried for asimple join condition. In this case, the related items are queriedbased on the value of a foreign key column on the parent; if these columnsare deferred or otherwise not loaded on any of the parent objects inthe collection, the loader falls back to the JOIN method.References: #4775
engine
- [engine] [bug]
Fixed bug where using reflection function such as MetaData.reflect()
with an Engine
object that had execution options applied to itwould fail, as the resulting OptionEngine
proxy object failed toinclude a .engine
attribute used within the reflection routines.References: #4754
sql
- [sql] [bug]
Adjusted the initialization for Enum
to minimize how often itinvokes the .members
attribute of a given PEP-435 enumerationobject, to suit the case where this attribute is expensive to invoke, as isthe case for some popular third party enumeration libraries.References: #4758
- [sql] [bug] [postgresql]
Fixed issue where the array_agg
construct in combination withFunctionElement.filter()
would not produce the correct operatorprecedence in combination with the array index operator.References: #4760
- [sql] [bug]
Fixed an unlikely issue where the “corresponding column” routine for unionsand other CompoundSelect
objects could return the wrong column insome overlapping column situtations, thus potentially impacting some ORMoperations when set operations are in use, if the underlyingselect()
constructs were used previously in other similar kinds ofroutines, due to a cached value not being cleared.References: #4747
postgresql
- [postgresql] [usecase]
Added support for reflection of indexes on PostgreSQL partitioned tables,which was added to PostgreSQL as of version 11.References: #4771
- [postgresql] [usecase]
Added support for multidimensional Postgresql array literals via nestingthe postgresql.array
object within another one. Themultidimensional array type is detected automatically.
See also
References: #4756
mysql
- [mysql] [bug]
Fixed bug where the special logic to render “NULL” for theTIMESTAMP
datatype when nullable=True
would not work if thecolumn’s datatype were a TypeDecorator
or a Variant
.The logic now ensures that it unwraps down to the originalTIMESTAMP
so that this special case NULL keyword is correctlyrendered when requested.References: #4743
- [mysql] [bug]
Enhanced MySQL/MariaDB version string parsing to accommodate for exoticMariaDB version strings where the “MariaDB” word is embedded among otheralphanumeric characters such as “MariaDBV1”. This detection is critical inorder to correctly accommodate for API features that have split between MySQLand MariaDB such as the “transaction_isolation” system variable.References: #4624
sqlite
- [sqlite] [usecase]
Added support for composite (tuple) IN operators with SQLite, by renderingthe VALUES keyword for this backend. As other backends such as DB2 areknown to use the same syntax, the syntax is enabled in the base compilerusing a dialect-level flag tuplein_values
. The change also includessupport for “empty IN tuple” expressions for SQLite when using “in()”between a tuple value and an empty set.References: #4766
mssql
- [mssql] [bug]
Ensured that the queries used to reflect indexes and view definitions willexplicitly CAST string parameters into NVARCHAR, as many SQL Server driversfrequently treat string values, particularly those with non-asciicharacters or larger string values, as TEXT which often don’t comparecorrectly against VARCHAR characters in SQL Server’s information schematables for some reason. These CAST operations already take place forreflection queries against SQL Server information_schema.
tables butwere missing from three additional queries that are against sys.
tables.References: #4745
1.3.5
Released: June 17, 2019
orm
- [orm] [bug]
Fixed a series of related bugs regarding joined table inheritance more thantwo levels deep, in conjunction with modification to primary key values,where those primary key columns are also linked together in a foreign keyrelationship as is typical for joined table inheritance. The intermediarytable in a three-level inheritance hierarchy will now get its UPDATE ifonly the primary key value has changed and passive_updates=False (e.g.foreign key constraints not being enforced), whereas before it would beskipped; similarly, with passive_updates=True (e.g. ON UPDATE CASCADE ineffect), the third-level table will not receive an UPDATE statement as wasthe case earlier which would fail since CASCADE already modified it. In arelated issue, a relationship linked to a three-level inheritance hierarchyon the primary key of an intermediary table of a joined-inheritancehierarchy will also correctly have its foreign key column updated when theparent object’s primary key is modified, even if that parent object is asubclass of the linked parent class, whereas before these classes wouldnot be counted.References: #4723
- [orm] [bug]
Fixed bug where the Mapper.all_orm_descriptors
accessor wouldreturn an entry for the Mapper
itself under the declarativemapper_
key, when this is not a descriptor. The .is_attribute
flag that’s present on all InspectionAttr
objects is nowconsulted, which has also been modified to be True
for an associationproxy, as it was erroneously set to False for this object.References: #4729
- [orm] [bug]
Fixed regression in Query.join()
where the aliased=True
flagwould not properly apply clause adaptation to filter criteria, if aprevious join were made to the same entity. This is because the adapterswere placed in the wrong order. The order has been reversed so that theadapter for the most recent aliased=True
call takes precedence as wasthe case in 1.2 and earlier. This broke the “elementtree” examples amongother things.References: #4704
- [orm] [bug] [py3k]
Replaced the Python compatbility routines for getfullargspec()
with afully vendored version from Python 3.3. Originally, Python was emittingdeprecation warnings for this function in Python 3.8 alphas. While thischange was reverted, it was observed that Python 3 implementations forgetfullargspec()
are an order of magnitude slower as of the 3.4 serieswhere it was rewritten against Signature
. While Python plans toimprove upon this situation, SQLAlchemy projects for now are using a simplereplacement to avoid any future issues.References: #4674
- [orm] [bug]
Reworked the attribute mechanics used by AliasedClass
to nolonger rely upon calling getattribute
on the MRO of the wrappedclass, and to instead resolve the attribute normally on the wrapped classusing getattr(), and then unwrap/adapt that. This allows a greater rangeof attribute styles on the mapped class including special getattr()
schemes; but it also makes the code simpler and more resilient in general.References: #4694
sql
- [sql] [bug]
Fixed a series of quoting issues which all stemmed from the concept of theliteral_column()
construct, which when being “proxied” through asubquery to be referred towards by a label that matches its text, the labelwould not have quoting rules applied to it, even if the string in theLabel
were set up as a quoted_name
construct. Notapplying quoting to the text of the Label
is a bug because thistext is strictly a SQL identifier name and not a SQL expression, and thestring should not have quotes embedded into it already unlike theliteral_column()
which it may be applied towards. The existingbehavior of a non-labeled literal_column()
being propagated as is onthe outside of a subquery is maintained in order to help with manualquoting schemes, although it’s not clear if valid SQL can be generated forsuch a construct in any case.References: #4730
postgresql
- [postgresql] [bug]
Fixed bug where PostgreSQL dialect could not correctly reflect an ENUMdatatype that has no members, returning a list with None
for theget_enums()
call and raising a TypeError when reflecting a column whichhas such a datatype. The inspection now returns an empty list.References: #4701
- [postgresql] [usecase]
Added support for column sorting flags when reflecting indexes forPostgreSQL, including ASC, DESC, NULLSFIRST, NULLSLAST. Also adds thisfacility to the reflection system in general which can be applied to otherdialects in future releases. Pull request courtesy Eli Collins.References: #4717
mysql
- [mysql] [bug]
Fixed bug where MySQL ON DUPLICATE KEY UPDATE would not accommodate settinga column to the value NULL. Pull request courtesy Lukáš Banič.References: #4715
1.3.4
Released: May 27, 2019
orm
- [orm] [bug]
Fixed issue where the AttributeEvents.active_history
flagwould not be set for an event listener that propgated to a subclass via theAttributeEvents.propagate
flag. This bug has been presentfor the full span of the AttributeEvents
system.References: #4695
- [orm] [bug]
Fixed regression where new association proxy system was still not proxyinghybrid attributes when they made use of the @hybrid_property.expression
decorator to return an alternate SQL expression, or when the hybridreturned an arbitrary PropComparator
, at the expression level.This involved further generalization of the heuristics used to detect thetype of object being proxied at the level of QueryableAttribute
,to better detect if the descriptor ultimately serves mapped classes orcolumn expressions.References: #4690
- [orm] [bug]
Applied the mapper “configure mutex” against the declarative class mappingprocess, to guard against the race which can occur if mappers are usedwhile dynamic module import schemes are still in the process of configuringmappers for related classes. This does not guard against all possible raceconditions, such as if the concurrent import has not yet encountered thedependent classes as of yet, however it guards against as much as possiblewithin the SQLAlchemy declarative process.References: #4686
- [orm] [bug]
A warning is now emitted for the case where a transient object is beingmerged into the session with Session.merge()
when that object isalready transient in the Session
. This warns for the case wherethe object would normally be double-inserted.References: #4647
- [orm] [bug]
Fixed regression in new relationship m2o comparison logic first introducedat Improvement to the behavior of many-to-one query expressions when comparing to an attribute that is persisted asNULL and is in an un-fetched state in the mapped instance. Since theattribute has no explicit default, it needs to default to NULL whenaccessed in a persistent setting.References: #4676
engine
- [engine] [bug] [postgresql]
Moved the “rollback” which occurs during dialect initialization so that itoccurs after additional dialect-specific initialize steps, in particularthose of the psycopg2 dialect which would inadvertently leave transactionalstate on the first new connection, which could interfere with somepsycopg2-specific APIs which require that no transaction is started. Pullrequest courtesy Matthew Wilkes.References: #4663
sql
- [sql] [bug]
Fixed that the GenericFunction
class was inadvertentlyregistering itself as one of the named functions. Pull request courtesyAdrien Berchet.References: #4653
- [sql] [bug]
Fixed issue where double negation of a boolean column wouldn’t resetthe “NOT” operator.References: #4618
- [sql] [bug]
The GenericFunction
namespace is being migrated so that functionnames are looked up in a case-insensitive manner, as SQL functions do notcollide on case sensitive differences nor is this something which wouldoccur with user-defined functions or stored procedures. Lookups forfunctions declared with GenericFunction
now use a caseinsensitive scheme, however a deprecation case is supported which allowstwo or more GenericFunction
objects with the same name ofdifferent cases to exist, which will cause case sensitive lookups to occurfor that particular name, while emitting a warning at function registrationtime. Thanks to Adrien Berchet for a lot of work on this complicatedfeature.References: #4569
postgresql
- [postgresql] [bug] [orm]
Fixed an issue where the “number of rows matched” warning would emit even ifthe dialect reported “supports_sane_multi_rowcount=False”, as is the casefor psycogp2 with use_batch_mode=True
and others.References: #4661
mysql
- [mysql] [bug]
Added support for DROP CHECK constraint which is required by MySQL 8.0.16to drop a CHECK constraint; MariaDB supports plain DROP CONSTRAINT. Thelogic distinguishes between the two syntaxes by checking the server versionstring for MariaDB presence. Alembic migrations has already workedaround this issue by implementing its own DROP for MySQL / MariaDB CHECKconstraints, however this change implements it straight in Core so that itsavailable for general use. Pull request courtesy Hannes Hansen.References: #4650
mssql
- [mssql] [feature]
Added support for SQL Server filtered indexes, via the mssql_where
parameter which works similarly to that of the postgresql_where
indexfunction in the PostgreSQL dialect.
See also
References: #4657
- [mssql] [bug]
Added error code 20047 to “is_disconnect” for pymssql. Pull requestcourtesy Jon Schuff.References: #4680
misc
- [misc] [bug]
Removed errant “sqla_nose.py” symbol from MANIFEST.in which created anundesirable warning message.References: #4625
1.3.3
Released: April 15, 2019
orm
- [orm] [bug]
Fixed 1.3 regression in new “ambiguous FROMs” query logic introduced inQuery.join() handles ambiguity in deciding the “left” side more explicitly where a Query
that explicitly places an entityin the FROM clause with Query.select_from()
and also joins to itusing Query.join()
would later cause an “ambiguous FROM” error ifthat entity were used in additional joins, as the entity appears twice inthe “from” list of the Query
. The fix resolves this ambiguity byfolding the standalone entity into the join that it’s already a part of inthe same way that ultimately happens when the SELECT statement is rendered.References: #4584
- [orm] [bug]
Adjusted the Query.filter_by()
method to not call and()
internally against multiple criteria, instead passing it off toQuery.filter()
as a series of criteria, instead of a single criteria.This allows Query.filter_by()
to defer to Query.filter()
’streatment of variable numbers of clauses, including the case where the listis empty. In this case, the Query
object will not have a.whereclause
, which allows subsequent “no whereclause” methods likeQuery.select_from()
to behave consistently.References: #4606
postgresql
- [postgresql] [bug]
Fixed regression from release 1.3.2 caused by #4562 where a URLthat contained only a query string and no hostname, such as for thepurposes of specifying a service file with connection information, would nolonger be propagated to psycopg2 properly. The change in #4562has been adjusted to further suit psycopg2’s exact requirements, which isthat if there are any connection parameters whatsoever, the “dsn” parameteris no longer required, so in this case the query string parameters arepassed alone.References: #4601
mssql
- [mssql] [bug]
Fixed issue in SQL Server dialect where if a bound parameter were present inan ORDER BY expression that would ultimately not be rendered in the SQLServer version of the statement, the parameters would still be part of theexecution parameters, leading to DBAPI-level errors. Pull request courtesyMatt Lewellyn.References: #4587
misc
- [bug] [pool]
Fixed behavioral regression as a result of deprecating the “use_threadlocal”flag for Pool
, where the SingletonThreadPool
no longermakes use of this option which causes the “rollback on return” logic to takeplace when the same Engine
is used multiple times in the contextof a transaction to connect or implicitly execute, thereby cancelling thetransaction. While this is not the recommended way to work with enginesand connections, it is nonetheless a confusing behavioral change as whenusing SingletonThreadPool
, the transaction should stay openregardless of what else is done with the same engine in the same thread.The use_threadlocal
flag remains deprecated however theSingletonThreadPool
now implements its own version of the samelogic.References: #4585
- [bug] [ext]
Fixed bug where using copy.copy()
or copy.deepcopy()
onMutableList
would cause the items within the list to beduplicated, due to an inconsistency in how Python pickle and copy both makeuse of getstate()
and setstate()
regarding lists. In orderto resolve, a reduce_ex
method had to be added toMutableList
. In order to maintain backwards compatibility withexisting pickles based on getstate()
, the setstate()
methodremains as well; the test suite asserts that pickles made against the oldversion of the class can still be deserialized by the pickle module.References: #4603
1.3.2
Released: April 2, 2019
orm
- [orm] [bug] [ext]
Restored instance-level support for plain Python descriptors, e.g.@property
objects, in conjunction with association proxies, in that ifthe proxied object is not within ORM scope at all, it gets classified as“ambiguous” but is proxed directly. For class level access, a basic classlevel__get__()
now returns theAmbiguousAssociationProxyInstance
directly, rather than raisingits exception, which is the closest approximation to the previous behaviorthat returned the AssociationProxy
itself that’s possible. Alsoimproved the stringification of these objects to be more descriptive ofcurrent state.References: #4573, #4574
- [orm] [bug]
Fixed bug where use of with_polymorphic()
or other aliased constructwould not properly adapt when the aliased target were used as theSelect.correlate_except()
target of a subquery used inside of acolumn_property()
. This required a fix to the clause adaptionmechanics to properly handle a selectable that shows up in the “correlateexcept” list, in a similar manner as which occurs for selectables that showup in the “correlate” list. This is ultimately a fairly fundamental bugthat has lasted for a long time but it is hard to come across it.References: #4537
- [orm] [bug]
Fixed regression where a new error message that was supposed to raise whenattempting to link a relationship option to an AliasedClass without usingPropComparator.of_type()
would instead raise an AttributeError
.Note that in 1.3, it is no longer valid to create an option path from aplain mapper relationship to an AliasedClass
without usingPropComparator.of_type()
.References: #4566
sql
- [sql] [bug] [documentation]
Thanks to TypeEngine methods bind_expression, column_expression work with Variant, type-specific types, we no longer need to rely on recipes thatsubclass dialect-specific types directly, TypeDecorator
can nowhandle all cases. Additionally, the above change made it slightly lesslikely that a direct subclass of a base SQLAlchemy type would work asexpected, which could be misleading. Documentation has been updated to useTypeDecorator
for these examples including the PostgreSQL“ArrayOfEnum” example datatype and direct support for the “subclass a typedirectly” has been removed.References: #4580
postgresql
- [postgresql] [feature]
Added support for parameter-less connection URLs for the psycopg2 dialect,meaning, the URL can be passed to create_engine()
as"postgresql+psycopg2://"
with no additional arguments to indicate anempty DSN passed to libpq, which indicates to connect to “localhost” withno username, password, or database given. Pull request courtesy JulianMehnle.References: #4562
- [postgresql] [bug]
Modified the Select.with_for_update.of
parameter so that if ajoin or other composed selectable is passed, the individual Table
objects will be filtered from it, allowing one to pass a join() object tothe parameter, as occurs normally when using joined table inheritance withthe ORM. Pull request courtesy Raymond Lu.References: #4550
1.3.1
Released: March 9, 2019
orm
- [orm] [bug] [ext]
Fixed regression where an association proxy linked to a synonym would nolonger work, both at instance level and at class level.References: #4522
mssql
- [mssql] [bug]
A commit() is emitted after an isolation level change to SNAPSHOT, as bothpyodbc and pymssql open an implicit transaction which blocks subsequent SQLfrom being emitted in the current transaction.This change is also backported to: 1.2.19
References: #4536
- [mssql] [bug]
Fixed regression in SQL Server reflection due to #4393 where theremoval of open-ended **kw
from the Float
datatype causedreflection of this type to fail due to a “scale” argument being passed.References: #4525
1.3.0
Released: March 4, 2019
orm
- [orm] [feature]
The Query.get()
method can now accept a dictionary of attribute keysand values as a means of indicating the primary key value to load; isparticularly useful for composite primary keys. Pull request courtesySanjana S.References: #4316
- [orm] [feature]
A SQL expression can now be assigned to a primary key attribute for an ORMflush in the same manner as ordinary attributes as described inEmbedding SQL Insert/Update Expressions into a Flush where the expression will be evaulatedand then returned to the ORM using RETURNING, or in the case of pysqlite,works using the cursor.lastrowid attribute.Requires either a database thatsupports RETURNING (e.g. Postgresql, Oracle, SQL Server) or pysqlite.References: #3133
engine
- [engine] [feature]
Revised the formatting for StatementError
when stringified. Eacherror detail is broken up over multiple newlines instead of spaced out on asingle line. Additionally, the SQL representation now stringifies the SQLstatement rather than using repr()
, so that newlines are rendered as is.Pull request courtesy Nate Clark.
See also
Changed StatementError formatting (newlines and %s)
References: #4500
sql
- [sql] [bug]
The Alias
class and related subclasses CTE
,Lateral
and TableSample
have been reworked so that it isnot possible for a user to construct the objects directly. These constructsrequire that the standalone construction function or selectable-bound methodbe used to instantiate new objects.References: #4509
schema
- [schema] [feature]
Added new parameters Table.resolve_fks
andMetaData.reflect.resolve_fks
which when set to False willdisable the automatic reflection of related tables encountered inForeignKey
objects, which can both reduce SQL overhead for omittedtables as well as avoid tables that can’t be reflected for database-specificreasons. Two Table
objects present in the same MetaData
collection can still refer to each other even if the reflection of the twotables occurred separately.References: #4517
1.3.0b3
Released: February 8, 2019
orm
- [orm] [bug]
Improved the behavior of orm.with_polymorphic()
in conjunction withloader options, in particular wildcard operations as well asorm.load_only()
. The polymorphic object will be more accuratelytargeted so that column-level options on the entity will correctly takeeffect.The issue is a continuation of the same kinds of things fixed in#4468.References: #4469
orm declarative
- [bug] [declarative] [orm]
Added some helper exceptions that invoke when a mapping based onAbstractConcreteBase
, DeferredReflection
, orAutoMap
is used before the mapping is ready to be used, whichcontain descriptive information on the class, rather than falling throughinto other failure modes that are less informative.References: #4470
sql
- [sql] [bug]
Fully removed the behavior of strings passed directly as components of aselect()
or Query
object being coerced to text()
constructs automatically; the warning that has been emitted is now anArgumentError or in the case of order_by() / group_by() a CompileError.This has emitted a warning since version 1.0 however its presence continuesto create concerns for the potential of mis-use of this behavior.
Note that public CVEs have been posted for order_by() / group_by() whichare resolved by this commit: CVE-2019-7164 CVE-2019-7548
See also
Coercion of string SQL fragments to text() fully removed
References: #4481
- [sql] [bug]
Quoting is applied to Function
names, those which are usually butnot necessarily generated from the sql.func
construct, at compiletime if they contain illegal characters, such as spaces or punctuation. Thenames are as before treated as case insensitive however, meaning if thenames contain uppercase or mixed case characters, that alone does nottrigger quoting. The case insensitivity is currently maintained forbackwards compatibility.References: #4467
- [sql] [bug]
Added “SQL phrase validation” to key DDL phrases that are accepted as plainstrings, including ForeignKeyConstraint.on_delete
,ForeignKeyConstraint.on_update
,ExcludeConstraint.using
,ForeignKeyConstraint.initially
, for areas where a series of SQLkeywords only are expected.Any non-space characters that suggest the phrasewould need to be quoted will raise a CompileError
. This changeis related to the series of changes committed as part of #4481.References: #4481
postgresql
- [postgresql] [bug]
Fixed issue where using an uppercase name for an index type (e.g. GIST,BTREE, etc. ) or an EXCLUDE constraint would treat it as an identifier tobe quoted, rather than rendering it as is. The new behavior converts thesetypes to lowercase and ensures they contain only valid SQL characters.References: #4473
misc
- [bug] [ext]
Implemented a more comprehensive assignment operation (e.g. “bulk replace”)when using association proxy with sets or dictionaries. Fixes the problemof redundant proxy objects being created to replace the old ones, whichleads to excessive events and SQL and in the case of unique constraintswill cause the flush to fail.
See also
Implemented bulk replace for sets, dicts with AssociationProxy
References: #2642
- [change] [tests]
The test system has removed support for Nose, which is unmaintained forseveral years and is producing warnings under Python 3. The test suite iscurrently standardized on Pytest. Pull request courtesy Parth Shandilya.References: #4460
1.3.0b2
Released: January 25, 2019
general
- [general] [change]
A large change throughout the library has ensured that all objects,parameters, and behaviors which have been noted as deprecated or legacy nowemit DeprecationWarning
warnings when invoked.As the Python 3interpreter now defaults to displaying deprecation warnings, as well as thatmodern test suites based on tools like tox and pytest tend to displaydeprecation warnings, this change should make it easier to note what APIfeatures are obsolete. A major rationale for this change is so that long-deprecated features that nonetheless still see continue to see real worlduse can finally be removed in the near future; the biggest example of thisare the SessionExtension
and MapperExtension
classes aswell as a handful of other pre-event extension hooks, which have beendeprecated since version 0.7 but still remain in the library. Another isthat several major longstanding behaviors are to be deprecated as well,including the threadlocal engine strategy, the convert_unicode flag, and nonprimary mappers.
See also
Deprecation warnings are emitted for all deprecated elements; new deprecations added
References: #4393
orm
- [orm] [feature]
Implemented a new feature whereby the AliasedClass
construct cannow be used as the target of a relationship()
. This allows theconcept of “non primary mappers” to no longer be necessary, as theAliasedClass
is much easier to configure and automatically inheritsall the relationships of the mapped class, as well as preserves theability for loader options to work normally.
See also
Relationship to AliasedClass replaces the need for non primary mappers
References: #4423
- [orm] [feature]
Added new MapperEvents.before_mapper_configured()
event. Thisevent complements the other “configure” stage mapper events with a permapper event that receives each Mapper
right before itsconfigure step, and additionally may be used to prevent or delay theconfiguration of specific Mapper
objects using a newreturn value orm.interfaces.EXT_SKIP
. See thedocumentation link for an example.
See also
MapperEvents.before_mapper_configured()
References: #4397
- [orm] [bug]
Fixed long-standing issue where duplicate collection members would cause abackref to delete the association between the member and its parent objectwhen one of the duplicates were removed, as occurs as a side effect ofswapping two objects in one statement.
See also
Many-to-one backref checks for collection duplicates during remove operation
References: #1103
- [orm] [bug]
Extended the fix first made as part of #3287, where a loader optionmade against a subclass using a wildcard would extend itself to includeapplication of the wildcard to attributes on the super classes as well, to a“bound” loader option as well, e.g. in an expression likeLoad(SomeSubClass).load_only('foo')
. Columns that are part of theparent class of SomeSubClass
will also be excluded in the same way as ifthe unbound option load_only('foo')
were used.References: #4373
- [orm] [bug]
Improved error messages emitted by the ORM in the area of loader optiontraversal. This includes early detection of mis-matched loader strategiesalong with a clearer explanation why these strategies don’t match.References: #4433
- [orm] [bug]
The “remove” event for collections is now called before the item is removedin the case of the collection.remove()
method, as is consistent with thebehavior for most other forms of collection item removal (such asdelitem
, replacement under setitem
). For pop()
methods,the remove event still fires after the operation.
- [orm] [bug] [engine]
Added accessors for execution options to Core and ORM, viaQuery.get_execution_options()
,Connection.get_execution_options()
,Engine.get_execution_options()
, andExecutable.get_execution_options()
. PR courtesy Daniel Lister.References: #4464
- [orm] [bug]
Fixed issue in association proxy due to #3423 which caused the useof custom PropComparator
objects with hybrid attributes, such asthe one demonstrated in the dictlike-polymorphic
example to notfunction within an association proxy. The strictness that was added in#3423 has been relaxed, and additional logic to accommodate foran association proxy that links to a custom hybrid have been added.References: #4446
- [orm] [bug]
Implemented the .get_history()
method, which also implies availabilityof AttributeState.history
, for synonym()
attributes.Previously, trying to access attribute history via a synonym would raise anAttributeError
.References: #3777
- [orm] [change]
Added a new function close_all_sessions()
which takesover the task of the Session.close_all()
method, whichis now deprecated as this is confusing as a classmethod.Pull request courtesy Augustin Trancart.References: #4412
orm declarative
- [orm declarative] [bug]
Added a clause_element()
method to ColumnProperty
whichcan allow the usage of a not-fully-declared column or deferred attribute ina declarative mapped class slightly more friendly when it’s used in aconstraint or other column-oriented scenario within the class declaration,though this still can’t work in open-ended expressions; prefer to call theColumnProperty.expression
attribute if receiving TypeError
.References: #4372
engine
- [engine] [feature]
Added public accessor QueuePool.timeout()
that returns the configuredtimeout for a QueuePool
object. Pull request courtesy Irina Delamare.References: #3689
- [engine] [change]
The “threadlocal” engine strategy which has been a legacy feature ofSQLAlchemy since around version 0.2 is now deprecated, along with thePool.threadlocal
parameter of Pool
which has noeffect in most modern use cases.
See also
“threadlocal” engine strategy deprecated
References: #4393
sql
- [sql] [feature]
Amended the AnsiFunction
class, the base of common SQLfunctions like CURRENT_TIMESTAMP
, to accept positional argumentslike a regular ad-hoc function. This to suit the case that many ofthese functions on specific backends accept arguments such as“fractional seconds” precision and such. If the function is createdwith arguments, it renders the parenthesis and the arguments. Ifno arguments are present, the compiler generates the non-parenthesized form.References: #4386
- [sql] [change]
The create_engine.convert_unicode
andString.convert_unicode
parameters have been deprecated. Theseparameters were built back when most Python DBAPIs had little to no supportfor Python Unicode objects, and SQLAlchemy needed to take on the verycomplex task of marshalling data and SQL strings between Unicode andbytestrings throughout the system in a performant way. Thanks to Python 3,DBAPIs were compelled to adapt to Unicode-aware APIs and today all DBAPIssupported by SQLAlchemy support Unicode natively, including on Python 2,allowing this long-lived and very complicated feature to finally be (mostly)removed. There are still of course a few Python 2 edge cases whereSQLAlchemy has to deal with Unicode however these are handled automatically;in modern use, there should be no need for end-user interaction with theseflags.
See also
convert_unicode parameters deprecated
References: #4393
mssql
- [mssql] [bug]
The literal_processor
for the Unicode
andUnicodeText
datatypes now render an N
character in front ofthe literal string expression as required by SQL Server for Unicode stringvalues rendered in SQL expressions.References: #4442
misc
- [bug] [ext]
Fixed a regression in 1.3.0b1 caused by #3423 where associationproxy objects that access an attribute that’s only present on a polymorphicsubclass would raise an AttributeError
even though the actual instancebeing accessed was an instance of that subclass.References: #4401
1.3.0b1
Released: November 16, 2018
orm
- [orm] [feature]
Added new feature Query.only_return_tuples()
. Causes theQuery
object to return keyed tuple objects unconditionally evenif the query is against a single entity. Pull request courtesy EricAtkin.This change is also backported to: 1.2.5
- [orm] [feature]
Added new flag Session.bulk_save_objects.preserve_order
to theSession.bulk_save_objects()
method, which defaults to True. When setto False, the given mappings will be grouped into inserts and updates pereach object type, to allow for greater opportunities to batch commonoperations together. Pull request courtesy Alessandro Cucci.
- [orm] [feature]
The “selectin” loader strategy now omits the JOIN in the case of a simpleone-to-many load, where it instead relies loads only from the relatedtable, relying upon the foreign key columns of the related table in orderto match up to primary keys in the parent table. This optimization can bedisabled by setting the relationship.omit_join
flag to False.Many thanks to Jayson Reis for the efforts on this.
See also
selectin loading no longer uses JOIN for simple one-to-many
References: #4340
- [orm] [feature]
Added .info
dictionary to the InstanceState
class, the objectthat comes from calling inspect()
on a mapped object.
See also
info dictionary added to InstanceState
References: #4257
- [orm] [bug]
Fixed bug where use of Lateral
construct in conjunction withQuery.join()
as well as Query.select_entity_from()
would notapply clause adaption to the right side of the join. “lateral” introducesthe use case of the right side of a join being correlatable. Previously,adaptation of this clause wasn’t considered. Note that in 1.2 only,a selectable introduced by Query.subquery()
is still not adapteddue to #4304; the selectable needs to be produced by theselect()
function to be the right side of the “lateral” join.This change is also backported to: 1.2.12
References: #4334
- [orm] [bug]
Fixed issue regarding passive_deletes=”all”, where the foreign keyattribute of an object is maintained with its value even after the objectis removed from its parent collection. Previously, the unit of work wouldset this to NULL even though passive_deletes indicated it should not bemodified.
See also
passive_deletes=’all’ will leave FK unchanged for object removed from collection
References: #3844
- [orm] [bug]
Improved the behavior of a relationship-bound many-to-one object expressionsuch that the retrieval of column values on the related object are nowresilient against the object being detached from its parentSession
, even if the attribute has been expired. New featureswithin the InstanceState
are used to memoize the last known valueof a particular column attribute before its expired, so that the expressioncan still evaluate when the object is detached and expired at the sametime. Error conditions are also improved using modern attribute statefeatures to produce more specific messages as needed.
See also
Improvement to the behavior of many-to-one query expressions
References: #4359
- [orm] [bug] [mysql] [postgresql]
The ORM now doubles the “FOR UPDATE” clause within the subquery thatrenders in conjunction with joined eager loading in some cases, as it hasbeen observed that MySQL does not lock the rows from a subquery. Thismeans the query renders with two FOR UPDATE clauses; note that on somebackends such as Oracle, FOR UPDATE clauses on subqueries are silentlyignored since they are unnecessary. Additionally, in the case of the “OF”clause used primarily with PostgreSQL, the FOR UPDATE is rendered only onthe inner subquery when this is used so that the selectable can be targetedto the table within the SELECT statement.
See also
FOR UPDATE clause is rendered within the joined eager load subquery as well as outside
References: #4246
- [orm] [bug]
Refactored Query.join()
to further clarify the individual componentsof structuring the join. This refactor adds the ability forQuery.join()
to determine the most appropriate “left” side of thejoin when there is more than one element in the FROM list or the query isagainst multiple entities. If more than one FROM/entity matches, an erroris raised that asks for an ON clause to be specified to resolve theambiguity. In particular this targets the regression we saw in#4363 but is also of general use. The codepaths withinQuery.join()
are now easier to follow and the error cases aredecided more specifically at an earlier point in the operation.
See also
Query.join() handles ambiguity in deciding the “left” side more explicitly
References: #4365
- [orm] [bug]
Fixed long-standing issue in Query
where a scalar subquery suchas produced by Query.exists()
, Query.as_scalar()
and otherderivations from Query.statement
would not correctly be adaptedwhen used in a new Query
that required entity adaptation, such aswhen the query were turned into a union, or a from_self(), etc. The changeremoves the “no adaptation” annotation from the select()
objectproduced by the Query.statement
accessor.References: #4304
- [orm] [bug]
An informative exception is re-raised when a primary key value is notsortable in Python during an ORM flush under Python 3, such as an Enum
that has no lt()
method; normally Python 3 raises a TypeError
in this case. The flush process sorts persistent objects by primary keyin Python so the values must be sortable.References: #4232
- [orm] [bug]
Removed the collection converter used by the MappedCollection
class. This converter was used only to assert that the incoming dictionarykeys matched that of their corresponding objects, and only during a bulk setoperation. The converter can interfere with a custom validator orAttributeEvents.bulk_replace()
listener that wants to convertincoming values further. The TypeError
which would be raised by thisconverter when an incoming key didn’t match the value is removed; incomingvalues during a bulk assignment will be keyed to their value-generated key,and not the key that’s explicitly present in the dictionary.
Overall, @converter is superseded by theAttributeEvents.bulk_replace()
event handler added as part of#3896.References: #3604
- [orm] [bug]
Added new behavior to the lazy load that takes place when the “old” value ofa many-to-one is retrieved, such that exceptions which would be raised dueto either lazy="raise"
or a detached session error are skipped.
See also
Many-to-one replacement won’t raise for “raiseload” or detached for “old” object
References: #4353
- [orm] [bug]
A long-standing oversight in the ORM, the delete
method for a many-to-one relationship was non-functional, e.g. for an operation such as dela.b
. This is now implemented and is equivalent to setting the attributeto None
.
See also
“del” implemented for ORM attributes
References: #4354
orm declarative
- [bug] [declarative] [orm]
Fixed bug where declarative would not update the state of theMapper
as far as what attributes were present, when additionalattributes were added or removed after the mapper attribute collections hadalready been called and memoized. Additionally, a NotImplementedError
is now raised if a fully mapped attribute (e.g. column, relationship, etc.)is deleted from a class that is currently mapped, since the mapper will notfunction correctly if the attribute has been removed.References: #4133
engine
- [engine] [feature]
Added new “lifo” mode to QueuePool
, typically enabled by settingthe flag create_engine.pool_use_lifo
to True. “lifo” modemeans the same connection just checked in will be the first to be checkedout again, allowing excess connections to be cleaned up from the serverside during periods of the pool being only partially utilized. Pull requestcourtesy Taem Park.
See also
New last-in-first-out strategy for QueuePool
sql
- [sql] [feature]
Refactored SQLCompiler
to expose aSQLCompiler.group_by_clause()
method similar to theSQLCompiler.order_by_clause()
and SQLCompiler.limit_clause()
methods, which can be overridden by dialects to customize how GROUP BYrenders. Pull request courtesy Samuel Chou.This change is also backported to: 1.2.13
- [sql] [feature]
Added Sequence
to the “string SQL” system that will render ameaningful string expression ("<next sequence value: my_sequence>"
)when stringifying without a dialect a statement that includes a “sequencenextvalue” expression, rather than raising a compilation error.References: #4144
- [sql] [feature]
Added new naming convention tokens column_0N_name
, column_0_N_name
,etc., which will render the names / keys / labels for all columns referencedby a particular constraint in a sequence. In order to accommodate for thelength of such a naming convention, the SQL compiler’s auto-truncationfeature now applies itself to constraint names as well, which creates ashortened, deterministically generated name for the constraint that willapply to a target backend without going over the character limit of thatbackend.
The change also repairs two other issues. One is that the column_0_key
token wasn’t available even though this token was documented, the other wasthat the referred_column_0_name
token would inadvertently render the.key
and not the .name
of the column if these two values weredifferent.
See also
New multi-column naming convention tokens, long name truncation
References: #3989
- [sql] [feature]
Added new logic to the “expanding IN” bound parameter feature whereby ifthe given list is empty, a special “empty set” expression that is specificto different backends is generated, thus allowing IN expressions to befully dynamic including empty IN expressions.
See also
Expanding IN feature now supports empty lists
References: #4271
- [sql] [feature]
The Python builtin dir()
is now supported for a SQLAlchemy “properties”object, such as that of a Core columns collection (e.g. .c
),mapper.attrs
, etc. Allows iPython autocompletion to work as well.Pull request courtesy Uwe Korn.
- [sql] [feature]
Added new feature FunctionElement.as_comparison()
which allows a SQLfunction to act as a binary comparison operation that can work within theORM.
See also
Binary comparison interpretation for SQL functions
References: #3831
- [sql] [bug]
Added “like” based operators as “comparison” operators, includingColumnOperators.startswith()
ColumnOperators.endswith()
ColumnOperators.ilike()
ColumnOperators.notilike()
among manyothers, so that all of these operators can be the basis for an ORM“primaryjoin” condition.References: #4302
- [sql] [bug]
Fixed issue with TypeEngine.bind_expression()
andTypeEngine.column_expression()
methods where these methods would notwork if the target type were part of a Variant
, or other targettype of a TypeDecorator
. Additionally, the SQL compiler nowcalls upon the dialect-level implementation when it renders these methodsso that dialects can now provide for SQL-level processing for built-intypes.
See also
TypeEngine methods bind_expression, column_expression work with Variant, type-specific types
References: #3981
postgresql
- [postgresql] [feature]
Added new PG type postgresql.REGCLASS
which assists in castingtable names to OID values. Pull request courtesy Sebastian Bank.This change is also backported to: 1.2.7
References: #4160
- [postgresql] [feature]
Added rudimental support for reflection of PostgreSQLpartitioned tables, e.g. that relkind=’p’ is added to reflectionqueries that return table information.
See also
Added basic reflection support for PostgreSQL partitioned tables
References: #4237
mysql
- [mysql] [feature]
Support added for the “WITH PARSER” syntax of CREATE FULLTEXT INDEXin MySQL, using the mysql_with_parser
keyword argument. Reflectionis also supported, which accommodates MySQL’s special comment formatfor reporting on this option as well. Additionally, the “FULLTEXT” and“SPATIAL” index prefixes are now reflected back into the mysql_prefix
index option.References: #4219
- [mysql] [feature]
Added support for the parameters in an ON DUPLICATE KEY UPDATE statement onMySQL to be ordered, since parameter order in a MySQL UPDATE clause issignificant, in a similar manner as that described atParameter-Ordered Updates. Pull request courtesy Maxim Bublis.
See also
Control of parameter ordering within ON DUPLICATE KEY UPDATE
- [mysql] [feature]
The “pre-ping” feature of the connection pool now usesthe ping()
method of the DBAPI connection in the case ofmysqlclient, PyMySQL and mysql-connector-python. Pull requestcourtesy Maxim Bublis.
See also
Protocol-level ping now used for pre-ping
sqlite
- [sqlite] [feature]
Added support for SQLite’s json functionality via the newSQLite implementation for types.JSON
, sqlite.JSON
.The name used for the type is JSON
, following an example found atSQLite’s own documentation. Pull request courtesy Ilja Everilä.
See also
References: #3850
- [sqlite] [feature]
Implemented the SQLite ON CONFLICT
clause as understood at the DDLlevel, e.g. for primary key, unique, and CHECK constraints as well asspecified on a Column
to satisfy inline primary key and NOT NULL.Pull request courtesy Denis Kataev.
See also
Support for SQLite ON CONFLICT in constraints added
References: #4360
mssql
- [mssql] [feature]
Added fast_executemany=True
parameter to the SQL Server pyodbc dialect,which enables use of pyodbc’s new performance feature of the same namewhen using Microsoft ODBC drivers.
See also
Support for pyodbc fast_executemany
References: #4158
- [mssql] [bug]
Deprecated the use of Sequence
with SQL Server in order to affectthe “start” and “increment” of the IDENTITY value, in favor of newparameters mssql_identity_start
and mssql_identity_increment
whichset these parameters directly. Sequence
will be used to generatereal CREATE SEQUENCE
DDL with SQL Server in a future release.
See also
New parameters to affect IDENTITY start and increment, use of Sequence deprecated
References: #4362
oracle
- [oracle] [feature]
Added a new event currently used only by the cx_Oracle dialect,DialectEvents.setiputsizes()
. The event passes a dictionary ofBindParameter
objects to DBAPI-specific type objects that will bepassed, after conversion to parameter names, to the cx_Oraclecursor.setinputsizes()
method. This allows both visibility into thesetinputsizes process as well as the ability to alter the behavior of whatdatatypes are passed to this method.
See also
Fine grained control over cx_Oracle data binding performance with setinputsizes
This change is also backported to: 1.2.9
References: #4290
- [oracle] [bug]
Updated the parameters that can be sent to the cx_Oracle DBAPI to both allowfor all current parameters as well as for future parameters not added yet.In addition, removed unused parameters that were deprecated in version 1.2,and additionally we are now defaulting “threaded” to False.
See also
cx_Oracle connect arguments modernized, deprecated parameters removed
References: #4369
- [oracle] [bug]
The Oracle dialect will no longer use the NCHAR/NCLOB datatypesrepresent generic unicode strings or clob fields in conjunction withUnicode
and UnicodeText
unless the flaguse_nchar_for_unicode=True
is passed to create_engine()
-this includes CREATE TABLE behavior as well as setinputsizes()
forbound parameters. On the read side, automatic Unicode conversion underPython 2 has been added to CHAR/VARCHAR/CLOB result rows, to match thebehavior of cx_Oracle under Python 3. In order to mitigate the performancehit under Python 2, SQLAlchemy’s very performant (when C extensionsare built) native Unicode handlers are used under Python 2.
See also
National char datatypes de-emphasized for generic unicode, re-enabled with option
References: #4242
misc
- [feature] [ext]
Added new attribute Query.lazy_loaded_from
which is populatedwith an InstanceState
that is using this Query
inorder to lazy load a relationship. The rationale for this is thatit serves as a hint for the horizontal sharding feature to use, such thatthe identity token of the state can be used as the default identity tokento use for the query within id_chooser().This change is also backported to: 1.2.9
References: #4243
- [feature] [ext]
Added new feature BakedQuery.to_query()
, which allows for aclean way of using one BakedQuery
as a subquery inside of anotherBakedQuery
without needing to refer explicitly to aSession
.References: #4318
- [feature] [ext]
The AssociationProxy
now has standard column comparison operationssuch as ColumnOperators.like()
andColumnOperators.startswith()
available when the target attribute is aplain column - the EXISTS expression that joins to the target table isrendered as usual, but the column expression is then use within the WHEREcriteria of the EXISTS. Note that this alters the behavior of the.contains()
method on the association proxy to make use ofColumnOperators.contains()
when used on a column-based attribute.
See also
AssociationProxy now provides standard column operators for a column-oriented target
References: #4351
- [feature] [ext]
Added support for bulk Query.update()
and Query.delete()
to the ShardedQuery
class within the horizontal shardingextension. This also adds an additional expansion hook to thebulk update/delete methods Query._execute_crud()
.
See also
Horizontal Sharding extension supports bulk update and delete methods
References: #4196
- [bug] [ext]
Reworked AssociationProxy
to store state that’s specific to aparent class in a separate object, so that a singleAssociationProxy
can serve for multiple parent classes, as isintrinsic to inheritance, without any ambiguity in the state returned by it.A new method AssociationProxy.for_class()
is added to allowinspection of class-specific state.
See also
AssociationProxy stores class-specific state on a per-class basis
References: #3423
- [bug] [ext]
The long-standing behavior of the association proxy collection maintainingonly a weak reference to the parent object is reverted; the proxy will nowmaintain a strong reference to the parent for as long as the proxycollection itself is also in memory, eliminating the “stale associationproxy” error. This change is being made on an experimental basis to see ifany use cases arise where it causes side effects.
See also
New Features and Improvements - Core
References: #4268
- [bug] [ext]
Fixed multiple issues regarding de-association of scalar objects with theassociation proxy. del
now works, and additionally a new flagAssociationProxy.cascade_scalar_deletes
is added, which whenset to True indicates that setting a scalar attribute to None
ordeleting via del
will also set the source association to None
.
See also
Association proxy has new cascade_scalar_deletes flag
References: #4308