Mike Bayer [Mon, 2 Nov 2020 22:37:12 +0000 (17:37 -0500)]
Reduce import time overhead
* Fix subclass traversals to not run classes multiple times
* switch compiler visitor to use an attrgetter, to avoid
an eval() at startup time
* don't pre-generate traversal functions, there's lots of these
which are expensive to generate at once and most applications
won't use them all; have it generate them on first use instead
* Some ideas about removing asyncio imports, they don't seem to
be too signficant, apply some more simplicity to the overall
"greenlet fallback" situation
Mike Bayer [Sat, 31 Oct 2020 23:08:28 +0000 (19:08 -0400)]
update selectin docs
* correct many-to-one example that doesnt use JOIN or ORDER BY
anymore
* Oracle does tuple IN, let's test it
* many-to-many is supported but joins all the way right now
* remove verbiage about yield_per for the moment to simplify
updates to how yield_per works w/ new style execution. yield_per
is difficult to explain and the section seems kind of complicated
with those details added at the moment.
Mike Bayer [Sat, 26 Sep 2020 02:31:16 +0000 (22:31 -0400)]
tutorial 2.0 WIP
Add SelectBase.exists() method as it seems strange this is
not available already. The Exists construct itself does
not provide full SELECT-building capabilities so it makes
sense this should be used more like a scalar_subquery.
Make sure stream_results is getting set up when yield_per
is used, for 2.0 style statements as well. this was
hardcoded inside of Query.yield_per() and is now moved
to take place within QueryContext.
jonathan vanasco [Wed, 28 Oct 2020 18:35:39 +0000 (14:35 -0400)]
Apply underscore naming to several more operators
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`
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.
Mike Bayer [Fri, 30 Oct 2020 03:21:13 +0000 (23:21 -0400)]
rename "bulk" UPDATE and DELETE to not use the word "bulk"
This term confuses this feature with the lesser used
"bulk insert/update" feature, and also "bulk" is not as
descriptive here as only a single statement is run; there's
not a large set of data passed in.
For now call it UPDATE/DELETE with arbitrary WHERE clause,
or ORM-enabled UPDATE/DELETE.
Mike Bayer [Thu, 29 Oct 2020 18:29:57 +0000 (14:29 -0400)]
Implement PropComparator.and_() for remaining options
In c7b489b25802f7a25ef78d0731411295c611cc1c we implemented
with_loader_criteria() for everyone as well as PropComparator.and_()
for joinedload() and join(), but forgot to do anything for
lazyload(), selectinload(), or subqueryload(). Even though
I actually documented it in terms of lazyload().
Mike Bayer [Wed, 21 Oct 2020 17:58:22 +0000 (13:58 -0400)]
Don't populate expired attrs w/ evaluator
Fixed bug in :meth:`_orm.Query.update` where objects in the
:class:`_orm.Session` that were already expired would be unnecessarily
SELECTed individually when they were refreshed by the "evaluate"
synchronize strategy.
For 1.4 there was also a similar issue with fetch that would actually
get the wrong data back, as the new value would be loaded, then
applied with the evaluator.
Mike Bayer [Mon, 19 Oct 2020 19:57:13 +0000 (15:57 -0400)]
Add FAQ entry for retry subject; recipe w/ autocommit
In order to invalidate a connection within a Transaction
block and an execution context, we need to take advantage
of the simpler transaction design added in 1.4. The recipe
can be done on 1.3 but it requires a lot more hacking
and isn't worth it.
Clearly since the recipe is part of the tests now we can
in the future consider adding a feature that's built
in for this case but it would have to absolutely guarantee
the DBAPI is in autocommit mode and also prevent
any "write" operations from taking place. Recipe for now.
Mike Bayer [Mon, 19 Oct 2020 14:19:29 +0000 (10:19 -0400)]
Ensure no compiler visit method tries to access .statement
Fixed structural compiler issue where some constructs such as MySQL /
PostgreSQL "on conflict / on duplicate key" would rely upon the state of
the :class:`_sql.Compiler` object being fixed against their statement as
the top level statement, which would fail in cases where those statements
are branched from a different context, such as a DDL construct linked to a
SQL statement.
Mike Bayer [Sat, 17 Oct 2020 15:39:56 +0000 (11:39 -0400)]
Ensure escaping of percent signs in columns, parameters
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.
* Added new constructor for _anonymous_label() that ensures incoming
string tokens based on column or table names will have percent
signs escaped; abstracts away the format of the label.
* generalized cx_Oracle's quoted_bind_names facility into the compiler
itself, and leveraged this for the psycopg2 dialect's issue with
percent signs in names as well. the parameter substitution is now
integrated with compiler.construct_parameters() as well as the
recently reworked set_input_sizes(), reducing verbosity in the
cx_Oracle dialect.
Mike Bayer [Fri, 16 Oct 2020 16:03:11 +0000 (12:03 -0400)]
Add deprecation for base Executable.bind
These attributes will be removed in SQLAlchemy 2.0.
Also alters the deprecation message to qualify the
type of object correctly. this in turn requires changes
in the warnings filter and deprecation tests.
Mike Bayer [Thu, 15 Oct 2020 22:18:03 +0000 (18:18 -0400)]
Genericize setinputsizes and support pyodbc
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.
Mike Bayer [Mon, 12 Oct 2020 19:17:25 +0000 (15:17 -0400)]
Deprecate strings indicating attribute names
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.
Support indexing on expressions and functions for the MySQL dialect
A user noticed that creating an index where the "key part" was an expression
or function would raise an error for MySQL because the key part was not
parenthesized. The proposed change will check whether a key part is not a
Column or Unary Expression and parenthesize if the case is False.
This fix also contains a minor fix to a test case that was previously incorrect
(`def test_create_index_expr():`).
Mike Bayer [Mon, 12 Oct 2020 17:16:14 +0000 (13:16 -0400)]
Deprecate bound metadata
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.
Added new parameter :paramref:`_automap.AutomapBase.prepare.autoload_with`
which supersedes :paramref:`_automap.AutomapBase.prepare.reflect`
and :paramref:`_automap.AutomapBase.prepare.engine`.
Mike Bayer [Thu, 3 Sep 2020 18:14:39 +0000 (14:14 -0400)]
Deprecate duplicated column names in Table definition
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.
Mike Bayer [Mon, 12 Oct 2020 15:14:14 +0000 (11:14 -0400)]
repair pg8000 and pin to 1.16.6 min version
Due to https://github.com/tlocke/pg8000/commit/3a2e7439ae3613367ec231218d7e0f541466d1e5
we no longer decode the description. pin to 1.16.6 as minimum version
so that we don't need to track version changes in code.
Mike Bayer [Thu, 8 Oct 2020 19:20:48 +0000 (15:20 -0400)]
generalize scoped_session proxying and apply to asyncio elements
Reworked the proxy creation used by scoped_session() to be
based on fully copied code with augmented docstrings and
moved it into langhelpers. asyncio session, engine,
connection can now take
advantage of it so that all non-async methods are availble.
Overall implementation of most important accessors / methods
on AsyncConnection, etc. , including awaitable versions
of invalidate, execution_options, etc.
In order to support an event dispatcher on the async
classes while still allowing them to hold __slots__,
make some adjustments to the event system to allow
that to be present, at least rudimentally.
I completely misread https://www.python.org/dev/peps/pep-0418/#rationale
and the accuracy of monotonic() is *worse* on windows than time.time(),
which is bizarre.
Mike Bayer [Wed, 7 Oct 2020 13:47:46 +0000 (09:47 -0400)]
force a sleep for test_reconnect
as I dont have a windows machine to test I don't really know
how to get a millisecond-accurate timer for windows,
Python documentation claimed time.monotonic() did this however
the continued failure of test_reconnect indicates this is not the case
and that the timer is still bumping up by multi-millisecond
granularity. force a delay instead.
Mike Bayer [Wed, 7 Oct 2020 12:42:48 +0000 (08:42 -0400)]
Use monotonic time for pool age measurement
The internal clock used by the :class:`_pool.Pool` object is now
time.monotonic_time() under Python 3. Under Python 2, time.time() is still
used, which is legacy. This clock is used to measure the age of a
connection against its starttime, and used in comparisons against the
pool_timeout setting as well as the last time the pool was marked as
invalid to determine if the connection should be recycled. Previously,
time.time() was used which was subject to inaccuracies as a result of
system clock changes as well as poor time resolution on windows.
Mike Bayer [Wed, 7 Oct 2020 04:50:53 +0000 (00:50 -0400)]
limit "no identity" test to a hardcoded dialect
this test can't require "skip identity_columns" because
older Postgresql and Oracle report false for "identity_columns",
but their dialects won't skip actually rendering.
for now the only option is to hardcode to a non-identity
dialect.
Mike Bayer [Wed, 7 Oct 2020 03:48:47 +0000 (23:48 -0400)]
add --notimingintensive; block from github jobs
this provides a front-end option to disable tests marked
as timing_intensive, all of which are in test_pool, which are more
fragile and aren't consistent on the
github runners. also remove /reduce unnecessary time.sleep()
from two other pool tests that are not timing intensive.
note that this removes test_hanging_connect_within_overflow
from the github runs via the timing_intensive requirement.
I've also removed MockReconnectTest from exclusions as those are
really important tests and they use mocks so should not have
platform dependent issues. Need to see what the
windows failures are.
Fixed bug where a call ``InstanceState.obj()`` could return None when
synchronizing the instance states of the objects in the session in case
they become out of scope but are not yet finalized by the gc. This
case does not happen in cPython, but it may present itself in pypy.
The approach is to allow None to be gracefully handled by the
evaluator itself, ensuring it returns None in all cases when None
is passed in.
Mike Bayer [Wed, 7 Oct 2020 03:46:03 +0000 (23:46 -0400)]
modernize requirements for boolean constraint test
this test was not actually working correctly against
mariadb and was "failing" (i.e. "passing") inappropriately
for pymysql, mysqlclient. it also started "passing" (i.e. "failing")
for mariadb as of 1.0.3.
modernize reqs here including for mssql bit behavior.
I'm not 100% sure what this sentence is saying, but I'm pretty sure it needs either commas or parentheses to break it up a little. I think parens make the most sense in this case assuming I am reading it correctly. Here's the original sentence and proposed edit in plaintext:
ORIG
"...persistent objects which were removed from a collection or in some cases a scalar attribute may also be pulled into the Session of a parent object;..."
EDIT
"...persistent objects which were removed from a collection (or in some cases a scalar attribute) may also be pulled into the Session of a parent object;..."
Add support to ``FETCH {FIRST | NEXT} [ count ] {ROW | ROWS}
{ONLY | WITH TIES}`` in the select for the supported backends,
currently PostgreSQL, Oracle and MSSQL.
Mike Bayer [Wed, 30 Sep 2020 12:37:57 +0000 (08:37 -0400)]
raise on lower-case column shared to multiple tables
Fixed bug where an error was not raised for lower-case
:func:`_column` added to lower-case :func:`_table` object. This now raises
:class:`_exc.ArgumentError` which has always been the case for
upper-case :class:`_schema.Column` and :class:`_schema.Table`.
Mike Bayer [Tue, 29 Sep 2020 18:17:42 +0000 (14:17 -0400)]
Scan for tables without relying upon whereclause
Fixed bug where an UPDATE statement against a JOIN using MySQL multi-table
format would fail to include the table prefix for the target table if the
statement had no WHERE clause, as only the WHERE clause were scanned to
detect a "multi table update" at that particular point. The target
is now also scanned if it's a JOIN to get the leftmost table as the
primary table and the additional entries as additional FROM entries.
Mike Bayer [Tue, 29 Sep 2020 19:44:33 +0000 (15:44 -0400)]
bump variance on test_string, test_unicode
a recent rerun of profiles added more profiling data that's
failing over small differences. 15% variance is fine for these
tests that are looking for thousands of encode calls.
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.
Fixed compilation error on oracle for sequence and identity column
``nominvalue`` and ``nomaxvalue`` options that require no space in them.
Improved test compatibility with oracle 18.
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.
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.
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.
Mike Bayer [Mon, 28 Sep 2020 02:40:09 +0000 (22:40 -0400)]
dont use uninstrument event to dispose registry entry
since 450f5c0d6519a439f4025c3892fe4c we've been seeing
errors during the uninstrument_class event where first
we saw an internal weakref being collected earlier than seen,
then fixing that we saw the listener collection changing during
iteration for similar reasons.
we would assume the issue is because of the interaction between
mapper / instrumentation/ registry during a test teardown
and the usage of the uninstrument_class event within this
interaction. this interaction is too fundamental to be
relying upon this event in any case and when I wrote this
new code i was planning on changing that part in any case,
I just forgot.
Mike Bayer [Mon, 28 Sep 2020 03:18:57 +0000 (23:18 -0400)]
build the full compilestate every time
the ORMSelectCompileState was trying to get away with
not building out the "froms" list of the state, but we need
this for select.froms. Build this out and add some tests
for select(), including some other state-oriented use cases.
Mike Bayer [Sun, 27 Sep 2020 15:06:48 +0000 (11:06 -0400)]
Repair erroneous "future" symbol
the change in 1e800285508ecd869c6874fed failed to fully
remove the "future" symbol which then got confused against the
import of the "future" package itself, which is also not needed.
remove it entirely.
pin pytest < 6.1 to see if new error condition may be avoided