Mike Bayer [Tue, 16 Mar 2021 00:01:23 +0000 (20:01 -0400)]
Move enable_eagerloads(False) out of _from_self() into count()
Fixed regression where calling upon :meth:`_orm.Query.count` in conjunction
with a loader option such as :func:`_orm.joinedload` would fail to ignore
the loader option. This is a behavior that has always been very specific to
the :meth:`_orm.Query.count` method; an error is normally raised if a given
:class:`_orm.Query` has options that don't apply to what it is returning.
Specifically, the call to enable_eagerloads(False) inside of
_from_self() is not needed as loader options are now not invoked
for subqueries. Instead, set enable_eagerloads(False) in the
count() method itself, so that these options won't be considered
in this specific case.
Mike Bayer [Tue, 16 Feb 2021 23:36:50 +0000 (18:36 -0500)]
Implement Mypy plugin
Rudimentary and experimental support for Mypy has been added in the form of
a new plugin, which itself depends on new typing stubs for SQLAlchemy. The
plugin allows declarative mappings in their standard form to both be
compatible with Mypy as well as to provide typing support for mapped
classes and instances.
Mike Bayer [Fri, 12 Mar 2021 03:13:52 +0000 (22:13 -0500)]
Clarify ORM server side results
the docs here implied that the buffering scheme used by
BufferedRowCursorFetchStrategy is also used by the ORM, however
this is not currently the case. The ORM strictly uses the
"yield_per" option, which is either set explcitly, or passed
at result time via the fetchmany() / partitions() / yield_per()
methods.
Mike Bayer [Tue, 9 Mar 2021 18:36:34 +0000 (13:36 -0500)]
Apply percent sign escaping to op(), custom_op()
Fixed bug where the "percent escaping" feature that occurs with dialects
that use the "format" or "pyformat" bound parameter styles was not enabled
for the :meth:`.Operations.op` and :meth:`.Operations.custom_op` methods,
for custom operators that use percent signs. The percent sign will now be
automatically doubled based on the paramstyle as necessary.
Mike Bayer [Tue, 9 Mar 2021 15:48:59 +0000 (10:48 -0500)]
Link to state, not object, for mutable extension
The ``sqlalchemy.ext.mutable`` extension now tracks the "parents"
collection using the :class:`.InstanceState` associated with objects,
rather than the object itself. The latter approach required that the object
be hashable so that it can be inside of a ``WeakKeyDictionary``, which goes
against the behavioral contract of the ORM overall which is that ORM mapped
objects do not need to provide any particular kind of ``__hash__()`` method
and that unhashable objects are supported.
Mike Bayer [Fri, 5 Mar 2021 22:34:10 +0000 (17:34 -0500)]
Replace reset_agent with direct call from connection
Fixed a regression where the "reset agent" of the connection pool wasn't
really being utilized by the :class:`_engine.Connection` when it were
closed, and also leading to a double-rollback scenario that was somewhat
wasteful. The newer architecture of the engine has been updated so that
the connection pool "reset-on-return" logic will be skipped when the
:class:`_engine.Connection` explicitly closes out the transaction before
returning the pool to the connection.
Gord Thompson [Sat, 6 Mar 2021 19:19:13 +0000 (12:19 -0700)]
Fix named CHECK constraint name omitted on repeated creates
Fixed issue where the CHECK constraint generated by :class:`_types.Boolean`
or :class:`_types.Enum` would fail to render the naming convention
correctly after the first compilation, due to an unintended change of state
within the name given to the constraint. This issue was first introduced in
0.9 in the fix for issue #3067, and the fix revises the approach taken at
that time which appears to have been more involved than what was needed.
Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com> Fixes: #6007
Change-Id: I7ecff0a9d86191520f6841b3922a5af5a6971fba
Mike Bayer [Sat, 6 Mar 2021 02:52:03 +0000 (21:52 -0500)]
improve targeting and labeling for unary() in columns clause
Fixed regression where usage of the standalone :func:`_sql.distinct()` used
in the form of being directly SELECTed would fail to be locatable in the
result set by column identity, which is how the ORM locates columns. While
standalone :func:`_sql.distinct()` is not oriented towards being directly
SELECTed (use :meth:`_sql.select.distinct` for a regular
``SELECT DISTINCT..``) , it was usable to a limited extent in this way
previously (but wouldn't work in subqueries, for example). The column
targeting for unary expressions such as "DISTINCT <col>" has been improved
so that this case works again, and an additional improvement has been made
so that usage of this form in a subquery at least generates valid SQL which
was not the case previously.
The change additionally enhances the ability to target elements in
``row._mapping`` based on SQL expression objects in ORM-enabled
SELECT statements, including whether the statement was invoked by
``connection.execute()`` or ``session.execute()``.
Mike Bayer [Fri, 5 Mar 2021 21:02:38 +0000 (16:02 -0500)]
Ensure all Query statements compile w/ orm, fix test harness
Fixed regression where :meth:`_orm.Query.join` would produce no effect if
the query itself as well as the join target were against a
:class:`_schema.Table` object, rather than a mapped class. This was part of
a more systemic issue where the legacy ORM query compiler would not be
correctly used from a :class:`_orm.Query` if the statement produced had not
ORM entities present within it.
Also repair the assert_compile() method, which was using
Query._compile_state() which was bypassing the bug. A handful
of ORM tests with Query objects and Core-only objects were actually
failing if the default compilation path were used.
Mike Bayer [Fri, 5 Mar 2021 17:27:09 +0000 (12:27 -0500)]
Clarify COMMIT/ROLLBACK logging when autocommit is turned on
Improved engine logging to note ROLLBACK and COMMIT which is logged while
the DBAPI driver is in AUTOCOMMIT mode. These ROLLBACK/COMMIT are library
level and do not have any effect when AUTOCOMMIT is in effect, however it's
still worthwhile to log as these indicate where SQLAlchemy sees the
"transaction" demarcation.
Fixed issue where the :class:`_mutable.MutableComposite` construct could be
placed into an invalid state when the parent object was already loaded, and
then covered by a subsequent query, due to the composite properties'
refresh handler replacing the object with a new one not handled by the
mutable extension.
Mike Bayer [Tue, 2 Mar 2021 23:48:08 +0000 (18:48 -0500)]
Remove passive_deletes warning for many-to-one
Removed very old warning that states that passive_deletes is not intended
for many-to-one relationships. While it is likely that in many cases
placing this parameter on a many-to-one relationship is not what was
intended, there are use cases where delete cascade may want to be
disallowed following from such a relationship.
Mike Bayer [Tue, 2 Mar 2021 16:16:49 +0000 (11:16 -0500)]
convert AsyncSession.delete into awaitable
The API for :meth:`_asyncio.AsyncSession.delete` is now an awaitable;
this method cascades along relationships which must be loaded in a
similar manner as the :meth:`_asyncio.AsyncSession.merge` method.
Mike Bayer [Fri, 26 Feb 2021 04:20:05 +0000 (23:20 -0500)]
disable all raiseload within the unit of work process.
The unit of work process now turns off all "lazy='raise'" behavior
altogether when a flush is proceeding. While there are areas where the UOW
is sometimes loading things that aren't ultimately needed, the lazy="raise"
strategy is not helpful here as the user often does not have much control
or visibility into the flush process.
Mike Bayer [Sat, 27 Feb 2021 17:48:54 +0000 (12:48 -0500)]
support stringify for plain CTE
Altered the compilation for the :class:`.CTE` construct so that a string is
returned representing the inner SELECT statement if the :class:`.CTE` is
stringified directly, outside of the context of an enclosing SELECT; This
is the same behavior of :meth:`_FromClause.alias` and
:meth:`_SelectStatement.subquery`. Previously, a blank string would be
returned as the CTE is normally placed above a SELECT after that SELECT has
been generated, which is generally misleading when debugging.
Mike Bayer [Thu, 25 Feb 2021 22:07:06 +0000 (17:07 -0500)]
Revert AppenderQuery modifications from ORM
We are unfortunately stuck with this class completely
until we get rid of "dynamic" altogether. The usage
contract includes the "query_class" mixin feature where
users add their own methods, and this use case very
well in line with 2.0's contract. As Query is not going away
in any case this has to stay in "legacy" style, there's no
point trying to change it as the new version was still fully
dependent on Query.
Mike Bayer [Tue, 23 Feb 2021 02:49:09 +0000 (21:49 -0500)]
mutex asyncpg / aiomysql connection state changes
Added an ``asyncio.Lock()`` within SQLAlchemy's emulated DBAPI cursor,
local to the connection, for the asyncpg dialect, so that the space between
the call to ``prepare()`` and ``fetch()`` is prevented from allowing
concurrent executions on the connection from causing interface error
exceptions, as well as preventing race conditions when starting a new
transaction. Other PostgreSQL DBAPIs are threadsafe at the connection level
so this intends to provide a similar behavior, outside the realm of server
side cursors.
Apply the same idea to the aiomysql dialect which also would
otherwise be subject to corruption if the connection were used
concurrently.
While this is an issue which can also occur with the threaded
connection libraries, we anticipate asyncio users are more likely
to attempt using the same connection in multiple awaitables
at a time, even though this won't achieve concurrency for that
use case, as the asyncio programming style is very encouraging
of this. As the failure modes are also more complicated under
asyncio, we'd rather not have this being reported.
Mike Bayer [Tue, 23 Feb 2021 03:14:41 +0000 (22:14 -0500)]
refer to row elements as "elements", not columns
disambiguate between the "elements of a row" and
a "column" which is taken to mean a database column, and
remove confusing terms like "single-column ORM entity".
Federico Caselli [Thu, 18 Feb 2021 20:05:05 +0000 (21:05 +0100)]
Update the create wheel action:
- use manylinux1 for python 2 since manylinux2010 has dropped
support for it
- use a different action to upload the artifacts to the release so
that a single step can be used
- also generate manylinux2014 wheels for python3
Federico Caselli [Thu, 18 Feb 2021 18:12:45 +0000 (19:12 +0100)]
Minor optimization to the code
* remove the c version of distill params since it's actually slower than
the python one
* add a function to langhelpers to check if the cextensions are active
* minor cleanup to the OrderedSet implementation
Mike Bayer [Thu, 18 Feb 2021 15:43:16 +0000 (10:43 -0500)]
Extract table names when comparing to nrte error
Fixed issue where the process of joining two tables could fail if one of
the tables had an unrelated, unresolvable foreign key constraint which
would raise :class:`_exc.NoReferenceError` within the join process, which
nonetheless could be bypassed to allow the join to complete. The logic
which tested the exception for signficance within the process would make
assumptions about the construct which would fail.
Oliver Rice [Sat, 13 Feb 2021 19:21:55 +0000 (14:21 -0500)]
Support legacy select(<iterable>) in addition to select(<list>) in v1.4
Fixed regression where use of an arbitrary iterable with the
:func:`_sql.select` function was not working, outside of plain lists. The
forwards/backwards compatibility logic here now checks for a wider range of
incoming "iterable" types including that a ``.c`` collection from a
selectable can be passed directly. Pull request compliments of Oliver Rice.
Mike Bayer [Sun, 14 Feb 2021 04:21:04 +0000 (23:21 -0500)]
Allow update.returing() to work with from_statement()
The ORM used in :term:`2.0 style` can now return ORM objects from the rows
returned by an UPDATE..RETURNING or INSERT..RETURNING statement, by
supplying the construct to :meth:`_sql.Select.from_statement` in an ORM
context.
Mike Bayer [Sat, 13 Feb 2021 22:13:51 +0000 (17:13 -0500)]
expand and further generalize bound parameter translate
Continued with the improvement made as part of :ticket:`5653` to further
support bound parameter names, including those generated against column
names, for names that include colons, parenthesis, and question marks, as
well as improved test support, so that bound parameter names even if they
are auto-derived from column names should have no problem including for
parenthesis in psycopg2's "pyformat" style.
As part of this change, the format used by the asyncpg DBAPI adapter (which
is local to SQLAlchemy's asyncpg diaelct) has been changed from using
"qmark" paramstyle to "format", as there is a standard and internally
supported SQL string escaping style for names that use percent signs with
"format" style (i.e. to double percent signs), as opposed to names that use
question marks with "qmark" style (where an escaping system is not defined
by pep-249 or Python).
Mike Bayer [Thu, 11 Feb 2021 19:05:49 +0000 (14:05 -0500)]
Further refine labeling for renamed columns
Forked from I22f6cf0f0b3360e55299cdcb2452cead2b2458ea
we are attempting to decide the case for columns mapped
under a different name. since the .key feature of
Column seems to support this fully, see if an annotation
can be used to indicate an effective .key for a column.
The effective change is that the labeling of column expressions
in rows has been improved to retain the original name of the ORM
attribute even if used in a subquery.
Mike Bayer [Thu, 11 Feb 2021 19:05:49 +0000 (14:05 -0500)]
Apply consistent labeling for all future style ORM queries
Fixed issue in new 1.4/2.0 style ORM queries where a statement-level label
style would not be preserved in the keys used by result rows; this has been
applied to all combinations of Core/ORM columns / session vs. connection
etc. so that the linkage from statement to result row is the same in all
cases.
also repairs a cache key bug where query.from_statement()
vs. select().from_statement() would not be disambiguated; the
compile options were not included in the cache key for
FromStatement.
Mike Bayer [Wed, 10 Feb 2021 15:36:52 +0000 (10:36 -0500)]
Don't pre-calc inserted primary key if no getter
the _setup_ins_pk_from_empty() method provides a placeholder
result for inserted_primary_key_rows that is not typically
going to be invoked. For an executemany (or even execute)
that isn't already stating it wants primary key values
up front, defer this computation until explicitly requested.