.. changelog::
:version: 1.4.0b1
- :include_notes_from: unreleased_14
+ :released: November 2, 2020
+
+ .. change::
+ :tags: feature, orm
+ :tickets: 5159
+
+ The ORM can now generate queries previously only available when using
+ :class:`_orm.Query` using the :func:`_sql.select` construct directly.
+ A new system by which ORM "plugins" may establish themselves within a
+ Core :class:`_sql.Select` allow the majority of query building logic
+ previously inside of :class:`_orm.Query` to now take place within
+ a compilation-level extension for :class:`_sql.Select`. Similar changes
+ have been made for the :class:`_sql.Update` and :class:`_sql.Delete`
+ constructs as well. The constructs when invoked using :meth:`_orm.Session.execute`
+ now do ORM-related work within the method. For :class:`_sql.Select`,
+ the :class:`_engine.Result` object returned now contains ORM-level
+ entities and results.
+
+ .. seealso::
+
+ :ref:`change_5159`
+
+ .. change::
+ :tags: feature,sql
+ :tickets: 4737
+
+ Added "from linting" as a built-in feature to the SQL compiler. This
+ allows the compiler to maintain graph of all the FROM clauses in a
+ particular SELECT statement, linked by criteria in either the WHERE
+ or in JOIN clauses that link these FROM clauses together. If any two
+ FROM clauses have no path between them, a warning is emitted that the
+ query may be producing a cartesian product. As the Core expression
+ language as well as the ORM are built on an "implicit FROMs" model where
+ a particular FROM clause is automatically added if any part of the query
+ refers to it, it is easy for this to happen inadvertently and it is
+ hoped that the new feature helps with this issue.
+
+ .. seealso::
+
+ :ref:`change_4737`
+
+ .. change::
+ :tags: deprecated, orm
+ :tickets: 5606
+
+ The "slice index" feature used by :class:`_orm.Query` as well as by the
+ dynamic relationship loader will no longer accept negative indexes in
+ SQLAlchemy 2.0. These operations do not work efficiently and load the
+ entire collection in, which is both surprising and undesirable. These
+ will warn in 1.4 unless the :paramref:`_orm.Session.future` flag is set in
+ which case they will raise IndexError.
+
+
+ .. change::
+ :tags: sql, change
+ :tickets: 4617
+
+ The "clause coercion" system, which is SQLAlchemy Core's system of receiving
+ arguments and resolving them into :class:`_expression.ClauseElement` structures in order
+ to build up SQL expression objects, has been rewritten from a series of
+ ad-hoc functions to a fully consistent class-based system. This change
+ is internal and should have no impact on end users other than more specific
+ error messages when the wrong kind of argument is passed to an expression
+ object, however the change is part of a larger set of changes involving
+ the role and behavior of :func:`_expression.select` objects.
+
+
+ .. change::
+ :tags: bug, mysql
+
+ The MySQL and MariaDB dialects now query from the information_schema.tables
+ system view in order to determine if a particular table exists or not.
+ Previously, the "DESCRIBE" command was used with an exception catch to
+ detect non-existent, which would have the undesirable effect of emitting a
+ ROLLBACK on the connection. There appeared to be legacy encoding issues
+ which prevented the use of "SHOW TABLES", for this, but as MySQL support is
+ now at 5.0.2 or above due to :ticket:`4189`, the information_schema tables
+ are now available in all cases.
+
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 5122
+
+ A query that is against a mapped inheritance subclass which also uses
+ :meth:`_query.Query.select_entity_from` or a similar technique in order to
+ provide an existing subquery to SELECT from, will now raise an error if the
+ given subquery returns entities that do not correspond to the given
+ subclass, that is, they are sibling or superclasses in the same hierarchy.
+ Previously, these would be returned without error. Additionally, if the
+ inheritance mapping is a single-inheritance mapping, the given subquery
+ must apply the appropriate filtering against the polymorphic discriminator
+ column in order to avoid this error; previously, the :class:`_query.Query` would
+ add this criteria to the outside query however this interferes with some
+ kinds of query that return other kinds of entities as well.
+
+ .. seealso::
+
+ :ref:`change_5122`
+
+ .. change::
+ :tags: bug, engine
+ :tickets: 5004
+
+ Revised the :paramref:`.Connection.execution_options.schema_translate_map`
+ feature such that the processing of the SQL statement to receive a specific
+ schema name occurs within the execution phase of the statement, rather than
+ at the compile phase. This is to support the statement being efficiently
+ cached. Previously, the current schema being rendered into the statement
+ for a particular run would be considered as part of the cache key itself,
+ meaning that for a run against hundreds of schemas, there would be hundreds
+ of cache keys, rendering the cache much less performant. The new behavior
+ is that the rendering is done in a similar manner as the "post compile"
+ rendering added in 1.4 as part of :ticket:`4645`, :ticket:`4808`.
+
+ .. change::
+ :tags: usecase, sql
+ :tickets: 527
+
+ The :meth:`.Index.create` and :meth:`.Index.drop` methods now have a
+ parameter :paramref:`.Index.create.checkfirst`, in the same way as that of
+ :class:`_schema.Table` and :class:`.Sequence`, which when enabled will cause the
+ operation to detect if the index exists (or not) before performing a create
+ or drop operation.
+
+
+ .. change::
+ :tags: sql, postgresql
+ :tickets: 5498
+
+ Allow specifying the data type when creating a :class:`.Sequence` in
+ PostgreSQL by using the parameter :paramref:`.Sequence.data_type`.
+
+ .. change::
+ :tags: change, mssql
+ :tickets: 5084
+
+ SQL Server OFFSET and FETCH keywords are now used for limit/offset, rather
+ than using a window function, for SQL Server versions 11 and higher. TOP is
+ still used for a query that features only LIMIT. Pull request courtesy
+ Elkin.
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 5526
+
+ The :class:`_engine.URL` object is now an immutable named tuple. To modify
+ a URL object, use the :meth:`_engine.URL.set` method to produce a new URL
+ object.
+
+ .. seealso::
+
+ :ref:`change_5526` - notes on migration
+
+
+ .. change::
+ :tags: change, postgresql
+
+ When using the psycopg2 dialect for PostgreSQL, psycopg2 minimum version is
+ set at 2.7. The psycopg2 dialect relies upon many features of psycopg2
+ released in the past few years, so to simplify the dialect, version 2.7,
+ released in March, 2017 is now the minimum version required.
+
+
+ .. change::
+ :tags: usecase, sql
+
+ The :func:`.true` and :func:`.false` operators may now be applied as the
+ "onclause" of a :func:`_expression.join` on a backend that does not support
+ "native boolean" expressions, e.g. Oracle or SQL Server, and the expression
+ will render as "1=1" for true and "1=0" false. This is the behavior that
+ was introduced many years ago in :ticket:`2804` for and/or expressions.
+
+ .. change::
+ :tags: feature, engine
+ :tickets: 5087, 4395, 4959
+
+ Implemented an all-new :class:`_result.Result` object that replaces the previous
+ ``ResultProxy`` object. As implemented in Core, the subclass
+ :class:`_result.CursorResult` features a compatible calling interface with the
+ previous ``ResultProxy``, and additionally adds a great amount of new
+ functionality that can be applied to Core result sets as well as ORM result
+ sets, which are now integrated into the same model. :class:`_result.Result`
+ includes features such as column selection and rearrangement, improved
+ fetchmany patterns, uniquing, as well as a variety of implementations that
+ can be used to create database results from in-memory structures as well.
+
+
+ .. seealso::
+
+ :ref:`change_result_14_core`
+
+
+ .. change::
+ :tags: renamed, engine
+ :tickets: 5244
+
+ The :meth:`_reflection.Inspector.reflecttable` was renamed to
+ :meth:`_reflection.Inspector.reflect_table`.
+
+ .. change::
+ :tags: change, orm
+ :tickets: 4662
+
+ The condition where a pending object being flushed with an identity that
+ already exists in the identity map has been adjusted to emit a warning,
+ rather than throw a :class:`.FlushError`. The rationale is so that the
+ flush will proceed and raise a :class:`.IntegrityError` instead, in the
+ same way as if the existing object were not present in the identity map
+ already. This helps with schemes that are using the
+ :class:`.IntegrityError` as a means of catching whether or not a row
+ already exists in the table.
+
+ .. seealso::
+
+ :ref:`change_4662`
+
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 5001
+
+ Fixed issue where when constructing constraints from ORM-bound columns,
+ primarily :class:`_schema.ForeignKey` objects but also :class:`.UniqueConstraint`,
+ :class:`.CheckConstraint` and others, the ORM-level
+ :class:`.InstrumentedAttribute` is discarded entirely, and all ORM-level
+ annotations from the columns are removed; this is so that the constraints
+ are still fully pickleable without the ORM-level entities being pulled in.
+ These annotations are not necessary to be present at the schema/metadata
+ level.
+
+ .. change::
+ :tags: bug, mysql
+ :tickets: 5568
+
+ The "skip_locked" keyword used with ``with_for_update()`` will render "SKIP
+ LOCKED" on all MySQL backends, meaning it will fail for MySQL less than
+ version 8 and on current MariaDB backends. This is because those backends
+ do not support "SKIP LOCKED" or any equivalent, so this error should not be
+ silently ignored. This is upgraded from a warning in the 1.3 series.
+
+
+ .. change::
+ :tags: performance, postgresql
+ :tickets: 5401
+
+ The psycopg2 dialect now defaults to using the very performant
+ ``execute_values()`` psycopg2 extension for compiled INSERT statements,
+ and also implements RETURNING support when this extension is used. This
+ allows INSERT statements that even include an autoincremented SERIAL
+ or IDENTITY value to run very fast while still being able to return the
+ newly generated primary key values. The ORM will then integrate this
+ new feature in a separate change.
+
+ .. seealso::
+
+ :ref:`change_5401` - full list of changes regarding the
+ ``executemany_mode`` parameter.
+
+
+ .. change::
+ :tags: feature, orm
+ :tickets: 4472
+
+ Added the ability to add arbitrary criteria to the ON clause generated
+ by a relationship attribute in a query, which applies to methods such
+ as :meth:`_query.Query.join` as well as loader options like
+ :func:`_orm.joinedload`. Additionally, a "global" version of the option
+ allows limiting criteria to be applied to particular entities in
+ a query globally.
+
+ .. seealso::
+
+ :ref:`loader_option_criteria`
+
+ :ref:`do_orm_execute_global_criteria`
+
+ :func:`_orm.with_loader_criteria`
+
+ .. change::
+ :tags: renamed, sql
+
+ :class:`_schema.Table` parameter ``mustexist`` has been renamed
+ to :paramref:`_schema.Table.must_exist` and will now warn when used.
+
+ .. change::
+ :tags: removed, sql
+ :tickets: 4632
+
+ The "threadlocal" execution strategy, deprecated in 1.3, has been
+ removed for 1.4, as well as the concept of "engine strategies" and the
+ ``Engine.contextual_connect`` method. The "strategy='mock'" keyword
+ argument is still accepted for now with a deprecation warning; use
+ :func:`.create_mock_engine` instead for this use case.
+
+ .. seealso::
+
+ :ref:`change_4393_threadlocal` - from the 1.3 migration notes which
+ discusses the rationale for deprecation.
+
+ .. change::
+ :tags: mssql, postgresql, reflection, schema, usecase
+ :tickets: 4458
+
+ Improved support for covering indexes (with INCLUDE columns). Added the
+ ability for postgresql to render CREATE INDEX statements with an INCLUDE
+ clause from Core. Index reflection also report INCLUDE columns separately
+ for both mssql and postgresql (11+).
+
+ .. change::
+ :tags: change, platform
+ :tickets: 5400
+
+ The ``importlib_metadata`` library is used to scan for setuptools
+ entrypoints rather than pkg_resources. as importlib_metadata is a small
+ library that is included as of Python 3.8, the compatibility library is
+ installed as a dependency for Python versions older than 3.8.
+
+
+ .. change::
+ :tags: feature, sql, mssql, oracle
+ :tickets: 4808
+
+ Added new "post compile parameters" feature. This feature allows a
+ :func:`.bindparam` construct to have its value rendered into the SQL string
+ before being passed to the DBAPI driver, but after the compilation step,
+ using the "literal render" feature of the compiler. The immediate
+ rationale for this feature is to support LIMIT/OFFSET schemes that don't
+ work or perform well as bound parameters handled by the database driver,
+ while still allowing for SQLAlchemy SQL constructs to be cacheable in their
+ compiled form. The immediate targets for the new feature are the "TOP
+ N" clause used by SQL Server (and Sybase) which does not support a bound
+ parameter, as well as the "ROWNUM" and optional "FIRST_ROWS()" schemes used
+ by the Oracle dialect, the former of which has been known to perform better
+ without bound parameters and the latter of which does not support a bound
+ parameter. The feature builds upon the mechanisms first developed to
+ support "expanding" parameters for IN expressions. As part of this
+ feature, the Oracle ``use_binds_for_limits`` feature is turned on
+ unconditionally and this flag is now deprecated.
+
+ .. seealso::
+
+ :ref:`change_4808`
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 1390
+
+ Add support for regular expression on supported backends.
+ Two operations have been defined:
+
+ * :meth:`_sql.ColumnOperators.regexp_match` implementing a regular
+ expression match like function.
+ * :meth:`_sql.ColumnOperators.regexp_replace` implementing a regular
+ expression string replace function.
+
+ Supported backends include SQLite, PostgreSQL, MySQL / MariaDB, and Oracle.
+
+ .. seealso::
+
+ :ref:`change_1390`
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4696
+
+ The internal attribute symbols NO_VALUE and NEVER_SET have been unified, as
+ there was no meaningful difference between these two symbols, other than a
+ few codepaths where they were differentiated in subtle and undocumented
+ ways, these have been fixed.
+
+
+ .. change::
+ :tags: oracle, bug
+
+ Correctly render :class:`_schema.Sequence` and :class:`_schema.Identity`
+ column options ``nominvalue`` and ``nomaxvalue`` as ``NOMAXVALUE` and
+ ``NOMINVALUE`` on oracle database.
+
+ .. change::
+ :tags: bug, schema
+ :tickets: 4262
+
+ Cleaned up the internal ``str()`` for datatypes so that all types produce a
+ string representation without any dialect present, including that it works
+ for third-party dialect types without that dialect being present. The
+ string representation defaults to being the UPPERCASE name of that type
+ with nothing else.
+
+
+ .. change::
+ :tags: deprecated, sql
+ :tickets: 5010
+
+ The :meth:`_sql.Join.alias` method is deprecated and will be removed in
+ SQLAlchemy 2.0. An explicit select + subquery, or aliasing of the inner
+ tables, should be used instead.
+
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4194
+
+ Fixed bug where a versioning column specified on a mapper against a
+ :func:`_expression.select` construct where the version_id_col itself were against the
+ underlying table would incur additional loads when accessed, even if the
+ value were locally persisted by the flush. The actual fix is a result of
+ the changes in :ticket:`4617`, by fact that a :func:`_expression.select` object no
+ longer has a ``.c`` attribute and therefore does not confuse the mapper
+ into thinking there's an unknown column value present.
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 3858
+
+ An ``UnmappedInstanceError`` is now raised for :class:`.InstrumentedAttribute`
+ if an instance is an unmapped object. Prior to this an ``AttributeError``
+ was raised. Pull request courtesy Ramon Williams.
+
+ .. change::
+ :tags: removed, platform
+ :tickets: 5634
+
+ Dropped support for python 3.4 and 3.5 that has reached EOL. SQLAlchemy 1.4
+ series requires python 2.7 or 3.6+.
+
+ .. seealso::
+
+ :ref:`change_5634`
+
+ .. change::
+ :tags: performance, sql
+ :tickets: 4639
+
+ An all-encompassing reorganization and refactoring of Core and ORM
+ internals now allows all Core and ORM statements within the areas of
+ DQL (e.g. SELECTs) and DML (e.g. INSERT, UPDATE, DELETE) to allow their
+ SQL compilation as well as the construction of result-fetching metadata
+ to be fully cached in most cases. This effectively provides a transparent
+ and generalized version of what the "Baked Query" extension has offered
+ for the ORM in past versions. The new feature can calculate the
+ cache key for any given SQL construction based on the string that
+ it would ultimately produce for a given dialect, allowing functions that
+ compose the equivalent select(), Query(), insert(), update() or delete()
+ object each time to have that statement cached after it's generated
+ the first time.
+
+ The feature is enabled transparently but includes some new programming
+ paradigms that may be employed to make the caching even more efficient.
+
+ .. seealso::
+
+ :ref:`change_4639`
+
+ :ref:`sql_caching`
+
+ .. change::
+ :tags: orm, removed
+ :tickets: 4638
+
+ All long-deprecated "extension" classes have been removed, including
+ MapperExtension, SessionExtension, PoolListener, ConnectionProxy,
+ AttributeExtension. These classes have been deprecated since version 0.7
+ long superseded by the event listener system.
+
+
+ .. change::
+ :tags: feature, mssql, sql
+ :tickets: 4384
+
+ Added support for the :class:`_types.JSON` datatype on the SQL Server
+ dialect using the :class:`_mssql.JSON` implementation, which implements SQL
+ Server's JSON functionality against the ``NVARCHAR(max)`` datatype as per
+ SQL Server documentation. Implementation courtesy Gord Thompson.
+
+ .. change::
+ :tags: change, sql
+ :tickets: 4868
+
+ Added a core :class:`Values` object that enables a VALUES construct
+ to be used in the FROM clause of an SQL statement for databases that
+ support it (mainly PostgreSQL and SQL Server).
+
+ .. change::
+ :tags: usecase, mysql
+ :tickets: 5496
+
+ Added a new dialect token "mariadb" that may be used in place of "mysql" in
+ the :func:`_sa.create_engine` URL. This will deliver a MariaDB dialect
+ subclass of the MySQLDialect in use that forces the "is_mariadb" flag to
+ True. The dialect will raise an error if a server version string that does
+ not indicate MariaDB in use is received. This is useful for
+ MariaDB-specific testing scenarios as well as to support applications that
+ are hardcoding to MariaDB-only concepts. As MariaDB and MySQL featuresets
+ and usage patterns continue to diverge, this pattern may become more
+ prominent.
+
+
+ .. change::
+ :tags: bug, postgresql
+
+ The pg8000 dialect has been revised and modernized for the most recent
+ version of the pg8000 driver for PostgreSQL. Changes to the dialect
+ include:
+
+ * All data types are now sent as text rather than binary.
+
+ * Using adapters, custom types can be plugged in to pg8000.
+
+ * Previously, named prepared statements were used for all statements.
+ Now unnamed prepared statements are used by default, and named
+ prepared statements can be used explicitly by calling the
+ Connection.prepare() method, which returns a PreparedStatement
+ object.
+
+ Pull request courtesy Tony Locke.
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 5074
+
+ The :class:`.Session` object no longer initiates a
+ :class:`.SessionTransaction` object immediately upon construction or after
+ the previous transaction is closed; instead, "autobegin" logic now
+ initiates the new :class:`.SessionTransaction` on demand when it is next
+ needed. Rationale includes to remove reference cycles from a
+ :class:`.Session` that has been closed out, as well as to remove the
+ overhead incurred by the creation of :class:`.SessionTransaction` objects
+ that are often discarded immediately. This change affects the behavior of
+ the :meth:`.SessionEvents.after_transaction_create` hook in that the event
+ will be emitted when the :class:`.Session` first requires a
+ :class:`.SessionTransaction` be present, rather than whenever the
+ :class:`.Session` were created or the previous :class:`.SessionTransaction`
+ were closed. Interactions with the :class:`_engine.Engine` and the database
+ itself remain unaffected.
+
+ .. seealso::
+
+ :ref:`change_5074`
+
+
+ .. change::
+ :tags: oracle, change
+
+ The LIMIT / OFFSET scheme used in Oracle now makes use of named subqueries
+ rather than unnamed subqueries when it transparently rewrites a SELECT
+ statement to one that uses a subquery that includes ROWNUM. The change is
+ part of a larger change where unnamed subqueries are no longer directly
+ supported by Core, as well as to modernize the internal use of the select()
+ construct within the Oracle dialect.
+
+
+ .. change::
+ :tags: feature, engine, orm
+ :tickets: 3414
+
+ SQLAlchemy now includes support for Python asyncio within both Core and
+ ORM, using the included :ref:`asyncio extension <asyncio_toplevel>`. The
+ extension makes use of the `greenlet
+ <https://greenlet.readthedocs.io/en/latest/>`_ library in order to adapt
+ SQLAlchemy's sync-oriented internals such that an asyncio interface that
+ ultimately interacts with an asyncio database adapter is now feasible. The
+ single driver supported at the moment is the
+ :ref:`dialect-postgresql-asyncpg` driver for PostgreSQL.
+
+ .. seealso::
+
+ :ref:`change_3414`
+
+
+ .. change::
+ :tags: removed, sql
+
+ Removed the ``sqlalchemy.sql.visitors.iterate_depthfirst`` and
+ ``sqlalchemy.sql.visitors.traverse_depthfirst`` functions. These functions
+ were unused by any part of SQLAlchemy. The
+ :func:`_sa.sql.visitors.iterate` and :func:`_sa.sql.visitors.traverse`
+ functions are commonly used for these functions. Also removed unused
+ options from the remaining functions including "column_collections",
+ "schema_visitor".
+
+
+ .. change::
+ :tags: orm, performance
+
+ The bulk update and delete methods :meth:`.Query.update` and
+ :meth:`.Query.delete`, as well as their 2.0-style counterparts, now make
+ use of RETURNING when the "fetch" strategy is used in order to fetch the
+ list of affected primary key identites, rather than emitting a separate
+ SELECT, when the backend in use supports RETURNING. Additionally, the
+ "fetch" strategy will in ordinary cases not expire the attributes that have
+ been updated, and will instead apply the updated values directly in the
+ same way that the "evaluate" strategy does, to avoid having to refresh the
+ object. The "evaluate" strategy will also fall back to expiring
+ attributes that were updated to a SQL expression that was unevaluable in
+ Python.
+
+ .. seealso::
+
+ :ref:`change_orm_update_returning_14`
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4829
+
+ Added new entity-targeting capabilities to the ORM query context
+ help with the case where the :class:`.Session` is using a bind dictionary
+ against mapped classes, rather than a single bind, and the :class:`_query.Query`
+ is against a Core statement that was ultimately generated from a method
+ such as :meth:`_query.Query.subquery`. First implemented using a deep
+ search, the current approach leverages the unified :func:`_sql.select`
+ construct to keep track of the first mapper that is part of
+ the construct.
+
+
+ .. change::
+ :tags: mssql
+
+ The mssql dialect will assume that at least MSSQL 2005 is used.
+ There is no hard exception raised if a previous version is detected,
+ but operations may fail for older versions.
+
+ .. change::
+ :tags: bug, inheritance, orm
+ :tickets: 4212
+
+ An :class:`.ArgumentError` is now raised if both the ``selectable`` and
+ ``flat`` parameters are set to True in :func:`.orm.with_polymorphic`. The
+ selectable name is already aliased and applying flat=True overrides the
+ selectable name with an anonymous name that would've previously caused the
+ code to break. Pull request courtesy Ramon Williams.
+
+ .. change::
+ :tags: mysql, usecase
+ :tickets: 4976
+
+ Added support for use of the :class:`.Sequence` construct with MariaDB 10.3
+ and greater, as this is now supported by this database. The construct
+ integrates with the :class:`_schema.Table` object in the same way that it does for
+ other databases like PostgreSQL and Oracle; if is present on the integer
+ primary key "autoincrement" column, it is used to generate defaults. For
+ backwards compatibility, to support a :class:`_schema.Table` that has a
+ :class:`.Sequence` on it to support sequence only databases like Oracle,
+ while still not having the sequence fire off for MariaDB, the optional=True
+ flag should be set, which indicates the sequence should only be used to
+ generate the primary key if the target database offers no other option.
+
+ .. seealso::
+
+ :ref:`change_4976`
+
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 4634
+
+ The :paramref:`_schema.MetaData.bind` argument as well as the overall
+ concept of "bound metadata" is deprecated in SQLAlchemy 1.4 and will be
+ removed in SQLAlchemy 2.0. The parameter as well as related functions now
+ emit a :class:`_exc.RemovedIn20Warning` when :ref:`deprecation_20_mode` is
+ in use.
+
+ .. seealso::
+
+ :ref:`migration_20_implicit_execution`
+
+
+
+ .. change::
+ :tags: change, extensions
+ :tickets: 5142
+
+ Added new parameter :paramref:`_automap.AutomapBase.prepare.autoload_with`
+ which supersedes :paramref:`_automap.AutomapBase.prepare.reflect`
+ and :paramref:`_automap.AutomapBase.prepare.engine`.
+
+
+
+ .. change::
+ :tags: usecase, mssql, postgresql
+ :tickets: 4966
+
+ Added support for inspection / reflection of partial indexes / filtered
+ indexes, i.e. those which use the ``mssql_where`` or ``postgresql_where``
+ parameters, with :class:`_schema.Index`. The entry is both part of the
+ dictionary returned by :meth:`.Inspector.get_indexes` as well as part of a
+ reflected :class:`_schema.Index` construct that was reflected. Pull
+ request courtesy Ramon Williams.
+
+ .. change::
+ :tags: mssql, feature
+ :tickets: 4235, 4633
+
+ Added support for "CREATE SEQUENCE" and full :class:`.Sequence` support for
+ Microsoft SQL Server. This removes the deprecated feature of using
+ :class:`.Sequence` objects to manipulate IDENTITY characteristics which
+ should now be performed using ``mssql_identity_start`` and
+ ``mssql_identity_increment`` as documented at :ref:`mssql_identity`. The
+ change includes a new parameter :paramref:`.Sequence.data_type` to
+ accommodate SQL Server's choice of datatype, which for that backend
+ includes INTEGER, BIGINT, and DECIMAL(n, 0). The default starting value
+ for SQL Server's version of :class:`.Sequence` has been set at 1; this
+ default is now emitted within the CREATE SEQUENCE DDL for all backends.
+
+ .. seealso::
+
+ :ref:`change_4235`
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4718
+
+ Fixed issue in polymorphic loading internals which would fall back to a
+ more expensive, soon-to-be-deprecated form of result column lookup within
+ certain unexpiration scenarios in conjunction with the use of
+ "with_polymorphic".
+
+ .. change::
+ :tags: mssql, reflection
+ :tickets: 5527
+
+ As part of the support for reflecting :class:`_schema.Identity` objects,
+ the method :meth:`_reflection.Inspector.get_columns` no longer returns
+ ``mssql_identity_start`` and ``mssql_identity_increment`` as part of the
+ ``dialect_options``. Use the information in the ``identity`` key instead.
+
+ .. change::
+ :tags: schema, sql
+ :tickets: 5362, 5324, 5360
+
+ Added the :class:`_schema.Identity` construct that can be used to
+ configure identity columns rendered with GENERATED { ALWAYS |
+ BY DEFAULT } AS IDENTITY. Currently the supported backends are
+ PostgreSQL >= 10, Oracle >= 12 and MSSQL (with different syntax
+ and a subset of functionalities).
+
+ .. change::
+ :tags: change, orm, sql
+
+ A selection of Core and ORM query objects now perform much more of their
+ Python computational tasks within the compile step, rather than at
+ construction time. This is to support an upcoming caching model that will
+ provide for caching of the compiled statement structure based on a cache
+ key that is derived from the statement construct, which itself is expected
+ to be newly constructed in Python code each time it is used. This means
+ that the internal state of these objects may not be the same as it used to
+ be, as well as that some but not all error raise scenarios for various
+ kinds of argument validation will occur within the compilation / execution
+ phase, rather than at statement construction time. See the migration
+ notes linked below for complete details.
+
+ .. seealso::
+
+ :ref:`change_deferred_construction`
+
+
+ .. change::
+ :tags: usecase, mssql, reflection
+ :tickets: 5506
+
+ Added support for reflection of temporary tables with the SQL Server dialect.
+ Table names that are prefixed by a pound sign "#" are now introspected from
+ the MSSQL "tempdb" system catalog.
+
+ .. change::
+ :tags: firebird, deprecated
+ :tickets: 5189
+
+ The Firebird dialect is deprecated, as there is now a 3rd party
+ dialect that supports this database.
+
+ .. change::
+ :tags: misc, deprecated
+ :tickets: 5189
+
+ The Sybase dialect is deprecated.
+
+
+ .. change::
+ :tags: mssql, deprecated
+ :tickets: 5189
+
+ The adodbapi and mxODBC dialects are deprecated.
+
+
+ .. change::
+ :tags: mysql, deprecated
+ :tickets: 5189
+
+ The OurSQL dialect is deprecated.
+
+ .. change::
+ :tags: postgresql, deprecated
+ :tickets: 5189
+
+ The pygresql and py-postgresql dialects are deprecated.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 4649, 4569
+
+ Registered function names based on :class:`.GenericFunction` are now
+ retrieved in a case-insensitive fashion in all cases, removing the
+ deprecation logic from 1.3 which temporarily allowed multiple
+ :class:`.GenericFunction` objects to exist with differing cases. A
+ :class:`.GenericFunction` that replaces another on the same name whether or
+ not it's case sensitive emits a warning before replacing the object.
+
+ .. change::
+ :tags: orm, performance, postgresql
+ :tickets: 5263
+
+ Implemented support for the psycopg2 ``execute_values()`` extension
+ within the ORM flush process via the enhancements to Core made
+ in :ticket:`5401`, so that this extension is used
+ both as a strategy to batch INSERT statements together as well as
+ that RETURNING may now be used among multiple parameter sets to
+ retrieve primary key values back in batch. This allows nearly
+ all INSERT statements emitted by the ORM on behalf of PostgreSQL
+ to be submitted in batch and also via the ``execute_values()``
+ extension which benches at five times faster than plain
+ executemany() for this particular backend.
+
+ .. seealso::
+
+ :ref:`change_5263`
+
+ .. change::
+ :tags: change, general
+ :tickets: 4789
+
+ "python setup.py test" is no longer a test runner, as this is deprecated by
+ Pypa. Please use "tox" with no arguments for a basic test run.
+
+
+ .. change::
+ :tags: usecase, oracle
+ :tickets: 4857
+
+ The max_identifier_length for the Oracle dialect is now 128 characters by
+ default, unless compatibility version less than 12.2 upon first connect, in
+ which case the legacy length of 30 characters is used. This is a
+ continuation of the issue as committed to the 1.3 series which adds max
+ identifier length detection upon first connect as well as warns for the
+ change in Oracle server.
+
+ .. seealso::
+
+ :ref:`oracle_max_identifier_lengths` - in the Oracle dialect documentation
+
+
+ .. change::
+ :tags: bug, oracle
+ :tickets: 4971
+
+ The :class:`_oracle.INTERVAL` class of the Oracle dialect is now correctly
+ a subclass of the abstract version of :class:`.Interval` as well as the
+ correct "emulated" base class, which allows for correct behavior under both
+ native and non-native modes; previously it was only based on
+ :class:`.TypeEngine`.
+
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4994
+
+ An error is raised if any persistence-related "cascade" settings are made
+ on a :func:`_orm.relationship` that also sets up viewonly=True. The "cascade"
+ settings now default to non-persistence related settings only when viewonly
+ is also set. This is the continuation from :ticket:`4993` where this
+ setting was changed to emit a warning in 1.3.
+
+ .. seealso::
+
+ :ref:`change_4994`
+
+
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 5054
+
+ Creating an :func:`.and_` or :func:`.or_` construct with no arguments or
+ empty ``*args`` will now emit a deprecation warning, as the SQL produced is
+ a no-op (i.e. it renders as a blank string). This behavior is considered to
+ be non-intuitive, so for empty or possibly empty :func:`.and_` or
+ :func:`.or_` constructs, an appropriate default boolean should be included,
+ such as ``and_(True, *args)`` or ``or_(False, *args)``. As has been the
+ case for many major versions of SQLAlchemy, these particular boolean
+ values will not render if the ``*args`` portion is non-empty.
+
+ .. change::
+ :tags: removed, sql
+
+ Removed the concept of a bound engine from the :class:`.Compiler` object,
+ and removed the ``.execute()`` and ``.scalar()`` methods from
+ :class:`.Compiler`. These were essentially forgotten methods from over a
+ decade ago and had no practical use, and it's not appropriate for the
+ :class:`.Compiler` object itself to be maintaining a reference to an
+ :class:`_engine.Engine`.
+
+ .. change::
+ :tags: performance, engine
+ :tickets: 4524
+
+ The pool "pre-ping" feature has been refined to not invoke for a DBAPI
+ connection that was just opened in the same checkout operation. pre ping
+ only applies to a DBAPI connection that's been checked into the pool
+ and is being checked out again.
+
+ .. change::
+ :tags: deprecated, engine
+
+ The ``server_side_cursors`` engine-wide parameter is deprecated and will be
+ removed in a future release. For unbuffered cursors, the
+ :paramref:`_engine.Connection.execution_options.stream_results` execution
+ option should be used on a per-execution basis.
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4699
+
+ Improved declarative inheritance scanning to not get tripped up when the
+ same base class appears multiple times in the base inheritance list.
+
+
+ .. change::
+ :tags: orm, change
+ :tickets: 4395
+
+ The automatic uniquing of rows on the client side is turned off for the new
+ :term:`2.0 style` of ORM querying. This improves both clarity and
+ performance. However, uniquing of rows on the client side is generally
+ necessary when using joined eager loading for collections, as there
+ will be duplicates of the primary entity for each element in the
+ collection because a join was used. This uniquing must now be manually
+ enabled and can be achieved using the new
+ :meth:`_engine.Result.unique` modifier. To avoid silent failure, the ORM
+ explicitly requires the method be called when the result of an ORM
+ query in 2.0 style makes use of joined load collections. The newer
+ :func:`_orm.selectinload` strategy is likely preferable for eager loading
+ of collections in any case.
+
+ .. seealso::
+
+ :ref:`joinedload_not_uniqued`
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4195
+
+ Fixed bug in ORM versioning feature where assignment of an explicit
+ version_id for a counter configured against a mapped selectable where
+ version_id_col is against the underlying table would fail if the previous
+ value were expired; this was due to the fact that the mapped attribute
+ would not be configured with active_history=True.
+
+
+ .. change::
+ :tags: mssql, bug, schema
+ :tickets: 5597
+
+ Fixed an issue where :meth:`_reflection.has_table` always returned
+ ``False`` for temporary tables.
+
+ .. change::
+ :tags: mssql, engine
+ :tickets: 4809
+
+ Deprecated the ``legacy_schema_aliasing`` parameter to
+ :meth:`_sa.create_engine`. This is a long-outdated parameter that has
+ defaulted to False since version 1.1.
+
+ .. change::
+ :tags: usecase, orm
+ :tickets: 1653
+
+ The evaluator that takes place within the ORM bulk update and delete for
+ synchronize_session="evaluate" now supports the IN and NOT IN operators.
+ Tuple IN is also supported.
+
+
+ .. change::
+ :tags: change, sql
+ :tickets: 5284
+
+ The :func:`_expression.select` construct is moving towards a new calling
+ form that is ``select(col1, col2, col3, ..)``, with all other keyword
+ arguments removed, as these are all suited using generative methods. The
+ single list of column or table arguments passed to ``select()`` is still
+ accepted, however is no longer necessary if expressions are passed in a
+ simple positional style. Other keyword arguments are disallowed when this
+ form is used.
+
+
+ .. seealso::
+
+ :ref:`change_5284`
+
+ .. change::
+ :tags: change, sqlite
+ :tickets: 4895
+
+ Dropped support for right-nested join rewriting to support old SQLite
+ versions prior to 3.7.16, released in 2013. It is expected that
+ all modern Python versions among those now supported should all include
+ much newer versions of SQLite.
+
+ .. seealso::
+
+ :ref:`change_4895`
+
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 5131
+
+ The :meth:`_engine.Connection.connect` method is deprecated as is the concept of
+ "connection branching", which copies a :class:`_engine.Connection` into a new one
+ that has a no-op ".close()" method. This pattern is oriented around the
+ "connectionless execution" concept which is also being removed in 2.0.
+
+ .. change::
+ :tags: bug, general
+ :tickets: 4656, 4689
+
+ Refactored the internal conventions used to cross-import modules that have
+ mutual dependencies between them, such that the inspected arguments of
+ functions and methods are no longer modified. This allows tools like
+ pylint, Pycharm, other code linters, as well as hypothetical pep-484
+ implementations added in the future to function correctly as they no longer
+ see missing arguments to function calls. The new approach is also
+ simpler and more performant.
+
+ .. seealso::
+
+ :ref:`change_4656`
+
+ .. change::
+ :tags: sql, usecase
+ :tickets: 5191
+
+ Change the method ``__str`` of :class:`ColumnCollection` to avoid
+ confusing it with a python list of string.
+
+ .. change::
+ :tags: sql, reflection
+ :tickets: 4741
+
+ The "NO ACTION" keyword for foreign key "ON UPDATE" is now considered to be
+ the default cascade for a foreign key on all supporting backends (SQlite,
+ MySQL, PostgreSQL) and when detected is not included in the reflection
+ dictionary; this is already the behavior for PostgreSQL and MySQL for all
+ previous SQLAlchemy versions in any case. The "RESTRICT" keyword is
+ positively stored when detected; PostgreSQL does report on this keyword,
+ and MySQL as of version 8.0 does as well. On earlier MySQL versions, it is
+ not reported by the database.
+
+ .. change::
+ :tags: sql, reflection
+ :tickets: 5527, 5324
+
+ Added support for reflecting "identity" columns, which are now returned
+ as part of the structure returned by :meth:`_reflection.Inspector.get_columns`.
+ When reflecting full :class:`_schema.Table` objects, identity columns will
+ be represented using the :class:`_schema.Identity` construct.
+ Currently the supported backends are
+ PostgreSQL >= 10, Oracle >= 12 and MSSQL (with different syntax
+ and a subset of functionalities).
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 4753
+
+ The :func:`_expression.select` construct and related constructs now allow for
+ duplication of column labels and columns themselves in the columns clause,
+ mirroring exactly how column expressions were passed in. This allows
+ the tuples returned by an executed result to match what was SELECTed
+ for in the first place, which is how the ORM :class:`_query.Query` works, so
+ this establishes better cross-compatibility between the two constructs.
+ Additionally, it allows column-positioning-sensitive structures such as
+ UNIONs (i.e. :class:`_selectable.CompoundSelect`) to be more intuitively constructed
+ in those cases where a particular column might appear in more than one
+ place. To support this change, the :class:`_expression.ColumnCollection` has been
+ revised to support duplicate columns as well as to allow integer index
+ access.
+
+ .. seealso::
+
+ :ref:`change_4753`
+
+
+ .. change::
+ :tags: renamed, sql
+ :tickets: 4617
+
+ The :meth:`_expression.SelectBase.as_scalar` and :meth:`_query.Query.as_scalar` methods have
+ been renamed to :meth:`_expression.SelectBase.scalar_subquery` and
+ :meth:`_query.Query.scalar_subquery`, respectively. The old names continue to
+ exist within 1.4 series with a deprecation warning. In addition, the
+ implicit coercion of :class:`_expression.SelectBase`, :class:`_expression.Alias`, and other
+ SELECT oriented objects into scalar subqueries when evaluated in a column
+ context is also deprecated, and emits a warning that the
+ :meth:`_expression.SelectBase.scalar_subquery` method should be called explicitly.
+ This warning will in a later major release become an error, however the
+ message will always be clear when :meth:`_expression.SelectBase.scalar_subquery` needs
+ to be invoked. The latter part of the change is for clarity and to reduce
+ the implicit decisionmaking by the query coercion system. The
+ :meth:`.Subquery.as_scalar` method, which was previously
+ ``Alias.as_scalar``, is also deprecated; ``.scalar_subquery()`` should be
+ invoked directly from ` :func:`_expression.select` object or :class:`_query.Query` object.
+
+ This change is part of the larger change to convert :func:`_expression.select` objects
+ to no longer be directly part of the "from clause" class hierarchy, which
+ also includes an overhaul of the clause coercion system.
+
+
+ .. change::
+ :tags: bug, mssql
+ :tickets: 4980
+
+ Fixed the base class of the :class:`_mssql.DATETIMEOFFSET` datatype to
+ be based on the :class:`.DateTime` class hierarchy, as this is a
+ datetime-holding datatype.
+
+
+ .. change::
+ :tags: bug, engine
+ :tickets: 4712
+
+ The :class:`_engine.Connection` object will now not clear a rolled-back
+ transaction until the outermost transaction is explicitly rolled back.
+ This is essentially the same behavior that the ORM :class:`.Session` has
+ had for a long time, where an explicit call to ``.rollback()`` on all
+ enclosing transactions is required for the transaction to logically clear,
+ even though the DBAPI-level transaction has already been rolled back.
+ The new behavior helps with situations such as the "ORM rollback test suite"
+ pattern where the test suite rolls the transaction back within the ORM
+ scope, but the test harness which seeks to control the scope of the
+ transaction externally does not expect a new transaction to start
+ implicitly.
+
+ .. seealso::
+
+ :ref:`change_4712`
+
+
+ .. change::
+ :tags: deprecated, orm
+ :tickets: 4719
+
+ Calling the :meth:`_query.Query.instances` method without passing a
+ :class:`.QueryContext` is deprecated. The original use case for this was
+ that a :class:`_query.Query` could yield ORM objects when given only the entities
+ to be selected as well as a DBAPI cursor object. However, for this to work
+ correctly there is essential metadata that is passed from a SQLAlchemy
+ :class:`_engine.ResultProxy` that is derived from the mapped column expressions,
+ which comes originally from the :class:`.QueryContext`. To retrieve ORM
+ results from arbitrary SELECT statements, the :meth:`_query.Query.from_statement`
+ method should be used.
+
+
+ .. change::
+ :tags: deprecated, sql
+
+ The :class:`_schema.Table` class now raises a deprecation warning
+ when columns with the same name are defined. To replace a column a new
+ parameter :paramref:`_schema.Table.append_column.replace_existing` was
+ added to the :meth:`_schema.Table.append_column` method.
+
+ The :meth:`_expression.ColumnCollection.contains_column` will now
+ raises an error when called with a string, suggesting the caller
+ to use ``in`` instead.
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 4878
+
+ The :paramref:`.case_sensitive` flag on :func:`_sa.create_engine` is
+ deprecated; this flag was part of the transition of the result row object
+ to allow case sensitive column matching as the default, while providing
+ backwards compatibility for the former matching method. All string access
+ for a row should be assumed to be case sensitive just like any other Python
+ mapping.
+
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 5127
+
+ Improved the :func:`_sql.tuple_` construct such that it behaves predictably
+ when used in a columns-clause context. The SQL tuple is not supported as a
+ "SELECT" columns clause element on most backends; on those that do
+ (PostgreSQL, not surprisingly), the Python DBAPI does not have a "nested
+ type" concept so there are still challenges in fetching rows for such an
+ object. Use of :func:`_sql.tuple_` in a :func:`_sql.select` or
+ :class:`_orm.Query` will now raise a :class:`_exc.CompileError` at the
+ point at which the :func:`_sql.tuple_` object is seen as presenting itself
+ for fetching rows (i.e., if the tuple is in the columns clause of a
+ subquery, no error is raised). For ORM use,the :class:`_orm.Bundle` object
+ is an explicit directive that a series of columns should be returned as a
+ sub-tuple per row and is suggested by the error message. Additionally ,the
+ tuple will now render with parenthesis in all contexts. Previously, the
+ parenthesization would not render in a columns context leading to
+ non-defined behavior.
+
+ .. change::
+ :tags: usecase, sql
+ :tickets: 5576
+
+ Add support to ``FETCH {FIRST | NEXT} [ count ]
+ {ROW | ROWS} {ONLY | WITH TIES}`` in the select for the supported
+ backends, currently PostgreSQL, Oracle and MSSQL.
+
+ .. change::
+ :tags: feature, engine, alchemy2
+ :tickets: 4644
+
+ Implemented the :paramref:`_sa.create_engine.future` parameter which
+ enables forwards compatibility with SQLAlchemy 2. is used for forwards
+ compatibility with SQLAlchemy 2. This engine features
+ always-transactional behavior with autobegin.
+
+ .. seealso::
+
+ :ref:`migration_20_toplevel`
+
+ .. change::
+ :tags: usecase, sql
+ :tickets: 4449
+
+ Additional logic has been added such that certain SQL expressions which
+ typically wrap a single database column will use the name of that column as
+ their "anonymous label" name within a SELECT statement, potentially making
+ key-based lookups in result tuples more intuitive. The primary example of
+ this is that of a CAST expression, e.g. ``CAST(table.colname AS INTEGER)``,
+ which will export its default name as "colname", rather than the usual
+ "anon_1" label, that is, ``CAST(table.colname AS INTEGER) AS colname``.
+ If the inner expression doesn't have a name, then the previous "anonymous
+ label" logic is used. When using SELECT statements that make use of
+ :meth:`_expression.Select.apply_labels`, such as those emitted by the ORM, the
+ labeling logic will produce ``<tablename>_<inner column name>`` in the same
+ was as if the column were named alone. The logic applies right now to the
+ :func:`.cast` and :func:`.type_coerce` constructs as well as some
+ single-element boolean expressions.
+
+ .. seealso::
+
+ :ref:`change_4449`
+
+ .. change::
+ :tags: feature, orm
+ :tickets: 5508
+
+ The ORM Declarative system is now unified into the ORM itself, with new
+ import spaces under ``sqlalchemy.orm`` and new kinds of mappings. Support
+ for decorator-based mappings without using a base class, support for
+ classical style-mapper() calls that have access to the declarative class
+ registry for relationships, and full integration of Declarative with 3rd
+ party class attribute systems like ``dataclasses`` and ``attrs`` is now
+ supported.
+
+ .. seealso::
+
+ :ref:`change_5508`
+
+ :ref:`change_5027`
+
+ .. change::
+ :tags: removed, platform
+ :tickets: 5094
+
+ Removed all dialect code related to support for Jython and zxJDBC. Jython
+ has not been supported by SQLAlchemy for many years and it is not expected
+ that the current zxJDBC code is at all functional; for the moment it just
+ takes up space and adds confusion by showing up in documentation. At the
+ moment, it appears that Jython has achieved Python 2.7 support in its
+ releases but not Python 3. If Jython were to be supported again, the form
+ it should take is against the Python 3 version of Jython, and the various
+ zxJDBC stubs for various backends should be implemented as a third party
+ dialect.
+
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 5221
+
+ Enhanced the disambiguating labels feature of the
+ :func:`_expression.select` construct such that when a select statement
+ is used in a subquery, repeated column names from different tables are now
+ automatically labeled with a unique label name, without the need to use the
+ full "apply_labels()" feature that combines tablename plus column name.
+ The disambiguated labels are available as plain string keys in the .c
+ collection of the subquery, and most importantly the feature allows an ORM
+ :func:`_orm.aliased` construct against the combination of an entity and an
+ arbitrary subquery to work correctly, targeting the correct columns despite
+ same-named columns in the source tables, without the need for an "apply
+ labels" warning.
+
+
+ .. seealso::
+
+ :ref:`migration_20_query_from_self` - Illustrates the new
+ disambiguation feature as part of a strategy to migrate away from the
+ :meth:`_query.Query.from_self` method.
+
+ .. change::
+ :tags: usecase, postgresql
+ :tickets: 5549
+
+ Added support for PostgreSQL "readonly" and "deferrable" flags for all of
+ psycopg2, asyncpg and pg8000 dialects. This takes advantage of a newly
+ generalized version of the "isolation level" API to support other kinds of
+ session attributes set via execution options that are reliably reset
+ when connections are returned to the connection pool.
+
+ .. seealso::
+
+ :ref:`postgresql_readonly_deferrable`
+
+ .. change::
+ :tags: mysql, feature
+ :tickets: 5459
+
+ Added support for MariaDB Connector/Python to the mysql dialect. Original
+ pull request courtesy Georg Richter.
+
+ .. change::
+ :tags: usecase, orm
+ :tickets: 5171
+
+ Enhanced logic that tracks if relationships will be conflicting with each
+ other when they write to the same column to include simple cases of two
+ relationships that should have a "backref" between them. This means that
+ if two relationships are not viewonly, are not linked with back_populates
+ and are not otherwise in an inheriting sibling/overriding arrangement, and
+ will populate the same foreign key column, a warning is emitted at mapper
+ configuration time warning that a conflict may arise. A new parameter
+ :paramref:`_orm.relationship.overlaps` is added to suit those very rare cases
+ where such an overlapping persistence arrangement may be unavoidable.
+
+
+ .. change::
+ :tags: deprecated, orm
+ :tickets: 4705, 5202
+
+ Using strings to represent relationship names in ORM operations such as
+ :meth:`_orm.Query.join`, as well as strings for all ORM attribute names
+ in loader options like :func:`_orm.selectinload`
+ is deprecated and will be removed in SQLAlchemy 2.0. The class-bound
+ attribute should be passed instead. This provides much better specificity
+ to the given method, allows for modifiers such as ``of_type()``, and
+ reduces internal complexity.
+
+ Additionally, the ``aliased`` and ``from_joinpoint`` parameters to
+ :meth:`_orm.Query.join` are also deprecated. The :func:`_orm.aliased`
+ construct now provides for a great deal of flexibility and capability
+ and should be used directly.
+
+ .. seealso::
+
+ :ref:`migration_20_orm_query_join_strings`
+
+ :ref:`migration_20_query_join_options`
+
+ .. change::
+ :tags: change, platform
+ :tickets: 5404
+
+ Installation has been modernized to use setup.cfg for most package
+ metadata.
+
+ .. change::
+ :tags: bug, sql, postgresql
+ :tickets: 5653
+
+ Improved support for column names that contain percent signs in the string,
+ including repaired issues involving anoymous labels that also embedded a
+ column name with a percent sign in it, as well as re-established support
+ for bound parameter names with percent signs embedded on the psycopg2
+ dialect, using a late-escaping process similar to that used by the
+ cx_Oracle dialect.
+
+
+ .. change::
+ :tags: orm, deprecated
+ :tickets: 5134
+
+ Deprecated logic in :meth:`_query.Query.distinct` that automatically adds
+ columns in the ORDER BY clause to the columns clause; this will be removed
+ in 2.0.
+
+ .. seealso::
+
+ :ref:`migration_20_query_distinct`
+
+ .. change::
+ :tags: orm, removed
+ :tickets: 4642
+
+ Remove the deprecated loader options ``joinedload_all``, ``subqueryload_all``,
+ ``lazyload_all``, ``selectinload_all``. The normal version with method chaining
+ should be used in their place.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 4887
+
+ Custom functions that are created as subclasses of
+ :class:`.FunctionElement` will now generate an "anonymous label" based on
+ the "name" of the function just like any other :class:`.Function` object,
+ e.g. ``"SELECT myfunc() AS myfunc_1"``. While SELECT statements no longer
+ require labels in order for the result proxy object to function, the ORM
+ still targets columns in rows by using objects as mapping keys, which works
+ more reliably when the column expressions have distinct names. In any
+ case, the behavior is now made consistent between functions generated by
+ :attr:`.func` and those generated as custom :class:`.FunctionElement`
+ objects.
+
+
+ .. change::
+ :tags: usecase, extensions
+ :tickets: 4887
+
+ Custom compiler constructs created using the :mod:`sqlalchemy.ext.compiled`
+ extension will automatically add contextual information to the compiler
+ when a custom construct is interpreted as an element in the columns
+ clause of a SELECT statement, such that the custom element will be
+ targetable as a key in result row mappings, which is the kind of targeting
+ that the ORM uses in order to match column elements into result tuples.
+
+ .. change::
+ :tags: engine, bug
+ :tickets: 5497
+
+ Adjusted the dialect initialization process such that the
+ :meth:`_engine.Dialect.on_connect` is not called a second time
+ on the first connection. The hook is called first, then the
+ :meth:`_engine.Dialect.initialize` is called if that connection is the
+ first for that dialect, then no more events are called. This eliminates
+ the two calls to the "on_connect" function which can produce very
+ difficult debugging situations.
+
+ .. change::
+ :tags: feature, engine, pyodbc
+ :tickets: 5649
+
+ Reworked the "setinputsizes()" set of dialect hooks to be correctly
+ extensible for any arbirary DBAPI, by allowing dialects individual hooks
+ that may invoke cursor.setinputsizes() in the appropriate style for that
+ DBAPI. In particular this is intended to support pyodbc's style of usage
+ which is fundamentally different from that of cx_Oracle. Added support
+ for pyodbc.
+
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 4846
+
+ "Implicit autocommit", which is the COMMIT that occurs when a DML or DDL
+ statement is emitted on a connection, is deprecated and won't be part of
+ SQLAlchemy 2.0. A 2.0-style warning is emitted when autocommit takes
+ effect, so that the calling code may be adjusted to use an explicit
+ transaction.
+
+ As part of this change, DDL methods such as
+ :meth:`_schema.MetaData.create_all` when used against an
+ :class:`_engine.Engine` will run the operation in a BEGIN block if one is
+ not started already.
+
+ .. seealso::
+
+ :ref:`deprecation_20_mode`
+
+
+ .. change::
+ :tags: deprecated, orm
+ :tickets: 5573
+
+ Passing keyword arguments to methods such as :meth:`_orm.Session.execute`
+ to be passed into the :meth:`_orm.Session.get_bind` method is deprecated;
+ the new :paramref:`_orm.Session.execute.bind_arguments` dictionary should
+ be passed instead.
+
+
+ .. change::
+ :tags: renamed, schema
+ :tickets: 5413
+
+ Renamed the :meth:`_schema.Table.tometadata` method to
+ :meth:`_schema.Table.to_metadata`. The previous name remains with a
+ deprecation warning.
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 4336
+
+ Reworked the :meth:`_expression.ClauseElement.compare` methods in terms of a new
+ visitor-based approach, and additionally added test coverage ensuring that
+ all :class:`_expression.ClauseElement` subclasses can be accurately compared
+ against each other in terms of structure. Structural comparison
+ capability is used to a small degree within the ORM currently, however
+ it also may form the basis for new caching features.
+
+ .. change::
+ :tags: feature, orm
+ :tickets: 1763
+
+ Eager loaders, such as joined loading, SELECT IN loading, etc., when
+ configured on a mapper or via query options will now be invoked during
+ the refresh on an expired object; in the case of selectinload and
+ subqueryload, since the additional load is for a single object only,
+ the "immediateload" scheme is used in these cases which resembles the
+ single-parent query emitted by lazy loading.
+
+ .. seealso::
+
+ :ref:`change_1763`
+
+ .. change::
+ :tags: usecase, orm
+ :tickets: 5018, 3903
+
+ The ORM bulk update and delete operations, historically available via the
+ :meth:`_orm.Query.update` and :meth:`_orm.Query.delete` methods as well as
+ via the :class:`_dml.Update` and :class:`_dml.Delete` constructs for
+ :term:`2.0 style` execution, will now automatically accommodate for the
+ additional WHERE criteria needed for a single-table inheritance
+ discriminator in order to limit the statement to rows referring to the
+ specific subtype requested. The new :func:`_orm.with_loader_criteria`
+ construct is also supported for with bulk update/delete operations.
+
+ .. change::
+ :tags: engine, removed
+ :tickets: 4643
+
+ Remove deprecated method ``get_primary_keys`` in the :class:`.Dialect` and
+ :class:`_reflection.Inspector` classes. Please refer to the
+ :meth:`.Dialect.get_pk_constraint` and :meth:`_reflection.Inspector.get_primary_keys`
+ methods.
+
+ Remove deprecated event ``dbapi_error`` and the method
+ ``ConnectionEvents.dbapi_error``. Please refer to the
+ :meth:`_events.ConnectionEvents.handle_error` event.
+ This change also removes the attributes ``ExecutionContext.is_disconnect``
+ and ``ExecutionContext.exception``.
+
+ .. change::
+ :tags: removed, postgresql
+ :tickets: 4643
+
+ Remove support for deprecated engine URLs of the form ``postgres://``;
+ this has emitted a warning for many years and projects should be
+ using ``postgresql://``.
+
+ .. change::
+ :tags: removed, mysql
+ :tickets: 4643
+
+ Remove deprecated dialect ``mysql+gaerdbms`` that has been deprecated
+ since version 1.0. Use the MySQLdb dialect directly.
+
+ Remove deprecated parameter ``quoting`` from :class:`.mysql.ENUM`
+ and :class:`.mysql.SET` in the ``mysql`` dialect. The values passed to the
+ enum or the set are quoted by SQLAlchemy when needed automatically.
+
+ .. change::
+ :tags: removed, orm
+ :tickets: 4643
+
+ Remove deprecated function ``comparable_property``. Please refer to the
+ :mod:`~sqlalchemy.ext.hybrid` extension. This also removes the function
+ ``comparable_using`` in the declarative extension.
+
+ Remove deprecated function ``compile_mappers``. Please use
+ :func:`.configure_mappers`
+
+ Remove deprecated method ``collection.linker``. Please refer to the
+ :meth:`.AttributeEvents.init_collection` and
+ :meth:`.AttributeEvents.dispose_collection` event handlers.
+
+ Remove deprecated method ``Session.prune`` and parameter
+ ``Session.weak_identity_map``. See the recipe at
+ :ref:`session_referencing_behavior` for an event-based approach to
+ maintaining strong identity references.
+ This change also removes the class ``StrongInstanceDict``.
+
+ Remove deprecated parameter ``mapper.order_by``. Use :meth:`_query.Query.order_by`
+ to determine the ordering of a result set.
+
+ Remove deprecated parameter ``Session._enable_transaction_accounting``.
+
+ Remove deprecated parameter ``Session.is_modified.passive``.
+
+ .. change::
+ :tags: removed, schema
+ :tickets: 4643
+
+ Remove deprecated class ``Binary``. Please use :class:`.LargeBinary`.
+
+ .. change::
+ :tags: removed, sql
+ :tickets: 4643
+
+ Remove deprecated methods ``Compiled.compile``, ``ClauseElement.__and__`` and
+ ``ClauseElement.__or__`` and attribute ``Over.func``.
+
+ Remove deprecated ``FromClause.count`` method. Please use the
+ :class:`_functions.count` function available from the
+ :attr:`.func` namespace.
+
+ .. change::
+ :tags: removed, sql
+ :tickets: 4643
+
+ Remove deprecated parameters ``text.bindparams`` and ``text.typemap``.
+ Please refer to the :meth:`_expression.TextClause.bindparams` and
+ :meth:`_expression.TextClause.columns` methods.
+
+ Remove deprecated parameter ``Table.useexisting``. Please use
+ :paramref:`_schema.Table.extend_existing`.
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4836
+
+ An exception is now raised if the ORM loads a row for a polymorphic
+ instance that has a primary key but the discriminator column is NULL, as
+ discriminator columns should not be null.
+
+
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 4002
+
+ Deprecate usage of ``DISTINCT ON`` in dialect other than PostgreSQL.
+ Deprecate old usage of string distinct in MySQL dialect
+
+ .. change::
+ :tags: orm, usecase
+ :tickets: 5237
+
+ Update :paramref:`_orm.relationship.sync_backref` flag in a relationship
+ to make it implicitly ``False`` in ``viewonly=True`` relationships,
+ preventing synchronization events.
+
+
+ .. seealso::
+
+ :ref:`change_5237_14`
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 4877
+
+ Deprecated the behavior by which a :class:`_schema.Column` can be used as the key
+ in a result set row lookup, when that :class:`_schema.Column` is not part of the
+ SQL selectable that is being selected; that is, it is only matched on name.
+ A deprecation warning is now emitted for this case. Various ORM use
+ cases, such as those involving :func:`_expression.text` constructs, have been improved
+ so that this fallback logic is avoided in most cases.
+
+
+ .. change::
+ :tags: change, schema
+ :tickets: 5367
+
+ The :paramref:`.Enum.create_constraint` and
+ :paramref:`.Boolean.create_constraint` parameters now default to False,
+ indicating when a so-called "non-native" version of these two datatypes is
+ created, a CHECK constraint will not be generated by default. These CHECK
+ constraints present schema-management maintenance complexities that should
+ be opted in to, rather than being turned on by default.
+
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 4645
+
+ The "expanding IN" feature, which generates IN expressions at query
+ execution time which are based on the particular parameters associated with
+ the statement execution, is now used for all IN expressions made against
+ lists of literal values. This allows IN expressions to be fully cacheable
+ independently of the list of values being passed, and also includes support
+ for empty lists. For any scenario where the IN expression contains
+ non-literal SQL expressions, the old behavior of pre-rendering for each
+ position in the IN is maintained. The change also completes support for
+ expanding IN with tuples, where previously type-specific bind processors
+ weren't taking effect.
+
+ .. seealso::
+
+ :ref:`change_4645`
+
+ .. change::
+ :tags: bug, mysql
+ :tickets: 4189
+
+ MySQL dialect's server_version_info tuple is now all numeric. String
+ tokens like "MariaDB" are no longer present so that numeric comparison
+ works in all cases. The .is_mariadb flag on the dialect should be
+ consulted for whether or not mariadb was detected. Additionally removed
+ structures meant to support extremely old MySQL versions 3.x and 4.x;
+ the minimum MySQL version supported is now version 5.0.2.
+
+
+ .. change::
+ :tags: engine, feature
+ :tickets: 2056
+
+ Added new reflection method :meth:`.Inspector.get_sequence_names` which
+ returns all the sequences defined and :meth:`.Inspector.has_sequence` to
+ check if a particular sequence exits.
+ Support for this method has been added to the backend that support
+ :class:`.Sequence`: PostgreSQL, Oracle and MariaDB >= 10.3.
+
+ .. change::
+ :tags: usecase, postgresql
+ :tickets: 4914
+
+ The maximum buffer size for the :class:`.BufferedRowResultProxy`, which
+ is used by dialects such as PostgreSQL when ``stream_results=True``, can
+ now be set to a number greater than 1000 and the buffer will grow to
+ that size. Previously, the buffer would not go beyond 1000 even if the
+ value were set larger. The growth of the buffer is also now based
+ on a simple multiplying factor currently set to 5. Pull request courtesy
+ Soumaya Mauthoor.
+
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 4519
+
+ Accessing a collection-oriented attribute on a newly created object no
+ longer mutates ``__dict__``, but still returns an empty collection as has
+ always been the case. This allows collection-oriented attributes to work
+ consistently in comparison to scalar attributes which return ``None``, but
+ also don't mutate ``__dict__``. In order to accommodate for the collection
+ being mutated, the same empty collection is returned each time once
+ initially created, and when it is mutated (e.g. an item appended, added,
+ etc.) it is then moved into ``__dict__``. This removes the last of
+ mutating side-effects on read-only attribute access within the ORM.
+
+ .. seealso::
+
+ :ref:`change_4519`
+
+ .. change::
+ :tags: change, sql
+ :tickets: 4617
+
+ As part of the SQLAlchemy 2.0 migration project, a conceptual change has
+ been made to the role of the :class:`_expression.SelectBase` class hierarchy,
+ which is the root of all "SELECT" statement constructs, in that they no
+ longer serve directly as FROM clauses, that is, they no longer subclass
+ :class:`_expression.FromClause`. For end users, the change mostly means that any
+ placement of a :func:`_expression.select` construct in the FROM clause of another
+ :func:`_expression.select` requires first that it be wrapped in a subquery first,
+ which historically is through the use of the :meth:`_expression.SelectBase.alias`
+ method, and is now also available through the use of
+ :meth:`_expression.SelectBase.subquery`. This was usually a requirement in any
+ case since several databases don't accept unnamed SELECT subqueries
+ in their FROM clause in any case.
+
+ .. seealso::
+
+ :ref:`change_4617`
+
+ .. change::
+ :tags: change, sql
+ :tickets: 4617
+
+ Added a new Core class :class:`.Subquery`, which takes the place of
+ :class:`_expression.Alias` when creating named subqueries against a :class:`_expression.SelectBase`
+ object. :class:`.Subquery` acts in the same way as :class:`_expression.Alias`
+ and is produced from the :meth:`_expression.SelectBase.subquery` method; for
+ ease of use and backwards compatibility, the :meth:`_expression.SelectBase.alias`
+ method is synonymous with this new method.
+
+ .. seealso::
+
+ :ref:`change_4617`
+
+ .. change::
+ :tags: change, orm
+ :tickets: 4617
+
+ The ORM will now warn when asked to coerce a :func:`_expression.select` construct into
+ a subquery implicitly. This occurs within places such as the
+ :meth:`_query.Query.select_entity_from` and :meth:`_query.Query.select_from` methods
+ as well as within the :func:`.with_polymorphic` function. When a
+ :class:`_expression.SelectBase` (which is what's produced by :func:`_expression.select`) or
+ :class:`_query.Query` object is passed directly to these functions and others,
+ the ORM is typically coercing them to be a subquery by calling the
+ :meth:`_expression.SelectBase.alias` method automatically (which is now superseded by
+ the :meth:`_expression.SelectBase.subquery` method). See the migration notes linked
+ below for further details.
+
+ .. seealso::
+
+ :ref:`change_4617`
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 4617
+
+ The ORDER BY clause of a :class:`_selectable.CompoundSelect`, e.g. UNION, EXCEPT, etc.
+ will not render the table name associated with a given column when applying
+ :meth:`_selectable.CompoundSelect.order_by` in terms of a :class:`_schema.Table` - bound
+ column. Most databases require that the names in the ORDER BY clause be
+ expressed as label names only which are matched to names in the first
+ SELECT statement. The change is related to :ticket:`4617` in that a
+ previous workaround was to refer to the ``.c`` attribute of the
+ :class:`_selectable.CompoundSelect` in order to get at a column that has no table
+ name. As the subquery is now named, this change allows both the workaround
+ to continue to work, as well as allows table-bound columns as well as the
+ :attr:`_selectable.CompoundSelect.selected_columns` collections to be usable in the
+ :meth:`_selectable.CompoundSelect.order_by` method.
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 5226
+
+ The refresh of an expired object will now trigger an autoflush if the list
+ of expired attributes include one or more attributes that were explicitly
+ expired or refreshed using the :meth:`.Session.expire` or
+ :meth:`.Session.refresh` methods. This is an attempt to find a middle
+ ground between the normal unexpiry of attributes that can happen in many
+ cases where autoflush is not desirable, vs. the case where attributes are
+ being explicitly expired or refreshed and it is possible that these
+ attributes depend upon other pending state within the session that needs to
+ be flushed. The two methods now also gain a new flag
+ :paramref:`.Session.expire.autoflush` and
+ :paramref:`.Session.refresh.autoflush`, defaulting to True; when set to
+ False, this will disable the autoflush that occurs on unexpire for these
+ attributes.
+
+ .. change::
+ :tags: feature, sql
+ :tickets: 5380
+
+ Along with the new transparent statement caching feature introduced as part
+ of :ticket:`4369`, a new feature intended to decrease the Python overhead
+ of creating statements is added, allowing lambdas to be used when
+ indicating arguments being passed to a statement object such as select(),
+ Query(), update(), etc., as well as allowing the construction of full
+ statements within lambdas in a similar manner as that of the "baked query"
+ system. The rationale of using lambdas is adapted from that of the "baked
+ query" approach which uses lambdas to encapsulate any amount of Python code
+ into a callable that only needs to be called when the statement is first
+ constructed into a string. The new feature however is more sophisticated
+ in that Python literal values that would be passed as parameters are
+ automatically extracted, so that there is no longer a need to use
+ bindparam() objects with such queries. Use of the feature is optional and
+ can be used to as small or as great a degree as is desired, while still
+ allowing statements to be fully cacheable.
+
+ .. seealso::
+
+ :ref:`engine_lambda_caching`
+
+
+ .. change::
+ :tags: feature, orm
+ :tickets: 5027
+
+ Added support for direct mapping of Python classes that are defined using
+ the Python ``dataclasses`` decorator. Pull request courtesy Václav
+ Klusák. The new feature integrates into new support at the Declarative
+ level for systems such as ``dataclasses`` and ``attrs``.
+
+ .. seealso::
+
+ :ref:`change_5027`
+
+ :ref:`change_5508`
+
+
+ .. change::
+ :tags: change, engine
+ :tickets: 4710
+
+ The ``RowProxy`` class is no longer a "proxy" object, and is instead
+ directly populated with the post-processed contents of the DBAPI row tuple
+ upon construction. Now named :class:`.Row`, the mechanics of how the
+ Python-level value processors have been simplified, particularly as it impacts the
+ format of the C code, so that a DBAPI row is processed into a result tuple
+ up front. The object returned by the :class:`_engine.ResultProxy` is now the
+ :class:`.LegacyRow` subclass, which maintains mapping/tuple hybrid behavior,
+ however the base :class:`.Row` class now behaves more fully like a named
+ tuple.
+
+ .. seealso::
+
+ :ref:`change_4710_core`
+
+
+ .. change::
+ :tags: change, orm
+ :tickets: 4710
+
+ The "KeyedTuple" class returned by :class:`_query.Query` is now replaced with the
+ Core :class:`.Row` class, which behaves in the same way as KeyedTuple.
+ In SQLAlchemy 2.0, both Core and ORM will return result rows using the same
+ :class:`.Row` object. In the interim, Core uses a backwards-compatibility
+ class :class:`.LegacyRow` that maintains the former mapping/tuple hybrid
+ behavior used by "RowProxy".
+
+ .. seealso::
+
+ :ref:`change_4710_orm`
+
+ .. change::
+ :tags: feature, orm
+ :tickets: 4826
+
+ Added "raiseload" feature for ORM mapped columns via :paramref:`.orm.defer.raiseload`
+ parameter on :func:`.defer` and :func:`.deferred`. This provides
+ similar behavior for column-expression mapped attributes as the
+ :func:`.raiseload` option does for relationship mapped attributes. The
+ change also includes some behavioral changes to deferred columns regarding
+ expiration; see the migration notes for details.
+
+ .. seealso::
+
+ :ref:`change_4826`
+
+
+ .. change::
+ :tags: bug, orm
+ :tickets: 5150
+
+ The behavior of the :paramref:`_orm.relationship.cascade_backrefs` flag
+ will be reversed in 2.0 and set to ``False`` unconditionally, such that
+ backrefs don't cascade save-update operations from a forwards-assignment to
+ a backwards assignment. A 2.0 deprecation warning is emitted when the
+ parameter is left at its default of ``True`` at the point at which such a
+ cascade operation actually takes place. The new behavior can be
+ established as always by setting the flag to ``False`` on a specific
+ :func:`_orm.relationship`, or more generally can be set up across the board
+ by setting the the :paramref:`_orm.Session.future` flag to True.
+
+ .. seealso::
+
+ :ref:`change_5150`
+
+ .. change::
+ :tags: deprecated, engine
+ :tickets: 4755
+
+ Deprecated remaining engine-level introspection and utility methods
+ including :meth:`_engine.Engine.run_callable`, :meth:`_engine.Engine.transaction`,
+ :meth:`_engine.Engine.table_names`, :meth:`_engine.Engine.has_table`. The utility
+ methods are superseded by modern context-manager patterns, and the table
+ introspection tasks are suited by the :class:`_reflection.Inspector` object.
+
+ .. change::
+ :tags: removed, engine
+ :tickets: 4755
+
+ The internal dialect method ``Dialect.reflecttable`` has been removed. A
+ review of third party dialects has not found any making use of this method,
+ as it was already documented as one that should not be used by external
+ dialects. Additionally, the private ``Engine._run_visitor`` method
+ is also removed.
+
+
+ .. change::
+ :tags: removed, engine
+ :tickets: 4755
+
+ The long-deprecated ``Inspector.get_table_names.order_by`` parameter has
+ been removed.
+
+ .. change::
+ :tags: feature, engine
+ :tickets: 4755
+
+ The :paramref:`_schema.Table.autoload_with` parameter now accepts an :class:`_reflection.Inspector` object
+ directly, as well as any :class:`_engine.Engine` or :class:`_engine.Connection` as was the case before.
+
+
+ .. change::
+ :tags: change, performance, engine, py3k
+ :tickets: 5315
+
+ Disabled the "unicode returns" check that runs on dialect startup when
+ running under Python 3, which for many years has occurred in order to test
+ the current DBAPI's behavior for whether or not it returns Python Unicode
+ or Py2K strings for the VARCHAR and NVARCHAR datatypes. The check still
+ occurs by default under Python 2, however the mechanism to test the
+ behavior will be removed in SQLAlchemy 2.0 when Python 2 support is also
+ removed.
+
+ This logic was very effective when it was needed, however now that Python 3
+ is standard, all DBAPIs are expected to return Python 3 strings for
+ character datatypes. In the unlikely case that a third party DBAPI does
+ not support this, the conversion logic within :class:`.String` is still
+ available and the third party dialect may specify this in its upfront
+ dialect flags by setting the dialect level flag ``returns_unicode_strings``
+ to one of :attr:`.String.RETURNS_CONDITIONAL` or
+ :attr:`.String.RETURNS_BYTES`, both of which will enable Unicode conversion
+ even under Python 3.
+
+ .. change::
+ :tags: renamed, sql
+ :tickets: 5435, 5429
+
+ Several operators are renamed to achieve more consistent naming across
+ SQLAlchemy.
+
+ The operator changes are:
+
+ * ``isfalse`` is now ``is_false``
+ * ``isnot_distinct_from`` is now ``is_not_distinct_from``
+ * ``istrue`` is now ``is_true``
+ * ``notbetween`` is now ``not_between``
+ * ``notcontains`` is now ``not_contains``
+ * ``notendswith`` is now ``not_endswith``
+ * ``notilike`` is now ``not_ilike``
+ * ``notlike`` is now ``not_like``
+ * ``notmatch`` is now ``not_match``
+ * ``notstartswith`` is now ``not_startswith``
+ * ``nullsfirst`` is now ``nulls_first``
+ * ``nullslast`` is now ``nulls_last``
+ * ``isnot`` is now ``is_not``
+ * ``not_in_`` is now ``not_in``
+
+ Because these are core operators, the internal migration strategy for this
+ change is to support legacy terms for an extended period of time -- if not
+ indefinitely -- but update all documentation, tutorials, and internal usage
+ to the new terms. The new terms are used to define the functions, and
+ the legacy terms have been deprecated into aliases of the new terms.
+
+
+
+ .. change::
+ :tags: orm, deprecated
+ :tickets: 5192
+
+ The :func:`.eagerload` and :func:`.relation` were old aliases and are
+ now deprecated. Use :func:`_orm.joinedload` and :func:`_orm.relationship`
+ respectively.
+
+
+ .. change::
+ :tags: bug, sql
+ :tickets: 4621
+
+ The :class:`_expression.Join` construct no longer considers the "onclause" as a source
+ of additional FROM objects to be omitted from the FROM list of an enclosing
+ :class:`_expression.Select` object as standalone FROM objects. This applies to an ON
+ clause that includes a reference to another FROM object outside the JOIN;
+ while this is usually not correct from a SQL perspective, it's also
+ incorrect for it to be omitted, and the behavioral change makes the
+ :class:`_expression.Select` / :class:`_expression.Join` behave a bit more intuitively.
+