]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Create a framework to allow all SQLALCHEMY_WARN_20 to pass
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 17 Aug 2020 21:24:27 +0000 (17:24 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 16 Sep 2020 16:31:05 +0000 (12:31 -0400)
As the test suite has widespread use of many patterns
that are deprecated, enable SQLALCHEMY_WARN_20 globally
for the test suite but then break the warnings filter
out into a whole list of all the individual warnings
we are looking for.  this way individual changesets
can target a specific class of warning, as many of these
warnings will indivdidually affect dozens of files
and potentially hundreds of lines of code.

Many warnings are also resolved here as this
patch started out that way.   From this point
forward there should be changesets that target a
subset of the warnings at a time.

For expediency, updates some migration 2.0 docs
for ORM as well.

Change-Id: I98b8defdf7c37b818b3824d02f7668e3f5f31c94

46 files changed:
doc/build/changelog/migration_20.rst
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/engine/util.py
lib/sqlalchemy/ext/horizontal_shard.py
lib/sqlalchemy/orm/decl_api.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/query.py
lib/sqlalchemy/orm/util.py
lib/sqlalchemy/sql/dml.py
lib/sqlalchemy/sql/selectable.py
lib/sqlalchemy/testing/fixtures.py
lib/sqlalchemy/testing/profiling.py
lib/sqlalchemy/testing/suite/test_insert.py
lib/sqlalchemy/testing/warnings.py
test/dialect/postgresql/test_dialect.py
test/dialect/postgresql/test_query.py
test/dialect/postgresql/test_reflection.py
test/dialect/postgresql/test_types.py
test/engine/test_execute.py
test/orm/inheritance/_poly_fixtures.py
test/orm/inheritance/test_abc_inheritance.py
test/orm/inheritance/test_abc_polymorphic.py
test/orm/inheritance/test_assorted_poly.py
test/orm/inheritance/test_basic.py
test/orm/inheritance/test_concrete.py
test/orm/inheritance/test_magazine.py
test/orm/inheritance/test_manytomany.py
test/orm/inheritance/test_poly_linked_list.py
test/orm/inheritance/test_poly_persistence.py
test/orm/inheritance/test_polymorphic_rel.py
test/orm/inheritance/test_productspec.py
test/orm/inheritance/test_relationship.py
test/orm/inheritance/test_single.py
test/orm/test_deprecations.py
test/sql/test_case_statement.py
test/sql/test_defaults.py
test/sql/test_delete.py
test/sql/test_deprecations.py
test/sql/test_external_traversal.py
test/sql/test_functions.py
test/sql/test_insert.py
test/sql/test_insert_exec.py
test/sql/test_labels.py
test/sql/test_returning.py
test/sql/test_update.py
tox.ini

index 7bb35d42265fe995773fa8f6625e016686bb1f72..04a60ead19ef94bd91d33ba2281bc93a01567631 100644 (file)
@@ -649,101 +649,49 @@ or attribute::
 Declarative becomes a first class API
 =====================================
 
-.. admonition:: Certainty: almost definitely
+.. admonition:: Certainty: definite
 
-  Declarative is already what all the ORM documentation refers towards
-  so it doesn't even make sense that it's an "ext".   The hardest part will
-  be integrating the declarative documentation appropriately.
+  This is now committed in master and the new documenation can be seen at
+  :ref:`orm_mapping_classes_toplevel`.
 
 Declarative will now be part of ``sqlalchemy.orm`` in 2.0, and in 1.4 the
 new version will be present in ``sqlalchemy.future.orm``.   The concept
 of the ``Base`` class will be there as it is now and do the same thing
 it already does, however it will also have some new capabilities.
 
+.. seealso::
 
-The original "mapper()" function removed; replaced with a Declarative compatibility function
-============================================================================================
-
-.. admonition:: Certainty: tentative
-
-  The proposal to have "mapper()" be a sub-function of declarative simplifies
-  the codepaths towards a class becoming mapped.   The "classical mapping"
-  pattern doesn't really have that much usefulness, however as some users have
-  expressed their preference for it, the same code pattern will continue to
-  be available, just on top of declarative.  Hopefully it should be a little
-  nicer even.
-
-Declarative has become very capable and in fact a mapping that is set up with
-declarative may have a superior configuration than one made with ``mapper()`` alone.
-Features that make a declarative mapping superior include:
-
-* The declarative mapping has a reference to the "class registry", which is a
-  local set of classes that can then be accessed configurationally via strings
-  when configuring inter-class relationships.  Put another way, using declarative
-  you can say ``relationship("SomeClass")``, and the string name ``"SomeClass"``
-  is late-resolved to the actual mapped class ``SomeClass``.
-
-* Declarative provides convenience hooks on mapped classes such as
-  ``__declare_first__`` and ``__declare_last__``.   It also allows for
-  mixins and ``__abstract__`` classes which provide for superior organization
-  of classes and attributes.
-
-* Declarative sets parameters on the underlying ``mapper()`` that allow for
-  better behaviors.     A key example is when configuring single table
-  inheritance, and a particular table column is local to a subclass, Declarative
-  automatically sets up ``exclude_columns`` on the base class and other sibling
-  classes that don't include those columns.
-
-* Declarative also ensures that "inherits" is configured appropriately for
-  mappers against inherited classes and checks for several other conditions
-  that can only be determined by the fact that Declarative scans table information
-  from the mapped class itself.
-
-Some of the above Declarative capabilities are lost when one declares their
-mapping using ``__table__``, however the class registry and special hooks
-are still available.  Declarative does not in fact depend on the use of
-a special base class or metaclass, this is just the API that is currently
-used.  An alternative API that behaves just like ``mapper()`` can be defined
-right now as follows::
-
-    # 1.xx code
-
-    from sqlalchemy.ext.declarative import base
-    def declarative_mapper():
-        _decl_class_registry = {}
-
-        def mapper(cls, table, properties={}):
-            cls.__table__ = table
-            cls._decl_class_registry = _decl_class_registry
-            for key, value in properties.items():
-                setattr(cls, key, value)
-            base._as_declarative(cls, cls.__name__, cls.__dict__)
+  :ref:`orm_mapping_classes_toplevel` - all new unified documentation for
+  Declarative, classical mapping, dataclasses, attrs, etc.
 
-        return mapper
 
-    # mapper here is the mapper() function
-    mapper = declarative_mapper()
+The original "mapper()" function now a core element of Declarative, renamed
+===========================================================================
 
-Above, the ``mapper()`` callable is using a class registry that's local
-to where the ``declarative_mapper()`` function was called.   However, we
-can just as easily add the above ``mapper()`` function to any declarative base,
-to make for a pattern such as::
+.. admonition:: Certainty: definite
 
-    from sqlalchemy.future.orm import declarative_base
+  This is now committed in master and the new documenation can be seen at
+  :ref:`orm_mapping_classes_toplevel`.
 
-    base = declarative_base()
+By popular demand, "classical mapping" is staying around, however the new
+form of it is based off of the :class:`_orm.registry` object and is available
+as :meth:`_orm.registry.map_imperatively`.
 
-    class MyClass(object):
-        pass
+In addition, the primary rationale used for "classical mapping" is that of
+keeping the :class:`_schema.Table` setup distinct from the class.  Declarative
+has always allowed this style using so-called
+:ref:`hybrid declarative <orm_imperative_table_configuration>`. However,
+to remove the base class requirement, a first class :ref:`decorator <declarative_config_toplevel>`
+form has been added.
 
-    my_table = Table("my_table", base.metadata, Column('id', Integer, primary_key=True))
+As yet another separate but related enhancement, support for :ref:`Python
+dataclasses <orm_declarative_dataclasses>` is added as well to both
+declarative decorator and classical mapping forms.
 
-    # "classical" mapping:
-    base.mapper(MyClass, my_table)
+.. seealso::
 
-In 2.0, an application that still wishes to use a separate :class:`_schema.Table` and
-does not want to use Declarative with ``__table__``, can instead use the above
-pattern which basically does the same thing.
+  :ref:`orm_mapping_classes_toplevel` - all new unified documentation for
+  Declarative, classical mapping, dataclasses, attrs, etc.
 
 .. _migration_20_unify_select:
 
index 63f2af7ef9624e452ed67e0e0ca202559b226a9f..6aa2e7b14290ab7b92bcd5336019d4ebc4f72c85 100644 (file)
@@ -1350,6 +1350,7 @@ class Connection(Connectable):
             )
 
         dialect = self.dialect
+
         ret = self._execute_context(
             dialect,
             dialect.execution_ctx_cls._init_compiled,
index c1f6bad77953753fd95913b0e4be8301883e55aa..26dd5ddd019c2d4bb4a94d51c848948a7e869c87 100644 (file)
@@ -73,7 +73,6 @@ def py_fallback():
                     # textual statement with positional parameters to
                     # execute().
                     # execute(stmt, ("value", "value"))
-
                     return [zero]
             elif hasattr(zero, "keys"):
                 # execute(stmt, {"key":"value"})
index fe9bbaf02dcf97482e0453785a61db43d316cfb7..220cdbfc8c25f6fb79f05f2d86eb9b508fee4b6f 100644 (file)
@@ -186,8 +186,8 @@ class ShardedSession(Session):
         if shard_id is None:
             shard_id = self._choose_shard_and_assign(mapper, instance)
 
-        if self.transaction is not None:
-            return self.transaction.connection(mapper, shard_id=shard_id)
+        if self.in_transaction():
+            return self.get_transaction().connection(mapper, shard_id=shard_id)
         else:
             return self.get_bind(
                 mapper, shard_id=shard_id, instance=instance
index 68de18c2e4f2975da5c806c24e883bd84c8b30f7..41cc8811237b1d9d8fcd88d72271f334c263a4c1 100644 (file)
@@ -366,7 +366,7 @@ def declarative_base(
     if bind is not None:
         # util.deprecated_params does not work
         util.warn_deprecated_20(
-            'The "bind" argument to declarative_base is'
+            "The ``bind`` argument to declarative_base is "
             "deprecated and will be removed in SQLAlchemy 2.0.",
         )
 
@@ -701,7 +701,7 @@ class registry(object):
 @util.deprecated_params(
     bind=(
         "2.0",
-        'The "bind" argument to declarative_base is'
+        "The ``bind`` argument to as_declarative is "
         "deprecated and will be removed in SQLAlchemy 2.0.",
     )
 )
index db2b94a4eaffb958f625766936a58b40adae3935..821c8a3c895ef1097f7874f41b189aff10461037 100644 (file)
@@ -3014,7 +3014,7 @@ class Mapper(
         cols = []
         for key in col_attribute_names:
             cols.extend(props[key].columns)
-        return sql.select(cols, cond, use_labels=True)
+        return sql.select(*cols).where(cond).apply_labels()
 
     def _iterate_to_target_viawpoly(self, mapper):
         if self.isa(mapper):
index 91a638e4b52501771396740426778d1ceec919fb..9587fcd6ce0bfaca528459479f3a75f1c055fb20 100644 (file)
@@ -2915,7 +2915,7 @@ class Query(
             self.enable_eagerloads(False)
             .add_columns(sql.literal_column("1"))
             .with_labels()
-            .statement.with_only_columns([1])
+            .statement.with_only_columns(1)
         )
 
         ezero = self._entity_from_pre_ent_zero()
@@ -3098,7 +3098,16 @@ class Query(
                     bulk_ud.query = new_query
             self = bulk_ud.query
 
-        upd = sql.update(*self._raw_columns, **update_args).values(values)
+        upd = sql.update(*self._raw_columns)
+
+        ppo = update_args.pop("preserve_parameter_order", False)
+        if ppo:
+            upd = upd.ordered_values(*values)
+        else:
+            upd = upd.values(values)
+        if update_args:
+            upd = upd.with_dialect_options(**update_args)
+
         upd._where_criteria = self._where_criteria
         result = self.session.execute(
             upd,
index f7673e0b7c21166a722cfa00d49f437f9cd35828..2bfba16b5081d9f52e3e411ae24d61a2d1d15544 100644 (file)
@@ -245,13 +245,18 @@ def polymorphic_union(
     result = []
     for type_, table in table_map.items():
         if typecolname is not None:
-            cols = [col(name, table) for name in colnames]
-            cols.append(
-                sql.literal_column(sql_util._quote_ddl_expr(type_)).label(
-                    typecolname
-                ),
+            result.append(
+                sql.select(
+                    *(
+                        [col(name, table) for name in colnames]
+                        + [
+                            sql.literal_column(
+                                sql_util._quote_ddl_expr(type_)
+                            ).label(typecolname)
+                        ]
+                    )
+                ).select_from(table)
             )
-            result.append(sql.select(*cols).select_from(table))
         else:
             result.append(
                 sql.select(
index cd4bc17affc178771c99a5e0753f4f73d0ea33d1..fd2efc6f913c50f5b5c9206b63f421ad37b6ca44 100644 (file)
@@ -215,7 +215,7 @@ class UpdateBase(
                 "The :paramref:`%(func)s.whereclause` parameter "
                 "will be removed "
                 "in SQLAlchemy 2.0.  Please refer to the "
-                ":meth:`.%(classname)s.where` method."
+                ":meth:`%(classname)s.where` method."
             ),
             values=(
                 "The :paramref:`%(func)s.values` parameter will be removed "
@@ -308,8 +308,9 @@ class UpdateBase(
     def _validate_dialect_kwargs_deprecated(self, dialect_kw):
         util.warn_deprecated_20(
             "Passing dialect keyword arguments directly to the "
-            "constructor is deprecated and will be removed in SQLAlchemy "
+            "%s constructor is deprecated and will be removed in SQLAlchemy "
             "2.0.  Please use the ``with_dialect_options()`` method."
+            % (self.__class__.__name__)
         )
         self._validate_dialect_kwargs(dialect_kw)
 
index 0c808e7a7e9519bb5fc0f218ca5473a156432a59..6e0ac1facbcccd79a70593688ccdb427cfb0d3d1 100644 (file)
@@ -4612,7 +4612,7 @@ class Select(
 
         """
         return self.with_only_columns(
-            util.preloaded.sql_util.reduce_columns(
+            *util.preloaded.sql_util.reduce_columns(
                 self._exported_columns_iterator(),
                 only_synonyms=only_synonyms,
                 *(self._where_criteria + self._from_obj)
index 2d3b279172dbe2697fd4bdae28e0e0d8a6a49703..54b1cbb465b6fa5c71139a585e271fddb42de97d 100644 (file)
@@ -330,6 +330,12 @@ class _ORMTest(object):
         sa.orm.clear_mappers()
 
 
+def create_session(**kw):
+    kw.setdefault("autoflush", False)
+    kw.setdefault("expire_on_commit", False)
+    return sa.orm.Session(config.db, **kw)
+
+
 class ORMTest(_ORMTest, TestBase):
     pass
 
index f52827ca596b77d2c5f1032a5e4c1a64531cde44..48e44428bbeffe8baa83b2497f0a37555952ac17 100644 (file)
@@ -241,17 +241,26 @@ def function_call_count(variance=0.05, times=1, warmup=0):
     # likely due to the introduction of __signature__.
 
     from sqlalchemy.util import decorator
+    from sqlalchemy.util import deprecations
+    from sqlalchemy.engine import row
+    from sqlalchemy.testing import mock
 
     @decorator
     def wrap(fn, *args, **kw):
-        for warm in range(warmup):
-            fn(*args, **kw)
-
-        timerange = range(times)
-        with count_functions(variance=variance):
-            for time in timerange:
-                rv = fn(*args, **kw)
-            return rv
+
+        with mock.patch.object(
+            deprecations, "SQLALCHEMY_WARN_20", False
+        ), mock.patch.object(
+            row.LegacyRow, "_default_key_style", row.KEY_OBJECTS_NO_WARN
+        ):
+            for warm in range(warmup):
+                fn(*args, **kw)
+
+            timerange = range(times)
+            with count_functions(variance=variance):
+                for time in timerange:
+                    rv = fn(*args, **kw)
+                return rv
 
     return wrap
 
index 74347cc774308d30e5eab6204a93e21f02b7e0c6..7a7eac02f7b7efcc7dd135d42a4118dc234f511c 100644 (file)
@@ -225,7 +225,9 @@ class InsertBehaviorTest(fixtures.TablesTest):
         )
 
         connection.execute(
-            table.insert(inline=True).from_select(
+            table.insert()
+            .inline()
+            .from_select(
                 ("id", "data"),
                 select(table.c.id + 5, table.c.data).where(
                     table.c.data.in_(["data2", "data3"])
@@ -253,7 +255,9 @@ class InsertBehaviorTest(fixtures.TablesTest):
         )
 
         connection.execute(
-            table.insert(inline=True).from_select(
+            table.insert()
+            .inline()
+            .from_select(
                 ("id", "data"),
                 select(table.c.id + 5, table.c.data).where(
                     table.c.data.in_(["data2", "data3"])
index 298b20c1144e1f32c6b70cd2d861c466836b2cce..de5db6467b0412472cb2a909ac4e9a8047258f08 100644 (file)
@@ -43,6 +43,80 @@ def setup_filters():
         message=r"^The (Sybase|firebird) dialect is deprecated and will be",
     )
 
+    # 2.0 deprecation warnings, which we will want to have all of these
+    # be "error" however for  I98b8defdf7c37b818b3824d02f7668e3f5f31c94
+    # we are moving one at a time
+    for msg in [
+        #
+        # Core execution
+        #
+        r"The (?:Executable|Engine)\.(?:execute|scalar)\(\) function",
+        r"The current statement is being autocommitted using implicit "
+        "autocommit,",
+        r"The connection.execute\(\) method in SQLAlchemy 2.0 will accept "
+        "parameters as a single dictionary or a single sequence of "
+        "dictionaries only.",
+        r"The Connection.connect\(\) function/method is considered legacy",
+        r".*DefaultGenerator.execute\(\)",
+        #
+        # result sets
+        #
+        r"The Row.keys\(\) function/method",
+        r"Using non-integer/slice indices on Row ",
+        #
+        # Core SQL constructs
+        #
+        r"The FromClause\.select\(\).whereclause parameter is deprecated",
+        r"Set functions such as union\(\), union_all\(\), extract\(\),",
+        r"The legacy calling style of select\(\) is deprecated and will be "
+        "removed",
+        r"The FromClause.select\(\) method will no longer accept keyword "
+        "arguments in version 2.0",
+        r"The Join.select\(\) method will no longer accept keyword arguments "
+        "in version 2.0.",
+        r"The \"whens\" argument to case\(\) is now passed",
+        r"The Join.select\(\).whereclause parameter is deprecated",
+        #
+        # DML
+        #
+        r"The (?:update|delete).whereclause parameter will be removed in "
+        "SQLAlchemy 2.0.",
+        r"The (?:insert|update).values parameter will be removed in "
+        "SQLAlchemy 2.0.",
+        r"The update.preserve_parameter_order parameter will be removed in "
+        "SQLAlchemy 2.0.",
+        r"Passing dialect keyword arguments directly to the "
+        "(?:Insert|Update|Delete) constructor",
+        #
+        # ORM configuration
+        #
+        r"Calling the mapper\(\) function directly outside of a "
+        "declarative registry",
+        r"The ``declarative_base\(\)`` function is now available ",
+        r"The ``has_inherited_table\(\)`` function is now available",
+        r"The ``bind`` argument to declarative_base is deprecated and will "
+        "be removed in SQLAlchemy 2.0.",
+        #
+        # ORM Query
+        #
+        r"The Query\.get\(\) function",
+        r"The Query\.from_self\(\) function",
+        #
+        # ORM Session
+        #
+        r"The Session.autocommit parameter is deprecated ",
+        r".*object is being merged into a Session along the backref "
+        "cascade path",
+        r"Passing bind arguments to Session.execute\(\) as keyword arguments",
+        r"The Session.transaction function/method",
+        r"The merge_result\(\) method is superseded by the "
+        r"merge_frozen_result\(\)",
+        r"The Session.begin.subtransactions flag is deprecated",
+    ]:
+        warnings.filterwarnings(
+            "ignore", message=msg, category=sa_exc.RemovedIn20Warning,
+        )
+
     try:
         import pytest
     except ImportError:
index 13df1ce0fbc25665b20adcf068a92cac4bfb996f..971d4f12f71af06dfd85272cc513c7c6cb8fe47c 100644 (file)
@@ -556,13 +556,17 @@ class ExecutemanyValuesInsertsTest(ExecuteManyMode, fixtures.TablesTest):
 
         t = self.tables.data
 
-        ins = t.insert(inline=True).values(
-            id=bindparam("id"),
-            x=select(literal_column("5"))
-            .select_from(self.tables.data)
-            .scalar_subquery(),
-            y=bindparam("y"),
-            z=bindparam("z"),
+        ins = (
+            t.insert()
+            .inline()
+            .values(
+                id=bindparam("id"),
+                x=select(literal_column("5"))
+                .select_from(self.tables.data)
+                .scalar_subquery(),
+                y=bindparam("y"),
+                z=bindparam("z"),
+            )
         )
         # compiled SQL has a newline in it
         eq_(
@@ -608,13 +612,17 @@ class ExecutemanyValuesInsertsTest(ExecuteManyMode, fixtures.TablesTest):
 
         t = self.tables.data
 
-        ins = t.insert(inline=True).values(
-            id=bindparam("id"),
-            x=select(literal_column("5"))
-            .select_from(self.tables.data)
-            .scalar_subquery(),
-            y=bindparam("y"),
-            z=bindparam("z"),
+        ins = (
+            t.insert()
+            .inline()
+            .values(
+                id=bindparam("id"),
+                x=select(literal_column("5"))
+                .select_from(self.tables.data)
+                .scalar_subquery(),
+                y=bindparam("y"),
+                z=bindparam("z"),
+            )
         )
         # compiled SQL has a newline in it
         eq_(
index eec6eed4a9cbe672619a664e1261695e4849215d..3484fa4c33cd4947fd12c52417f5f4b4152c8b12 100644 (file)
@@ -194,13 +194,11 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
 
                 # single execute, explicit id, inline
 
-                conn.execute(
-                    table.insert(inline=True), {"id": 33, "data": "d7"}
-                )
+                conn.execute(table.insert().inline(), {"id": 33, "data": "d7"})
 
                 # single execute, inline, uses SERIAL
 
-                conn.execute(table.insert(inline=True), {"data": "d8"})
+                conn.execute(table.insert().inline(), {"data": "d8"})
 
         asserter.assert_(
             DialectSQL(
@@ -262,10 +260,8 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
                     {"id": 32, "data": "d4"},
                 )
                 conn.execute(table.insert(), {"data": "d5"}, {"data": "d6"})
-                conn.execute(
-                    table.insert(inline=True), {"id": 33, "data": "d7"}
-                )
-                conn.execute(table.insert(inline=True), {"data": "d8"})
+                conn.execute(table.insert().inline(), {"id": 33, "data": "d7"})
+                conn.execute(table.insert().inline(), {"data": "d8"})
 
         asserter.assert_(
             DialectSQL(
@@ -338,13 +334,11 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
 
                 # single execute, explicit id, inline
 
-                conn.execute(
-                    table.insert(inline=True), {"id": 33, "data": "d7"}
-                )
+                conn.execute(table.insert().inline(), {"id": 33, "data": "d7"})
 
                 # single execute, inline, uses SERIAL
 
-                conn.execute(table.insert(inline=True), {"data": "d8"})
+                conn.execute(table.insert().inline(), {"data": "d8"})
 
         asserter.assert_(
             DialectSQL(
@@ -406,10 +400,8 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
                     {"id": 32, "data": "d4"},
                 )
                 conn.execute(table.insert(), {"data": "d5"}, {"data": "d6"})
-                conn.execute(
-                    table.insert(inline=True), {"id": 33, "data": "d7"}
-                )
-                conn.execute(table.insert(inline=True), {"data": "d8"})
+                conn.execute(table.insert().inline(), {"id": 33, "data": "d7"})
+                conn.execute(table.insert().inline(), {"data": "d8"})
 
         asserter.assert_(
             DialectSQL(
@@ -467,10 +459,8 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
                     {"id": 32, "data": "d4"},
                 )
                 conn.execute(table.insert(), {"data": "d5"}, {"data": "d6"})
-                conn.execute(
-                    table.insert(inline=True), {"id": 33, "data": "d7"}
-                )
-                conn.execute(table.insert(inline=True), {"data": "d8"})
+                conn.execute(table.insert().inline(), {"id": 33, "data": "d7"})
+                conn.execute(table.insert().inline(), {"data": "d8"})
 
         asserter.assert_(
             DialectSQL(
@@ -532,10 +522,8 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
                     {"id": 32, "data": "d4"},
                 )
                 conn.execute(table.insert(), {"data": "d5"}, {"data": "d6"})
-                conn.execute(
-                    table.insert(inline=True), {"id": 33, "data": "d7"}
-                )
-                conn.execute(table.insert(inline=True), {"data": "d8"})
+                conn.execute(table.insert().inline(), {"id": 33, "data": "d7"})
+                conn.execute(table.insert().inline(), {"data": "d8"})
 
         asserter.assert_(
             DialectSQL(
@@ -634,7 +622,7 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
                 table.insert(),
                 [{"id": 31, "data": "d2"}, {"id": 32, "data": "d3"}],
             )
-            conn.execute(table.insert(inline=True), {"id": 33, "data": "d4"})
+            conn.execute(table.insert().inline(), {"id": 33, "data": "d4"})
             eq_(
                 conn.execute(table.select()).fetchall(),
                 [(30, "d1"), (31, "d2"), (32, "d3"), (33, "d4")],
@@ -671,7 +659,7 @@ class InsertTest(fixtures.TestBase, AssertsExecutionResults):
                 table.insert(),
                 [{"id": 31, "data": "d2"}, {"id": 32, "data": "d3"}],
             )
-            conn.execute(table.insert(inline=True), {"id": 33, "data": "d4"})
+            conn.execute(table.insert().inline(), {"id": 33, "data": "d4"})
             eq_(
                 conn.execute(table.select()).fetchall(),
                 [(30, "d1"), (31, "d2"), (32, "d3"), (33, "d4")],
index 263684e1286815ef66ba60ef94e466d034a85761..b8de35f421ee3b7d58066d26e715fe828d77b41b 100644 (file)
@@ -1193,7 +1193,7 @@ class ReflectionTest(AssertsCompiledSQL, fixtures.TestBase):
         )
         metadata.create_all()
         with testing.db.connect() as conn:
-            conn.execute("CREATE INDEX idx1 ON t (x) INCLUDE (name)")
+            conn.exec_driver_sql("CREATE INDEX idx1 ON t (x) INCLUDE (name)")
 
             # prior to #5205, this would return:
             # [{'column_names': ['x', 'name'],
index 2d1fd4ee89e438d6b8e5252b3d035d97d0c62e58..f13f251326140cdd82c6038634c75dd52eb99567 100644 (file)
@@ -3157,36 +3157,31 @@ class JSONRoundTripTest(fixtures.TablesTest):
         ).fetchall()
         eq_([d for d, in data], [None])
 
-    def _test_insert(self, engine):
-        with engine.connect() as conn:
-            conn.execute(
-                self.tables.data_table.insert(),
-                {"name": "r1", "data": {"k1": "r1v1", "k2": "r1v2"}},
-            )
-            self._assert_data([{"k1": "r1v1", "k2": "r1v2"}], conn)
+    def _test_insert(self, conn):
+        conn.execute(
+            self.tables.data_table.insert(),
+            {"name": "r1", "data": {"k1": "r1v1", "k2": "r1v2"}},
+        )
+        self._assert_data([{"k1": "r1v1", "k2": "r1v2"}], conn)
 
-    def _test_insert_nulls(self, engine):
-        with engine.connect() as conn:
-            conn.execute(
-                self.tables.data_table.insert(), {"name": "r1", "data": null()}
-            )
-            self._assert_data([None], conn)
+    def _test_insert_nulls(self, conn):
+        conn.execute(
+            self.tables.data_table.insert(), {"name": "r1", "data": null()}
+        )
+        self._assert_data([None], conn)
 
-    def _test_insert_none_as_null(self, engine):
-        with engine.connect() as conn:
-            conn.execute(
-                self.tables.data_table.insert(),
-                {"name": "r1", "nulldata": None},
-            )
-            self._assert_column_is_NULL(conn, column="nulldata")
+    def _test_insert_none_as_null(self, conn):
+        conn.execute(
+            self.tables.data_table.insert(), {"name": "r1", "nulldata": None},
+        )
+        self._assert_column_is_NULL(conn, column="nulldata")
 
-    def _test_insert_nulljson_into_none_as_null(self, engine):
-        with engine.connect() as conn:
-            conn.execute(
-                self.tables.data_table.insert(),
-                {"name": "r1", "nulldata": JSON.NULL},
-            )
-            self._assert_column_is_JSON_NULL(conn, column="nulldata")
+    def _test_insert_nulljson_into_none_as_null(self, conn):
+        conn.execute(
+            self.tables.data_table.insert(),
+            {"name": "r1", "nulldata": JSON.NULL},
+        )
+        self._assert_column_is_JSON_NULL(conn, column="nulldata")
 
     def test_reflect(self):
         insp = inspect(testing.db)
index 3a4b58df6d3cc2737290cf4d9ce459ecd542fb7c..7e3893afddf2bce318ac7110c810ea49b80defe0 100644 (file)
@@ -351,6 +351,7 @@ class ExecuteTest(fixtures.TablesTest):
 
     def test_stmt_exception_bytestring_raised(self):
         name = util.u("méil")
+        users = self.tables.users
         with testing.db.connect() as conn:
             assert_raises_message(
                 tsa.exc.StatementError,
@@ -3120,13 +3121,15 @@ class AutocommitKeywordFixture(object):
         with engine.connect() as conn:
             conn.exec_driver_sql("%s something table something" % keyword)
 
-            for _call in dbapi.connect().mock_calls:
-                _call.kwargs.clear()
-
             if expected:
-                eq_(dbapi.connect().mock_calls, [call.cursor(), call.commit()])
+                eq_(
+                    [n for (n, k, s) in dbapi.connect().mock_calls],
+                    ["cursor", "commit"],
+                )
             else:
-                eq_(dbapi.connect().mock_calls, [call.cursor()])
+                eq_(
+                    [n for (n, k, s) in dbapi.connect().mock_calls], ["cursor"]
+                )
 
 
 class AutocommitTextTest(AutocommitKeywordFixture, fixtures.TestBase):
index 77564bcdb4dc3b4eee3ad92072287c3dd934dbe1..4253b4bee6cc73f1ea41f6cb8daf1b958372e79a 100644 (file)
@@ -2,9 +2,9 @@ from sqlalchemy import ForeignKey
 from sqlalchemy import Integer
 from sqlalchemy import String
 from sqlalchemy import util
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import polymorphic_union
 from sqlalchemy.orm import relationship
+from sqlalchemy.orm import sessionmaker
 from sqlalchemy.sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
 from sqlalchemy.testing import AssertsCompiledSQL
 from sqlalchemy.testing import config
@@ -221,11 +221,9 @@ class _PolymorphicFixtureBase(fixtures.MappedTest, AssertsCompiledSQL):
         cls.c2 = c2 = Company(name="Elbonia, Inc.")
         c2.employees = [e3]
 
-        sess = create_session(connection)
-        sess.add(c1)
-        sess.add(c2)
-        sess.flush()
-        sess.expunge_all()
+        with sessionmaker(connection, expire_on_commit=False).begin() as sess:
+            sess.add(c1)
+            sess.add(c2)
 
         cls.all_employees = [e1, e2, b1, m1, e3]
         cls.c1_employees = [e1, e2, b1, m1]
index b5bff78d24db83a44cba6f2516b793aaf28e6b40..60c488be36904b96a04e891302546641c3dd07fc 100644 (file)
 from sqlalchemy import ForeignKey
 from sqlalchemy import Integer
 from sqlalchemy import String
+from sqlalchemy import testing
 from sqlalchemy.orm import class_mapper
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import polymorphic_union
 from sqlalchemy.orm import relationship
 from sqlalchemy.orm.interfaces import MANYTOONE
 from sqlalchemy.orm.interfaces import ONETOMANY
 from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
 
-def produce_test(parent, child, direction):
-    """produce a testcase for A->B->C inheritance with a self-referential
-    relationship between two of the classes, using either one-to-many or
-    many-to-one.
+def _combinations():
+    for parent in ["a", "b", "c"]:
+        for child in ["a", "b", "c"]:
+            for direction in [ONETOMANY, MANYTOONE]:
+
+                name = "Test%sTo%s%s" % (
+                    parent,
+                    child,
+                    (direction is ONETOMANY and "O2M" or "M2O"),
+                )
+                yield (name, parent, child, direction)
 
-    the old "no discriminator column" pattern is used.
 
-    """
+@testing.combinations(
+    *list(_combinations()), argnames="name,parent,child,direction", id_="saaa"
+)
+class ABCTest(fixtures.MappedTest):
+    @classmethod
+    def define_tables(cls, metadata):
+        parent, child, direction = cls.parent, cls.child, cls.direction
 
-    class ABCTest(fixtures.MappedTest):
-        @classmethod
-        def define_tables(cls, metadata):
-            global ta, tb, tc
-            ta = ["a", metadata]
+        ta = ["a", metadata]
+        ta.append(
+            Column(
+                "id", Integer, primary_key=True, test_needs_autoincrement=True,
+            )
+        ),
+        ta.append(Column("a_data", String(30)))
+        if "a" == parent and direction == MANYTOONE:
             ta.append(
                 Column(
-                    "id",
+                    "child_id",
                     Integer,
-                    primary_key=True,
-                    test_needs_autoincrement=True,
-                )
-            ),
-            ta.append(Column("a_data", String(30)))
-            if "a" == parent and direction == MANYTOONE:
-                ta.append(
-                    Column(
-                        "child_id",
-                        Integer,
-                        ForeignKey(
-                            "%s.id" % child, use_alter=True, name="foo"
-                        ),
-                    )
+                    ForeignKey("%s.id" % child, use_alter=True, name="foo"),
                 )
-            elif "a" == child and direction == ONETOMANY:
-                ta.append(
-                    Column(
-                        "parent_id",
-                        Integer,
-                        ForeignKey(
-                            "%s.id" % parent, use_alter=True, name="foo"
-                        ),
-                    )
+            )
+        elif "a" == child and direction == ONETOMANY:
+            ta.append(
+                Column(
+                    "parent_id",
+                    Integer,
+                    ForeignKey("%s.id" % parent, use_alter=True, name="foo"),
                 )
-            ta = Table(*ta)
-
-            tb = ["b", metadata]
-            tb.append(
-                Column("id", Integer, ForeignKey("a.id"), primary_key=True)
             )
+        ta = Table(*ta)
 
-            tb.append(Column("b_data", String(30)))
-
-            if "b" == parent and direction == MANYTOONE:
-                tb.append(
-                    Column(
-                        "child_id",
-                        Integer,
-                        ForeignKey(
-                            "%s.id" % child, use_alter=True, name="foo"
-                        ),
-                    )
-                )
-            elif "b" == child and direction == ONETOMANY:
-                tb.append(
-                    Column(
-                        "parent_id",
-                        Integer,
-                        ForeignKey(
-                            "%s.id" % parent, use_alter=True, name="foo"
-                        ),
-                    )
-                )
-            tb = Table(*tb)
+        tb = ["b", metadata]
+        tb.append(Column("id", Integer, ForeignKey("a.id"), primary_key=True))
 
-            tc = ["c", metadata]
-            tc.append(
-                Column("id", Integer, ForeignKey("b.id"), primary_key=True)
-            )
+        tb.append(Column("b_data", String(30)))
 
-            tc.append(Column("c_data", String(30)))
-
-            if "c" == parent and direction == MANYTOONE:
-                tc.append(
-                    Column(
-                        "child_id",
-                        Integer,
-                        ForeignKey(
-                            "%s.id" % child, use_alter=True, name="foo"
-                        ),
-                    )
-                )
-            elif "c" == child and direction == ONETOMANY:
-                tc.append(
-                    Column(
-                        "parent_id",
-                        Integer,
-                        ForeignKey(
-                            "%s.id" % parent, use_alter=True, name="foo"
-                        ),
-                    )
+        if "b" == parent and direction == MANYTOONE:
+            tb.append(
+                Column(
+                    "child_id",
+                    Integer,
+                    ForeignKey("%s.id" % child, use_alter=True, name="foo"),
                 )
-            tc = Table(*tc)
-
-        def teardown(self):
-            if direction == MANYTOONE:
-                parent_table = {"a": ta, "b": tb, "c": tc}[parent]
-                parent_table.update(
-                    values={parent_table.c.child_id: None}
-                ).execute()
-            elif direction == ONETOMANY:
-                child_table = {"a": ta, "b": tb, "c": tc}[child]
-                child_table.update(
-                    values={child_table.c.parent_id: None}
-                ).execute()
-            super(ABCTest, self).teardown()
-
-        def test_roundtrip(self):
-            parent_table = {"a": ta, "b": tb, "c": tc}[parent]
-            child_table = {"a": ta, "b": tb, "c": tc}[child]
-
-            remote_side = None
-
-            if direction == MANYTOONE:
-                foreign_keys = [parent_table.c.child_id]
-            elif direction == ONETOMANY:
-                foreign_keys = [child_table.c.parent_id]
-
-            atob = ta.c.id == tb.c.id
-            btoc = tc.c.id == tb.c.id
-
-            if direction == ONETOMANY:
-                relationshipjoin = parent_table.c.id == child_table.c.parent_id
-            elif direction == MANYTOONE:
-                relationshipjoin = parent_table.c.child_id == child_table.c.id
-                if parent is child:
-                    remote_side = [child_table.c.id]
-
-            abcjoin = polymorphic_union(
-                {
-                    "a": ta.select(
-                        tb.c.id == None,  # noqa
-                        from_obj=[ta.outerjoin(tb, onclause=atob)],
-                    ).subquery(),
-                    "b": ta.join(tb, onclause=atob)
-                    .outerjoin(tc, onclause=btoc)
-                    .select(tc.c.id == None)
-                    .reduce_columns()
-                    .subquery(),  # noqa
-                    "c": tc.join(tb, onclause=btoc).join(ta, onclause=atob),
-                },
-                "type",
-                "abcjoin",
             )
-
-            bcjoin = polymorphic_union(
-                {
-                    "b": ta.join(tb, onclause=atob)
-                    .outerjoin(tc, onclause=btoc)
-                    .select(tc.c.id == None)
-                    .reduce_columns()
-                    .subquery(),  # noqa
-                    "c": tc.join(tb, onclause=btoc).join(ta, onclause=atob),
-                },
-                "type",
-                "bcjoin",
+        elif "b" == child and direction == ONETOMANY:
+            tb.append(
+                Column(
+                    "parent_id",
+                    Integer,
+                    ForeignKey("%s.id" % parent, use_alter=True, name="foo"),
+                )
             )
+        tb = Table(*tb)
 
-            class A(object):
-                def __init__(self, name):
-                    self.a_data = name
+        tc = ["c", metadata]
+        tc.append(Column("id", Integer, ForeignKey("b.id"), primary_key=True))
 
-            class B(A):
-                pass
+        tc.append(Column("c_data", String(30)))
 
-            class C(B):
-                pass
-
-            mapper(
-                A,
-                ta,
-                polymorphic_on=abcjoin.c.type,
-                with_polymorphic=("*", abcjoin),
-                polymorphic_identity="a",
-            )
-            mapper(
-                B,
-                tb,
-                polymorphic_on=bcjoin.c.type,
-                with_polymorphic=("*", bcjoin),
-                polymorphic_identity="b",
-                inherits=A,
-                inherit_condition=atob,
-            )
-            mapper(
-                C,
-                tc,
-                polymorphic_identity="c",
-                with_polymorphic=("*", tc.join(tb, btoc).join(ta, atob)),
-                inherits=B,
-                inherit_condition=btoc,
+        if "c" == parent and direction == MANYTOONE:
+            tc.append(
+                Column(
+                    "child_id",
+                    Integer,
+                    ForeignKey("%s.id" % child, use_alter=True, name="foo"),
+                )
             )
-
-            parent_mapper = class_mapper({ta: A, tb: B, tc: C}[parent_table])
-            child_mapper = class_mapper({ta: A, tb: B, tc: C}[child_table])
-
-            parent_class = parent_mapper.class_
-            child_class = child_mapper.class_
-
-            parent_mapper.add_property(
-                "collection",
-                relationship(
-                    child_mapper,
-                    primaryjoin=relationshipjoin,
-                    foreign_keys=foreign_keys,
-                    order_by=child_mapper.c.id,
-                    remote_side=remote_side,
-                    uselist=True,
-                ),
+        elif "c" == child and direction == ONETOMANY:
+            tc.append(
+                Column(
+                    "parent_id",
+                    Integer,
+                    ForeignKey("%s.id" % parent, use_alter=True, name="foo"),
+                )
             )
-
-            sess = create_session()
-
-            parent_obj = parent_class("parent1")
-            child_obj = child_class("child1")
-            somea = A("somea")
-            someb = B("someb")
-            somec = C("somec")
-
-            # print "APPENDING", parent.__class__.__name__ , "TO",
-            # child.__class__.__name__
-
-            sess.add(parent_obj)
-            parent_obj.collection.append(child_obj)
-            if direction == ONETOMANY:
-                child2 = child_class("child2")
-                parent_obj.collection.append(child2)
-                sess.add(child2)
-            elif direction == MANYTOONE:
-                parent2 = parent_class("parent2")
-                parent2.collection.append(child_obj)
-                sess.add(parent2)
-            sess.add(somea)
-            sess.add(someb)
-            sess.add(somec)
-            sess.flush()
-            sess.expunge_all()
-
-            # assert result via direct get() of parent object
-            result = sess.query(parent_class).get(parent_obj.id)
-            assert result.id == parent_obj.id
-            assert result.collection[0].id == child_obj.id
-            if direction == ONETOMANY:
-                assert result.collection[1].id == child2.id
-            elif direction == MANYTOONE:
-                result2 = sess.query(parent_class).get(parent2.id)
-                assert result2.id == parent2.id
-                assert result2.collection[0].id == child_obj.id
-
-            sess.expunge_all()
-
-            # assert result via polymorphic load of parent object
-            result = sess.query(A).filter_by(id=parent_obj.id).one()
-            assert result.id == parent_obj.id
-            assert result.collection[0].id == child_obj.id
-            if direction == ONETOMANY:
-                assert result.collection[1].id == child2.id
-            elif direction == MANYTOONE:
-                result2 = sess.query(A).filter_by(id=parent2.id).one()
-                assert result2.id == parent2.id
-                assert result2.collection[0].id == child_obj.id
-
-    ABCTest.__name__ = "Test%sTo%s%s" % (
-        parent,
-        child,
-        (direction is ONETOMANY and "O2M" or "M2O"),
-    )
-    return ABCTest
-
-
-# test all combinations of polymorphic a/b/c related to another of a/b/c
-for parent in ["a", "b", "c"]:
-    for child in ["a", "b", "c"]:
-        for direction in [ONETOMANY, MANYTOONE]:
-            testclass = produce_test(parent, child, direction)
-            exec("%s = testclass" % testclass.__name__)
-            del testclass
-
-del produce_test
+        tc = Table(*tc)
+
+    @classmethod
+    def setup_mappers(cls):
+        parent, child, direction = cls.parent, cls.child, cls.direction
+        ta, tb, tc = cls.tables("a", "b", "c")
+        parent_table = {"a": ta, "b": tb, "c": tc}[parent]
+        child_table = {"a": ta, "b": tb, "c": tc}[child]
+
+        remote_side = None
+
+        if direction == MANYTOONE:
+            foreign_keys = [parent_table.c.child_id]
+        elif direction == ONETOMANY:
+            foreign_keys = [child_table.c.parent_id]
+
+        atob = ta.c.id == tb.c.id
+        btoc = tc.c.id == tb.c.id
+
+        if direction == ONETOMANY:
+            relationshipjoin = parent_table.c.id == child_table.c.parent_id
+        elif direction == MANYTOONE:
+            relationshipjoin = parent_table.c.child_id == child_table.c.id
+            if parent is child:
+                remote_side = [child_table.c.id]
+
+        abcjoin = polymorphic_union(
+            {
+                "a": ta.select()
+                .where(tb.c.id == None)  # noqa
+                .select_from(ta.outerjoin(tb, onclause=atob))
+                .subquery(),
+                "b": ta.join(tb, onclause=atob)
+                .outerjoin(tc, onclause=btoc)
+                .select()
+                .where(tc.c.id == None)
+                .reduce_columns()
+                .subquery(),  # noqa
+                "c": tc.join(tb, onclause=btoc).join(ta, onclause=atob),
+            },
+            "type",
+            "abcjoin",
+        )
+
+        bcjoin = polymorphic_union(
+            {
+                "b": ta.join(tb, onclause=atob)
+                .outerjoin(tc, onclause=btoc)
+                .select()
+                .where(tc.c.id == None)
+                .reduce_columns()
+                .subquery(),  # noqa
+                "c": tc.join(tb, onclause=btoc).join(ta, onclause=atob),
+            },
+            "type",
+            "bcjoin",
+        )
+
+        class A(cls.Comparable):
+            def __init__(self, name):
+                self.a_data = name
+
+        class B(A):
+            pass
+
+        class C(B):
+            pass
+
+        mapper(
+            A,
+            ta,
+            polymorphic_on=abcjoin.c.type,
+            with_polymorphic=("*", abcjoin),
+            polymorphic_identity="a",
+        )
+        mapper(
+            B,
+            tb,
+            polymorphic_on=bcjoin.c.type,
+            with_polymorphic=("*", bcjoin),
+            polymorphic_identity="b",
+            inherits=A,
+            inherit_condition=atob,
+        )
+        mapper(
+            C,
+            tc,
+            polymorphic_identity="c",
+            with_polymorphic=("*", tc.join(tb, btoc).join(ta, atob)),
+            inherits=B,
+            inherit_condition=btoc,
+        )
+
+        parent_mapper = class_mapper({ta: A, tb: B, tc: C}[parent_table])
+        child_mapper = class_mapper({ta: A, tb: B, tc: C}[child_table])
+
+        parent_mapper.add_property(
+            "collection",
+            relationship(
+                child_mapper,
+                primaryjoin=relationshipjoin,
+                foreign_keys=foreign_keys,
+                order_by=child_mapper.c.id,
+                remote_side=remote_side,
+                uselist=True,
+            ),
+        )
+
+    def test_roundtrip(self):
+        parent, child, direction = self.parent, self.child, self.direction
+        A, B, C = self.classes("A", "B", "C")
+        parent_class = {"a": A, "b": B, "c": C}[parent]
+        child_class = {"a": A, "b": B, "c": C}[child]
+
+        sess = create_session()
+
+        parent_obj = parent_class("parent1")
+        child_obj = child_class("child1")
+        somea = A("somea")
+        someb = B("someb")
+        somec = C("somec")
+
+        # print "APPENDING", parent.__class__.__name__ , "TO",
+        # child.__class__.__name__
+
+        sess.add(parent_obj)
+        parent_obj.collection.append(child_obj)
+        if direction == ONETOMANY:
+            child2 = child_class("child2")
+            parent_obj.collection.append(child2)
+            sess.add(child2)
+        elif direction == MANYTOONE:
+            parent2 = parent_class("parent2")
+            parent2.collection.append(child_obj)
+            sess.add(parent2)
+        sess.add(somea)
+        sess.add(someb)
+        sess.add(somec)
+        sess.commit()
+        sess.close()
+
+        # assert result via direct get() of parent object
+        result = sess.get(parent_class, parent_obj.id)
+        assert result.id == parent_obj.id
+        assert result.collection[0].id == child_obj.id
+        if direction == ONETOMANY:
+            assert result.collection[1].id == child2.id
+        elif direction == MANYTOONE:
+            result2 = sess.get(parent_class, parent2.id)
+            assert result2.id == parent2.id
+            assert result2.collection[0].id == child_obj.id
+
+        sess.expunge_all()
+
+        # assert result via polymorphic load of parent object
+        result = sess.query(A).filter_by(id=parent_obj.id).one()
+        assert result.id == parent_obj.id
+        assert result.collection[0].id == child_obj.id
+        if direction == ONETOMANY:
+            assert result.collection[1].id == child2.id
+        elif direction == MANYTOONE:
+            result2 = sess.query(A).filter_by(id=parent2.id).one()
+            assert result2.id == parent2.id
+            assert result2.collection[0].id == child_obj.id
index cf06c9e263c8ae781326cab30e68699a6ae56cfc..0d28ef342d57bdd14893c15132bc008a67b7a097 100644 (file)
@@ -2,10 +2,10 @@ from sqlalchemy import ForeignKey
 from sqlalchemy import Integer
 from sqlalchemy import String
 from sqlalchemy import testing
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import mapper
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
index fe688059135a35b233dd81fda309bf6c8de650e3..2767607cb0ad58fb67254d02b71eb2e3d447f512 100644 (file)
@@ -16,18 +16,19 @@ from sqlalchemy import util
 from sqlalchemy.orm import class_mapper
 from sqlalchemy.orm import column_property
 from sqlalchemy.orm import contains_eager
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import join
 from sqlalchemy.orm import joinedload
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import polymorphic_union
 from sqlalchemy.orm import relationship
 from sqlalchemy.orm import Session
+from sqlalchemy.orm import sessionmaker
 from sqlalchemy.orm import with_polymorphic
 from sqlalchemy.orm.interfaces import MANYTOONE
 from sqlalchemy.testing import AssertsExecutionResults
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
@@ -115,8 +116,8 @@ class RelationshipTest1(fixtures.MappedTest):
         session.flush()
         session.expunge_all()
 
-        p = session.query(Person).get(p.person_id)
-        m = session.query(Manager).get(m.person_id)
+        p = session.get(Person, p.person_id)
+        m = session.get(Manager, m.person_id)
         assert p.manager is m
 
     def test_descendant_refs_parent(self):
@@ -147,8 +148,8 @@ class RelationshipTest1(fixtures.MappedTest):
         session.flush()
         session.expunge_all()
 
-        p = session.query(Person).get(p.person_id)
-        m = session.query(Manager).get(m.person_id)
+        p = session.get(Person, p.person_id)
+        m = session.get(Manager, m.person_id)
         assert m.employee is p
 
 
@@ -215,9 +216,9 @@ class RelationshipTest2(fixtures.MappedTest):
         if jointype == "join1":
             poly_union = polymorphic_union(
                 {
-                    "person": people.select(
-                        people.c.type == "person"
-                    ).subquery(),
+                    "person": people.select()
+                    .where(people.c.type == "person")
+                    .subquery(),
                     "manager": join(
                         people,
                         managers,
@@ -230,9 +231,9 @@ class RelationshipTest2(fixtures.MappedTest):
         elif jointype == "join2":
             poly_union = polymorphic_union(
                 {
-                    "person": people.select(
-                        people.c.type == "person"
-                    ).subquery(),
+                    "person": people.select()
+                    .where(people.c.type == "person")
+                    .subquery(),
                     "manager": managers.join(
                         people, people.c.person_id == managers.c.person_id
                     ),
@@ -306,8 +307,8 @@ class RelationshipTest2(fixtures.MappedTest):
         sess.flush()
 
         sess.expunge_all()
-        p = sess.query(Person).get(p.person_id)
-        m = sess.query(Manager).get(m.person_id)
+        p = sess.get(Person, p.person_id)
+        m = sess.get(Manager, m.person_id)
         assert m.colleague is p
         if usedata:
             assert m.data.data == "ms data"
@@ -377,9 +378,9 @@ class RelationshipTest3(fixtures.MappedTest):
                     "manager": managers.join(
                         people, people.c.person_id == managers.c.person_id
                     ),
-                    "person": people.select(
-                        people.c.type == "person"
-                    ).subquery(),
+                    "person": people.select()
+                    .where(people.c.type == "person")
+                    .subquery(),
                 },
                 None,
             )
@@ -391,9 +392,9 @@ class RelationshipTest3(fixtures.MappedTest):
                         managers,
                         people.c.person_id == managers.c.person_id,
                     ),
-                    "person": people.select(
-                        people.c.type == "person"
-                    ).subquery(),
+                    "person": people.select()
+                    .where(people.c.type == "person")
+                    .subquery(),
                 },
                 None,
             )
@@ -477,10 +478,10 @@ class RelationshipTest3(fixtures.MappedTest):
         sess.flush()
 
         sess.expunge_all()
-        p = sess.query(Person).get(p.person_id)
-        p2 = sess.query(Person).get(p2.person_id)
-        p3 = sess.query(Person).get(p3.person_id)
-        m = sess.query(Person).get(m.person_id)
+        p = sess.get(Person, p.person_id)
+        p2 = sess.get(Person, p2.person_id)
+        p3 = sess.get(Person, p3.person_id)
+        m = sess.get(Person, m.person_id)
         assert len(p.colleagues) == 1
         assert p.colleagues == [p2]
         assert m.colleagues == [p3]
@@ -635,17 +636,15 @@ class RelationshipTest4(fixtures.MappedTest):
         session.expunge_all()
 
         def go():
-            testcar = (
-                session.query(Car)
-                .options(joinedload("employee"))
-                .get(car1.car_id)
+            testcar = session.get(
+                Car, car1.car_id, options=[joinedload("employee")]
             )
             assert str(testcar.employee) == "Engineer E4, status X"
 
         self.assert_sql_count(testing.db, go, 1)
 
-        car1 = session.query(Car).get(car1.car_id)
-        usingGet = session.query(person_mapper).get(car1.owner)
+        car1 = session.get(Car, car1.car_id)
+        usingGet = session.get(person_mapper, car1.owner)
         usingProperty = car1.employee
 
         assert str(engineer4) == "Engineer E4, status X"
@@ -656,10 +655,8 @@ class RelationshipTest4(fixtures.MappedTest):
         # and now for the lightning round, eager !
 
         def go():
-            testcar = (
-                session.query(Car)
-                .options(joinedload("employee"))
-                .get(car1.car_id)
+            testcar = session.get(
+                Car, car1.car_id, options=[joinedload("employee")],
             )
             assert str(testcar.employee) == "Engineer E4, status X"
 
@@ -864,8 +861,8 @@ class RelationshipTest6(fixtures.MappedTest):
         sess.flush()
 
         sess.expunge_all()
-        m = sess.query(Manager).get(m.person_id)
-        m2 = sess.query(Manager).get(m2.person_id)
+        m = sess.get(Manager, m.person_id)
+        m2 = sess.get(Manager, m2.person_id)
         assert m.colleague is m2
 
 
@@ -984,7 +981,8 @@ class RelationshipTest7(fixtures.MappedTest):
         car_join = polymorphic_union(
             {
                 "car": cars.outerjoin(offroad_cars)
-                .select(offroad_cars.c.car_id == None)
+                .select()
+                .where(offroad_cars.c.car_id == None)
                 .reduce_columns()
                 .subquery(),
                 "offroad": cars.join(offroad_cars),
@@ -1266,42 +1264,38 @@ class GenerativeTest(fixtures.MappedTest, AssertsExecutionResults):
         Status, Person, Engineer, Manager, Car = cls.classes(
             "Status", "Person", "Engineer", "Manager", "Car"
         )
-        session = create_session(connection)
+        with sessionmaker(connection).begin() as session:
 
-        active = Status(name="active")
-        dead = Status(name="dead")
+            active = Status(name="active")
+            dead = Status(name="dead")
 
-        session.add(active)
-        session.add(dead)
-        session.flush()
-
-        # TODO: we haven't created assertions for all
-        # the data combinations created here
+            session.add(active)
+            session.add(dead)
 
-        # creating 5 managers named from M1 to M5
-        # and 5 engineers named from E1 to E5
-        # M4, M5, E4 and E5 are dead
-        for i in range(1, 5):
-            if i < 4:
-                st = active
-            else:
-                st = dead
-            session.add(
-                Manager(name="M%d" % i, category="YYYYYYYYY", status=st)
-            )
-            session.add(Engineer(name="E%d" % i, field="X", status=st))
+            # TODO: we haven't created assertions for all
+            # the data combinations created here
 
-        session.flush()
+            # creating 5 managers named from M1 to M5
+            # and 5 engineers named from E1 to E5
+            # M4, M5, E4 and E5 are dead
+            for i in range(1, 5):
+                if i < 4:
+                    st = active
+                else:
+                    st = dead
+                session.add(
+                    Manager(name="M%d" % i, category="YYYYYYYYY", status=st)
+                )
+                session.add(Engineer(name="E%d" % i, field="X", status=st))
 
-        # get E4
-        engineer4 = session.query(Engineer).filter_by(name="E4").one()
+            # get E4
+            engineer4 = session.query(Engineer).filter_by(name="E4").one()
 
-        # create 2 cars for E4, one active and one dead
-        car1 = Car(employee=engineer4, status=active)
-        car2 = Car(employee=engineer4, status=dead)
-        session.add(car1)
-        session.add(car2)
-        session.flush()
+            # create 2 cars for E4, one active and one dead
+            car1 = Car(employee=engineer4, status=active)
+            car2 = Car(employee=engineer4, status=dead)
+            session.add(car1)
+            session.add(car2)
 
     def test_join_to_q_person(self):
         Status, Person, Engineer, Manager, Car = self.classes(
@@ -1357,7 +1351,7 @@ class GenerativeTest(fixtures.MappedTest, AssertsExecutionResults):
         )
         session = create_session()
         r = session.query(Person).filter(
-            exists([1], Car.owner == Person.person_id)
+            exists().where(Car.owner == Person.person_id)
         )
 
         eq_(
@@ -1424,9 +1418,9 @@ class MultiLevelTest(fixtures.MappedTest):
                 .where(table_Employee.c.atype == "Engineer")
                 .select_from(table_Employee.join(table_Engineer))
                 .subquery(),
-                "Employee": table_Employee.select(
-                    table_Employee.c.atype == "Employee"
-                ).subquery(),
+                "Employee": table_Employee.select()
+                .where(table_Employee.c.atype == "Employee")
+                .subquery(),
             },
             None,
             "pu_employee",
@@ -1540,9 +1534,9 @@ class ManyToManyPolyTest(fixtures.MappedTest):
 
         item_join = polymorphic_union(
             {
-                "BaseItem": base_item_table.select(
-                    base_item_table.c.child_name == "BaseItem"
-                ).subquery(),
+                "BaseItem": base_item_table.select()
+                .where(base_item_table.c.child_name == "BaseItem")
+                .subquery(),
                 "Item": base_item_table.join(item_table),
             },
             None,
@@ -1610,7 +1604,7 @@ class CustomPKTest(fixtures.MappedTest):
         # a 2-col pk in any case but the leading select has a NULL for the
         # "t2id" column
         d = util.OrderedDict()
-        d["t1"] = t1.select(t1.c.type == "t1").subquery()
+        d["t1"] = t1.select().where(t1.c.type == "t1").subquery()
         d["t2"] = t1.join(t2)
         pjoin = polymorphic_union(d, None, "pjoin")
 
@@ -1634,9 +1628,9 @@ class CustomPKTest(fixtures.MappedTest):
         # query using get(), using only one value.
         # this requires the select_table mapper
         # has the same single-col primary key.
-        assert sess.query(T1).get(ot1.id).id == ot1.id
+        assert sess.get(T1, ot1.id).id == ot1.id
 
-        ot1 = sess.query(T1).get(ot1.id)
+        ot1 = sess.get(T1, ot1.id)
         ot1.data = "hi"
         sess.flush()
 
@@ -1656,7 +1650,7 @@ class CustomPKTest(fixtures.MappedTest):
         # a 2-col pk in any case but the leading select has a NULL for the
         # "t2id" column
         d = util.OrderedDict()
-        d["t1"] = t1.select(t1.c.type == "t1").subquery()
+        d["t1"] = t1.select().where(t1.c.type == "t1").subquery()
         d["t2"] = t1.join(t2)
         pjoin = polymorphic_union(d, None, "pjoin")
 
@@ -1681,9 +1675,9 @@ class CustomPKTest(fixtures.MappedTest):
         # query using get(), using only one value.  this requires the
         # select_table mapper
         # has the same single-col primary key.
-        assert sess.query(T1).get(ot1.id).id == ot1.id
+        assert sess.get(T1, ot1.id).id == ot1.id
 
-        ot1 = sess.query(T1).get(ot1.id)
+        ot1 = sess.get(T1, ot1.id)
         ot1.data = "hi"
         sess.flush()
 
index 6372812d2843dfc6587489f1ead0b51831c25d39..9db11d362aa5ec3bf4872d561203ded6b5484b67 100644 (file)
@@ -19,7 +19,6 @@ from sqlalchemy.orm import class_mapper
 from sqlalchemy.orm import clear_mappers
 from sqlalchemy.orm import column_property
 from sqlalchemy.orm import composite
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import deferred
 from sqlalchemy.orm import exc as orm_exc
 from sqlalchemy.orm import joinedload
@@ -43,6 +42,7 @@ from sqlalchemy.testing.assertsql import CompiledSQL
 from sqlalchemy.testing.assertsql import Conditional
 from sqlalchemy.testing.assertsql import Or
 from sqlalchemy.testing.assertsql import RegexSQL
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
@@ -194,7 +194,7 @@ class PolyExpressionEagerLoad(fixtures.DeclarativeMappedTest):
             child_id = Column(Integer, ForeignKey("a.id"))
             child = relationship("A")
 
-            p_a = case([(discriminator == "a", "a")], else_="b")
+            p_a = case((discriminator == "a", "a"), else_="b")
 
             __mapper_args__ = {
                 "polymorphic_identity": "a",
@@ -455,7 +455,7 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
     def test_polymorphic_on_expr_explicit_map(self):
         t2, t1 = self.tables.t2, self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case([(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")])
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child"))
         mapper(
             Parent,
             t1,
@@ -470,7 +470,7 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
     def test_polymorphic_on_expr_implicit_map_no_label_joined(self):
         t2, t1 = self.tables.t2, self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case([(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")])
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child"))
         mapper(Parent, t1, polymorphic_identity="parent", polymorphic_on=expr)
         mapper(Child, t2, inherits=Parent, polymorphic_identity="child")
 
@@ -479,9 +479,9 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
     def test_polymorphic_on_expr_implicit_map_w_label_joined(self):
         t2, t1 = self.tables.t2, self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case(
-            [(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")]
-        ).label(None)
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child")).label(
+            None
+        )
         mapper(Parent, t1, polymorphic_identity="parent", polymorphic_on=expr)
         mapper(Child, t2, inherits=Parent, polymorphic_identity="child")
 
@@ -492,7 +492,7 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
         with a standalone expr"""
         t1 = self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case([(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")])
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child"))
         mapper(Parent, t1, polymorphic_identity="parent", polymorphic_on=expr)
         mapper(Child, inherits=Parent, polymorphic_identity="child")
 
@@ -503,9 +503,9 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
         with a standalone expr"""
         t1 = self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case(
-            [(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")]
-        ).label(None)
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child")).label(
+            None
+        )
         mapper(Parent, t1, polymorphic_identity="parent", polymorphic_on=expr)
         mapper(Child, inherits=Parent, polymorphic_identity="child")
 
@@ -514,7 +514,7 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
     def test_polymorphic_on_column_prop(self):
         t2, t1 = self.tables.t2, self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case([(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")])
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child"))
         cprop = column_property(expr)
         mapper(
             Parent,
@@ -530,7 +530,7 @@ class PolymorphicOnNotLocalTest(fixtures.MappedTest):
     def test_polymorphic_on_column_str_prop(self):
         t2, t1 = self.tables.t2, self.tables.t1
         Parent, Child = self.classes.Parent, self.classes.Child
-        expr = case([(t1.c.x == "p", "parent"), (t1.c.x == "c", "child")])
+        expr = case((t1.c.x == "p", "parent"), (t1.c.x == "c", "child"))
         cprop = column_property(expr)
         mapper(
             Parent,
@@ -1158,13 +1158,10 @@ class GetTest(fixtures.MappedTest):
         class Blub(Bar):
             pass
 
-    def test_get_polymorphic(self):
-        self._do_get_test(True)
-
-    def test_get_nonpolymorphic(self):
-        self._do_get_test(False)
-
-    def _do_get_test(self, polymorphic):
+    @testing.combinations(
+        ("polymorphic", True), ("test_get_nonpolymorphic", False), id_="ia"
+    )
+    def test_get(self, polymorphic):
         foo, Bar, Blub, blub, bar, Foo = (
             self.tables.foo,
             self.classes.Bar,
@@ -1197,18 +1194,18 @@ class GetTest(fixtures.MappedTest):
         if polymorphic:
 
             def go():
-                assert sess.query(Foo).get(f.id) is f
-                assert sess.query(Foo).get(b.id) is b
-                assert sess.query(Foo).get(bl.id) is bl
-                assert sess.query(Bar).get(b.id) is b
-                assert sess.query(Bar).get(bl.id) is bl
-                assert sess.query(Blub).get(bl.id) is bl
+                assert sess.get(Foo, f.id) is f
+                assert sess.get(Foo, b.id) is b
+                assert sess.get(Foo, bl.id) is bl
+                assert sess.get(Bar, b.id) is b
+                assert sess.get(Bar, bl.id) is bl
+                assert sess.get(Blub, bl.id) is bl
 
                 # test class mismatches - item is present
                 # in the identity map but we requested a subclass
-                assert sess.query(Blub).get(f.id) is None
-                assert sess.query(Blub).get(b.id) is None
-                assert sess.query(Bar).get(f.id) is None
+                assert sess.get(Blub, f.id) is None
+                assert sess.get(Blub, b.id) is None
+                assert sess.get(Bar, f.id) is None
 
             self.assert_sql_count(testing.db, go, 0)
         else:
@@ -1217,20 +1214,20 @@ class GetTest(fixtures.MappedTest):
             # polymorphic.  the important part being that get() always
             # returns an instance of the query's type.
             def go():
-                assert sess.query(Foo).get(f.id) is f
+                assert sess.get(Foo, f.id) is f
 
-                bb = sess.query(Foo).get(b.id)
+                bb = sess.get(Foo, b.id)
                 assert isinstance(b, Foo) and bb.id == b.id
 
-                bll = sess.query(Foo).get(bl.id)
+                bll = sess.get(Foo, bl.id)
                 assert isinstance(bll, Foo) and bll.id == bl.id
 
-                assert sess.query(Bar).get(b.id) is b
+                assert sess.get(Bar, b.id) is b
 
-                bll = sess.query(Bar).get(bl.id)
+                bll = sess.get(Bar, bl.id)
                 assert isinstance(bll, Bar) and bll.id == bl.id
 
-                assert sess.query(Blub).get(bl.id) is bl
+                assert sess.get(Blub, bl.id) is bl
 
             self.assert_sql_count(testing.db, go, 3)
 
@@ -1241,8 +1238,7 @@ class EagerLazyTest(fixtures.MappedTest):
 
     @classmethod
     def define_tables(cls, metadata):
-        global foo, bar, bar_foo
-        foo = Table(
+        Table(
             "foo",
             metadata,
             Column(
@@ -1250,22 +1246,25 @@ class EagerLazyTest(fixtures.MappedTest):
             ),
             Column("data", String(30)),
         )
-        bar = Table(
+        Table(
             "bar",
             metadata,
             Column("id", Integer, ForeignKey("foo.id"), primary_key=True),
             Column("bar_data", String(30)),
         )
 
-        bar_foo = Table(
+        Table(
             "bar_foo",
             metadata,
             Column("bar_id", Integer, ForeignKey("bar.id")),
             Column("foo_id", Integer, ForeignKey("foo.id")),
         )
 
-    def test_basic(self):
-        class Foo(object):
+    @classmethod
+    def setup_mappers(cls):
+        foo, bar, bar_foo = cls.tables("foo", "bar", "bar_foo")
+
+        class Foo(cls.Comparable):
             pass
 
         class Bar(Foo):
@@ -1278,17 +1277,24 @@ class EagerLazyTest(fixtures.MappedTest):
             "eager", relationship(foos, bar_foo, lazy="joined", viewonly=True)
         )
 
-        foo.insert().execute(data="foo1")
-        bar.insert().execute(id=1, data="bar1")
+    @classmethod
+    def insert_data(cls, connection):
+        foo, bar, bar_foo = cls.tables("foo", "bar", "bar_foo")
+
+        connection.execute(foo.insert(), dict(data="foo1"))
+        connection.execute(bar.insert(), dict(id=1, data="bar1"))
+
+        connection.execute(foo.insert(), dict(data="foo2"))
+        connection.execute(bar.insert(), dict(id=2, data="bar2"))
 
-        foo.insert().execute(data="foo2")
-        bar.insert().execute(id=2, data="bar2")
+        connection.execute(foo.insert(), dict(data="foo3"))  # 3
+        connection.execute(foo.insert(), dict(data="foo4"))  # 4
 
-        foo.insert().execute(data="foo3")  # 3
-        foo.insert().execute(data="foo4")  # 4
+        connection.execute(bar_foo.insert(), dict(bar_id=1, foo_id=3))
+        connection.execute(bar_foo.insert(), dict(bar_id=2, foo_id=4))
 
-        bar_foo.insert().execute(bar_id=1, foo_id=3)
-        bar_foo.insert().execute(bar_id=2, foo_id=4)
+    def test_basic(self):
+        Bar = self.classes.Bar
 
         sess = create_session()
         q = sess.query(Bar)
@@ -1464,7 +1470,7 @@ class FlushTest(fixtures.MappedTest):
         sess.add(a)
         sess.flush()
 
-        eq_(select(func.count("*")).select_from(user_roles).scalar(), 1)
+        eq_(sess.scalar(select(func.count("*")).select_from(user_roles)), 1)
 
     def test_two(self):
         admins, users, roles, user_roles = (
@@ -1514,7 +1520,7 @@ class FlushTest(fixtures.MappedTest):
 
         a.password = "sadmin"
         sess.flush()
-        eq_(select(func.count("*")).select_from(user_roles).scalar(), 1)
+        eq_(sess.scalar(select(func.count("*")).select_from(user_roles)), 1)
 
 
 class PassiveDeletesTest(fixtures.MappedTest):
@@ -2095,16 +2101,15 @@ class DistinctPKTest(fixtures.MappedTest):
 
     def _do_test(self, composite):
         session = create_session()
-        query = session.query(Employee)
 
         if composite:
-            alice1 = query.get([1, 2])
-            bob = query.get([2, 3])
-            alice2 = query.get([1, 2])
+            alice1 = session.get(Employee, [1, 2])
+            bob = session.get(Employee, [2, 3])
+            alice2 = session.get(Employee, [1, 2])
         else:
-            alice1 = query.get(1)
-            bob = query.get(2)
-            alice2 = query.get(1)
+            alice1 = session.get(Employee, 1)
+            bob = session.get(Employee, 2)
+            alice2 = session.get(Employee, 1)
 
             assert alice1.name == alice2.name == "alice"
             assert bob.name == "bob"
@@ -2142,22 +2147,23 @@ class SyncCompileTest(fixtures.MappedTest):
             Column("data3", String(128)),
         )
 
-    def test_joins(self):
-        for j1 in (
-            None,
-            _b_table.c.a_id == _a_table.c.id,
-            _a_table.c.id == _b_table.c.a_id,
-        ):
-            for j2 in (
-                None,
-                _b_table.c.a_id == _c_table.c.b_a_id,
-                _c_table.c.b_a_id == _b_table.c.a_id,
-            ):
-                self._do_test(j1, j2)
-                for t in reversed(_a_table.metadata.sorted_tables):
-                    t.delete().execute().close()
-
-    def _do_test(self, j1, j2):
+    @testing.combinations(
+        lambda _a_table, _b_table: None,
+        lambda _a_table, _b_table: _b_table.c.a_id == _a_table.c.id,
+        lambda _a_table, _b_table: _a_table.c.id == _b_table.c.a_id,
+        argnames="j1",
+    )
+    @testing.combinations(
+        lambda _b_table, _c_table: None,
+        lambda _b_table, _c_table: _b_table.c.a_id == _c_table.c.b_a_id,
+        lambda _b_table, _c_table: _c_table.c.b_a_id == _b_table.c.a_id,
+        argnames="j2",
+    )
+    def test_joins(self, j1, j2):
+        _a_table, _b_table, _c_table = self.tables("a", "b", "c")
+        j1 = testing.resolve_lambda(j1, **locals())
+        j2 = testing.resolve_lambda(j2, **locals())
+
         class A(object):
             def __init__(self, **kwargs):
                 for key, value in list(kwargs.items()):
@@ -2282,7 +2288,7 @@ class OverrideColKeyTest(fixtures.MappedTest):
         sess = create_session()
         sess.add(s1)
         sess.flush()
-        assert sess.query(Sub).get(10) is s1
+        assert sess.get(Sub, 10) is s1
 
     def test_override_onlyinparent(self):
         class Base(object):
@@ -2312,7 +2318,7 @@ class OverrideColKeyTest(fixtures.MappedTest):
         sess.flush()
 
         # s1 gets '10'
-        assert sess.query(Sub).get(10) is s1
+        assert sess.get(Sub, 10) is s1
 
         # s2 gets a new id, base_id is overwritten by the ultimate
         # PK col
@@ -2432,8 +2438,8 @@ class OverrideColKeyTest(fixtures.MappedTest):
         sess.flush()
         sess.expunge_all()
 
-        assert sess.query(Base).get(b1.base_id).subdata == "this is base"
-        assert sess.query(Sub).get(s1.base_id).subdata == "this is sub"
+        assert sess.get(Base, b1.base_id).subdata == "this is base"
+        assert sess.get(Sub, s1.base_id).subdata == "this is sub"
 
     def test_base_descriptors_over_base_cols(self):
         class Base(object):
@@ -2457,8 +2463,8 @@ class OverrideColKeyTest(fixtures.MappedTest):
         sess.flush()
         sess.expunge_all()
 
-        assert sess.query(Base).get(b1.base_id).data == "this is base"
-        assert sess.query(Sub).get(s1.base_id).data == "this is base"
+        assert sess.get(Base, b1.base_id).data == "this is base"
+        assert sess.get(Sub, s1.base_id).data == "this is base"
 
 
 class OptimizedLoadTest(fixtures.MappedTest):
@@ -2587,7 +2593,7 @@ class OptimizedLoadTest(fixtures.MappedTest):
             polymorphic_identity="sub",
             with_polymorphic=(
                 "*",
-                base.outerjoin(sub).select(use_labels=True).alias("foo"),
+                base.outerjoin(sub).select().apply_labels().alias("foo"),
             ),
         )
         sess = Session()
@@ -3602,4 +3608,4 @@ class NameConflictTest(fixtures.MappedTest):
         sess.flush()
         f_id = f.id
         sess.expunge_all()
-        assert sess.query(Content).get(f_id).content_type == "bar"
+        assert sess.get(Content, f_id).content_type == "bar"
index 376337b25399361029c98cef9ebd0a9e5f6175eb..9b0a050d7ac60c39d510a4ab4b2060f77dae2ebf 100644 (file)
@@ -7,7 +7,6 @@ from sqlalchemy.orm import attributes
 from sqlalchemy.orm import class_mapper
 from sqlalchemy.orm import clear_mappers
 from sqlalchemy.orm import configure_mappers
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import joinedload
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import polymorphic_union
@@ -18,6 +17,7 @@ from sqlalchemy.testing import assert_raises_message
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
 from sqlalchemy.testing import mock
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
@@ -359,7 +359,7 @@ class ConcreteTest(fixtures.MappedTest):
         eq_(test_calls.mock_calls, [mock.call.engineer_info_instance()])
 
         session.add(tom)
-        session.flush()
+        session.commit()
 
         session.close()
 
@@ -443,9 +443,9 @@ class ConcreteTest(fixtures.MappedTest):
 
         assert (
             len(
-                testing.db.execute(
-                    session.query(Employee).with_labels().statement
-                ).fetchall()
+                session.connection()
+                .execute(session.query(Employee).with_labels().statement)
+                .fetchall()
             )
             == 3
         )
@@ -518,17 +518,19 @@ class ConcreteTest(fixtures.MappedTest):
         session.flush()
         eq_(
             len(
-                testing.db.execute(
+                session.connection()
+                .execute(
                     session.query(Employee)
                     .with_polymorphic("*", pjoin, pjoin.c.type)
                     .with_labels()
                     .statement
-                ).fetchall()
+                )
+                .fetchall()
             ),
             4,
         )
-        eq_(session.query(Employee).get(jdoe.employee_id), jdoe)
-        eq_(session.query(Engineer).get(jerry.employee_id), jerry)
+        eq_(session.get(Employee, jdoe.employee_id), jdoe)
+        eq_(session.get(Engineer, jerry.employee_id), jerry)
         eq_(
             set(
                 [
@@ -575,33 +577,41 @@ class ConcreteTest(fixtures.MappedTest):
         # test adaption of the column by wrapping the query in a
         # subquery
 
-        eq_(
-            len(
-                testing.db.execute(
-                    session.query(Engineer)
-                    .with_polymorphic("*", pjoin2, pjoin2.c.type)
-                    .from_self()
-                    .statement
-                ).fetchall()
-            ),
-            2,
-        )
-        eq_(
-            set(
-                [
-                    repr(x)
-                    for x in session.query(Engineer)
-                    .with_polymorphic("*", pjoin2, pjoin2.c.type)
-                    .from_self()
-                ]
-            ),
-            set(
-                [
-                    "Engineer Jerry knows how to program",
-                    "Hacker Kurt 'Badass' knows how to hack",
-                ]
-            ),
-        )
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            eq_(
+                len(
+                    session.connection()
+                    .execute(
+                        session.query(Engineer)
+                        .with_polymorphic("*", pjoin2, pjoin2.c.type)
+                        .from_self()
+                        .statement
+                    )
+                    .fetchall()
+                ),
+                2,
+            )
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            eq_(
+                set(
+                    [
+                        repr(x)
+                        for x in session.query(Engineer)
+                        .with_polymorphic("*", pjoin2, pjoin2.c.type)
+                        .from_self()
+                    ]
+                ),
+                set(
+                    [
+                        "Engineer Jerry knows how to program",
+                        "Hacker Kurt 'Badass' knows how to hack",
+                    ]
+                ),
+            )
 
     def test_relationship(self):
         pjoin = polymorphic_union(
@@ -638,7 +648,7 @@ class ConcreteTest(fixtures.MappedTest):
         session.expunge_all()
 
         def go():
-            c2 = session.query(Company).get(c.id)
+            c2 = session.get(Company, c.id)
             assert set([repr(x) for x in c2.employees]) == set(
                 [
                     "Engineer Kurt knows how to hack",
@@ -650,10 +660,8 @@ class ConcreteTest(fixtures.MappedTest):
         session.expunge_all()
 
         def go():
-            c2 = (
-                session.query(Company)
-                .options(joinedload(Company.employees))
-                .get(c.id)
+            c2 = session.get(
+                Company, c.id, options=[joinedload(Company.employees)]
             )
             assert set([repr(x) for x in c2.employees]) == set(
                 [
@@ -1174,13 +1182,17 @@ class ColKeysTest(fixtures.MappedTest):
     def insert_data(cls, connection):
         connection.execute(
             refugees_table.insert(),
-            dict(refugee_fid=1, name="refugee1"),
-            dict(refugee_fid=2, name="refugee2"),
+            [
+                dict(refugee_fid=1, name="refugee1"),
+                dict(refugee_fid=2, name="refugee2"),
+            ],
         )
         connection.execute(
             offices_table.insert(),
-            dict(office_fid=1, name="office1"),
-            dict(office_fid=2, name="office2"),
+            [
+                dict(office_fid=1, name="office1"),
+                dict(office_fid=2, name="office2"),
+            ],
         )
 
     def test_keys(self):
@@ -1220,7 +1232,7 @@ class ColKeysTest(fixtures.MappedTest):
             polymorphic_identity="refugee",
         )
         sess = create_session()
-        eq_(sess.query(Refugee).get(1).name, "refugee1")
-        eq_(sess.query(Refugee).get(2).name, "refugee2")
-        eq_(sess.query(Office).get(1).name, "office1")
-        eq_(sess.query(Office).get(2).name, "office2")
+        eq_(sess.get(Refugee, 1).name, "refugee1")
+        eq_(sess.get(Refugee, 2).name, "refugee2")
+        eq_(sess.get(Office, 1).name, "office1")
+        eq_(sess.get(Office, 2).name, "office2")
index 228cb1273e9bf784f6d72b24d0c831d9fe70ac99..334ed22f370e03a6cf19468f3ef19c06089a8cff 100644 (file)
@@ -247,9 +247,9 @@ class MagazineTest(fixtures.MappedTest):
                     "c": self.tables.page.join(self.tables.magazine_page).join(
                         self.tables.classified_page
                     ),
-                    "p": self.tables.page.select(
-                        self.tables.page.c.type == "p"
-                    ).subquery(),
+                    "p": self.tables.page.select()
+                    .where(self.tables.page.c.type == "p")
+                    .subquery(),
                 },
                 None,
                 "page_join",
index dc162321fb919d454958119ff100cd4617e514ee..207ac09c7321be3e54456ec0f6f8243ea8e7f8fd 100644 (file)
@@ -5,11 +5,11 @@ from sqlalchemy import Sequence
 from sqlalchemy import String
 from sqlalchemy import Table
 from sqlalchemy.orm import class_mapper
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import relationship
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.fixtures import create_session
 
 
 class InheritTest(fixtures.MappedTest):
@@ -171,7 +171,7 @@ class InheritTest2(fixtures.MappedTest):
 
         # test that "bar.bid" does not need to be referenced in a get
         # (ticket 185)
-        assert sess.query(Bar).get(b.id).id == b.id
+        assert sess.get(Bar, b.id).id == b.id
 
     def test_basic(self):
         class Foo(object):
index e5102685840d639506b21584852d0857cd20e104..91be4d16712a45c073f14692227d442c4f0b452b 100644 (file)
@@ -4,10 +4,10 @@ from sqlalchemy import String
 from sqlalchemy.orm import backref
 from sqlalchemy.orm import clear_mappers
 from sqlalchemy.orm import configure_mappers
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import relationship
 from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
index 25eeb3d1df1b193b4749ba7f1173e3c0c91ee614..99cab870bd9ae69114ac34adde6072e362e9a2e1 100644 (file)
@@ -6,7 +6,6 @@ from sqlalchemy import Integer
 from sqlalchemy import String
 from sqlalchemy import Table
 from sqlalchemy import testing
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import polymorphic_union
 from sqlalchemy.orm import relationship
@@ -15,6 +14,7 @@ from sqlalchemy.testing import assert_raises
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
 from sqlalchemy.testing import is_
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 
 
@@ -123,7 +123,9 @@ class InsertOrderTest(PolymorphTest):
             {
                 "engineer": people.join(engineers),
                 "manager": people.join(managers),
-                "person": people.select(people.c.type == "person").subquery(),
+                "person": people.select()
+                .where(people.c.type == "person")
+                .subquery(),
             },
             None,
             "pjoin",
@@ -191,7 +193,7 @@ class InsertOrderTest(PolymorphTest):
         session.add(c)
         session.flush()
         session.expunge_all()
-        eq_(session.query(Company).get(c.company_id), c)
+        eq_(session.get(Company, c.company_id), c)
 
 
 @testing.combinations(
@@ -235,9 +237,9 @@ class RoundTripTest(PolymorphTest):
                     {
                         "engineer": people.join(engineers),
                         "manager": people.join(managers),
-                        "person": people.select(
-                            people.c.type == "person"
-                        ).subquery(),
+                        "person": people.select()
+                        .where(people.c.type == "person")
+                        .subquery(),
                     },
                     None,
                     "pjoin",
@@ -399,7 +401,7 @@ class RoundTripTest(PolymorphTest):
         employees = session.query(Person).order_by(Person.person_id).all()
         company = session.query(Company).first()
 
-        eq_(session.query(Person).get(dilbert.person_id), dilbert)
+        eq_(session.get(Person, dilbert.person_id), dilbert)
         session.expunge_all()
 
         eq_(
@@ -411,7 +413,7 @@ class RoundTripTest(PolymorphTest):
         session.expunge_all()
 
         def go():
-            cc = session.query(Company).get(company.company_id)
+            cc = session.get(Company, company.company_id)
             eq_(cc.employees, employees)
 
         if not lazy_relationship:
@@ -471,7 +473,7 @@ class RoundTripTest(PolymorphTest):
         # the "palias" alias does *not* get sucked up
         # into the "person_join" conversion.
         palias = people.alias("palias")
-        dilbert = session.query(Person).get(dilbert.person_id)
+        dilbert = session.get(Person, dilbert.person_id)
         is_(
             dilbert,
             session.query(Person)
index 86e0bd360bbff87a33c27cba197c2869a4fd1bba..69a485d41d89b85f2cbba2e0b30e24ace1d95317 100644 (file)
@@ -5,7 +5,6 @@ from sqlalchemy import select
 from sqlalchemy import testing
 from sqlalchemy import true
 from sqlalchemy.orm import aliased
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import defaultload
 from sqlalchemy.orm import join
 from sqlalchemy.orm import joinedload
@@ -15,6 +14,7 @@ from sqlalchemy.orm import with_polymorphic
 from sqlalchemy.testing import assert_raises
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing.assertsql import CompiledSQL
+from sqlalchemy.testing.fixtures import create_session
 from ._poly_fixtures import _Polymorphic
 from ._poly_fixtures import _PolymorphicAliasedJoins
 from ._poly_fixtures import _PolymorphicJoins
@@ -148,18 +148,18 @@ class _PolymorphicTestBase(object):
         self.assert_sql_count(testing.db, go, 3)
 
         eq_(
-            select(func.count("*"))
-            .select_from(
-                sess.query(Person)
-                .with_polymorphic("*")
-                .options(joinedload(Engineer.machines))
-                .order_by(Person.person_id)
-                .limit(2)
-                .offset(1)
-                .with_labels()
-                .subquery()
-            )
-            .scalar(),
+            sess.scalar(
+                select(func.count("*")).select_from(
+                    sess.query(Person)
+                    .with_polymorphic("*")
+                    .options(joinedload(Engineer.machines))
+                    .order_by(Person.person_id)
+                    .limit(2)
+                    .offset(1)
+                    .with_labels()
+                    .subquery()
+                )
+            ),
             2,
         )
 
@@ -170,21 +170,21 @@ class _PolymorphicTestBase(object):
         """
         sess = create_session()
         eq_(
-            sess.query(Person).get(e1.person_id),
+            sess.get(Person, e1.person_id),
             Engineer(name="dilbert", primary_language="java"),
         )
 
     def test_get_two(self):
         sess = create_session()
         eq_(
-            sess.query(Engineer).get(e1.person_id),
+            sess.get(Engineer, e1.person_id),
             Engineer(name="dilbert", primary_language="java"),
         )
 
     def test_get_three(self):
         sess = create_session()
         eq_(
-            sess.query(Manager).get(b1.person_id),
+            sess.get(Manager, b1.person_id),
             Boss(name="pointy haired boss", golf_swing="fore"),
         )
 
@@ -230,7 +230,7 @@ class _PolymorphicTestBase(object):
         )
 
     def test_multi_join_future(self):
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
         e = aliased(Person)
         c = aliased(Company)
 
@@ -283,7 +283,7 @@ class _PolymorphicTestBase(object):
         eq_(sess.query(Engineer).all()[0], Engineer(name="dilbert"))
 
     def test_filter_on_subclass_one_future(self):
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
         eq_(
             sess.execute(select(Engineer)).scalar(), Engineer(name="dilbert"),
         )
@@ -337,7 +337,7 @@ class _PolymorphicTestBase(object):
         )
 
     def test_join_from_polymorphic_nonaliased_one_future(self):
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
         eq_(
             sess.execute(
                 select(Person)
@@ -396,7 +396,7 @@ class _PolymorphicTestBase(object):
         )
 
     def test_join_from_polymorphic_flag_aliased_one_future(self):
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
 
         pa = aliased(Paperwork)
         eq_(
@@ -496,7 +496,7 @@ class _PolymorphicTestBase(object):
         )
 
     def test_join_from_with_polymorphic_nonaliased_one_future(self):
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
 
         pm = with_polymorphic(Person, [Manager])
         eq_(
@@ -1552,16 +1552,19 @@ class _PolymorphicTestBase(object):
         palias = aliased(Person)
         expected = [(m1, e1), (m1, e2), (m1, b1)]
 
-        eq_(
-            sess.query(Person, palias)
-            .filter(Person.company_id == palias.company_id)
-            .filter(Person.name == "dogbert")
-            .filter(Person.person_id > palias.person_id)
-            .from_self()
-            .order_by(Person.person_id, palias.person_id)
-            .all(),
-            expected,
-        )
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            eq_(
+                sess.query(Person, palias)
+                .filter(Person.company_id == palias.company_id)
+                .filter(Person.name == "dogbert")
+                .filter(Person.person_id > palias.person_id)
+                .from_self()
+                .order_by(Person.person_id, palias.person_id)
+                .all(),
+                expected,
+            )
 
     def test_self_referential_two_point_five(self):
         """Using two aliases, the above case works.
@@ -1572,21 +1575,24 @@ class _PolymorphicTestBase(object):
 
         expected = [(m1, e1), (m1, e2), (m1, b1)]
 
-        eq_(
-            sess.query(palias, palias2)
-            .filter(palias.company_id == palias2.company_id)
-            .filter(palias.name == "dogbert")
-            .filter(palias.person_id > palias2.person_id)
-            .from_self()
-            .order_by(palias.person_id, palias2.person_id)
-            .all(),
-            expected,
-        )
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            eq_(
+                sess.query(palias, palias2)
+                .filter(palias.company_id == palias2.company_id)
+                .filter(palias.name == "dogbert")
+                .filter(palias.person_id > palias2.person_id)
+                .from_self()
+                .order_by(palias.person_id, palias2.person_id)
+                .all(),
+                expected,
+            )
 
     def test_self_referential_two_future(self):
         # TODO: this is the SECOND test *EVER* of an aliased class of
         # an aliased class.
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
         expected = [(m1, e1), (m1, e2), (m1, b1)]
 
         # not aliasing the first class
@@ -1615,7 +1621,7 @@ class _PolymorphicTestBase(object):
         # TODO: this is the first test *EVER* of an aliased class of
         # an aliased class.  we should add many more tests for this.
         # new case added in Id810f485c5f7ed971529489b84694e02a3356d6d
-        sess = create_session(testing.db, future=True)
+        sess = create_session(future=True)
         expected = [(m1, e1), (m1, e2), (m1, b1)]
 
         # aliasing the first class
index aab3570c9daa13aa2ada29066f00f6e32b709e05..5fd2c5a6f63fa3b0fba8cc47c6906487fb9fe0d8 100644 (file)
@@ -7,11 +7,11 @@ from sqlalchemy import Integer
 from sqlalchemy import LargeBinary
 from sqlalchemy import String
 from sqlalchemy.orm import backref
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import deferred
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import relationship
 from sqlalchemy.testing import fixtures
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
index c7d2042b310ee822cbff5726abc4e8e92fc3c81c..8590949a771d6a9b34ff1ffd5af51a7365751a9c 100644 (file)
@@ -8,12 +8,12 @@ from sqlalchemy.orm import aliased
 from sqlalchemy.orm import backref
 from sqlalchemy.orm import configure_mappers
 from sqlalchemy.orm import contains_eager
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import joinedload
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import relationship
 from sqlalchemy.orm import selectinload
 from sqlalchemy.orm import Session
+from sqlalchemy.orm import sessionmaker
 from sqlalchemy.orm import subqueryload
 from sqlalchemy.orm import with_polymorphic
 from sqlalchemy.testing import AssertsCompiledSQL
@@ -21,6 +21,7 @@ from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
 from sqlalchemy.testing import is_
 from sqlalchemy.testing.entities import ComparableEntity
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
@@ -589,10 +590,9 @@ class M2MFilterTest(fixtures.MappedTest):
         e4 = Engineer(name="e4")
         org1 = Organization(name="org1", engineers=[e1, e2])
         org2 = Organization(name="org2", engineers=[e3, e4])
-        sess = create_session(connection)
-        sess.add(org1)
-        sess.add(org2)
-        sess.flush()
+        with sessionmaker(connection).begin() as sess:
+            sess.add(org1)
+            sess.add(org2)
 
     def test_not_contains(self):
         Organization = self.classes.Organization
@@ -838,9 +838,11 @@ class SelfReferentialM2MTest(fixtures.MappedTest, AssertsCompiledSQL):
 
         # another way to check
         eq_(
-            select(func.count("*"))
-            .select_from(q.limit(1).with_labels().subquery())
-            .scalar(),
+            sess.scalar(
+                select(func.count("*")).select_from(
+                    q.limit(1).with_labels().subquery()
+                )
+            ),
             1,
         )
         assert q.first() is c1
@@ -1134,15 +1136,16 @@ class SubClassEagerToSubClassTest(fixtures.MappedTest):
         global p1, p2
 
         Sub, Subparent = cls.classes.Sub, cls.classes.Subparent
-        sess = create_session(connection)
-        p1 = Subparent(
-            data="p1",
-            children=[Sub(data="s1"), Sub(data="s2"), Sub(data="s3")],
-        )
-        p2 = Subparent(data="p2", children=[Sub(data="s4"), Sub(data="s5")])
-        sess.add(p1)
-        sess.add(p2)
-        sess.flush()
+        with sessionmaker(connection).begin() as sess:
+            p1 = Subparent(
+                data="p1",
+                children=[Sub(data="s1"), Sub(data="s2"), Sub(data="s3")],
+            )
+            p2 = Subparent(
+                data="p2", children=[Sub(data="s4"), Sub(data="s5")]
+            )
+            sess.add(p1)
+            sess.add(p2)
 
     def test_joinedload(self):
         Subparent = self.classes.Subparent
@@ -1725,7 +1728,7 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
             "JOIN ep2 ON base2.id = ep2.base2_id",
         )
 
-    def test_six(self):
+    def test_six_legacy(self):
         Parent, Base1, Base2, Sub1, Sub2, EP1, EP2 = self._classes()
 
         s = Session()
@@ -1735,8 +1738,38 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
         # this query is coming out instead which is equivalent, but not
         # totally sure where this happens
 
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            self.assert_compile(
+                s.query(Sub2).from_self().join(Sub2.ep1).join(Sub2.ep2),
+                "SELECT anon_1.sub2_id AS anon_1_sub2_id, "
+                "anon_1.base2_base1_id AS anon_1_base2_base1_id, "
+                "anon_1.base2_data AS anon_1_base2_data, "
+                "anon_1.sub2_subdata AS anon_1_sub2_subdata "
+                "FROM (SELECT sub2.id AS sub2_id, base2.id AS base2_id, "
+                "base2.base1_id AS base2_base1_id, base2.data AS base2_data, "
+                "sub2.subdata AS sub2_subdata "
+                "FROM base2 JOIN sub2 ON base2.id = sub2.id) AS anon_1 "
+                "JOIN ep1 ON anon_1.sub2_id = ep1.base2_id "
+                "JOIN ep2 ON anon_1.sub2_id = ep2.base2_id",
+            )
+
+    def test_six(self):
+        Parent, Base1, Base2, Sub1, Sub2, EP1, EP2 = self._classes()
+
+        # as of from_self() changing in
+        # I3abfb45dd6e50f84f29d39434caa0b550ce27864,
+        # this query is coming out instead which is equivalent, but not
+        # totally sure where this happens
+
+        stmt = select(Sub2)
+
+        subq = aliased(Sub2, stmt.apply_labels().subquery())
+
+        stmt = select(subq).join(subq.ep1).join(Sub2.ep2).apply_labels()
         self.assert_compile(
-            s.query(Sub2).from_self().join(Sub2.ep1).join(Sub2.ep2),
+            stmt,
             "SELECT anon_1.sub2_id AS anon_1_sub2_id, "
             "anon_1.base2_base1_id AS anon_1_base2_base1_id, "
             "anon_1.base2_data AS anon_1_base2_data, "
@@ -1749,7 +1782,7 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
             "JOIN ep2 ON anon_1.sub2_id = ep2.base2_id",
         )
 
-    def test_seven(self):
+    def test_seven_legacy(self):
         Parent, Base1, Base2, Sub1, Sub2, EP1, EP2 = self._classes()
 
         s = Session()
@@ -1758,16 +1791,74 @@ class SubClassToSubClassMultiTest(AssertsCompiledSQL, fixtures.MappedTest):
         # I3abfb45dd6e50f84f29d39434caa0b550ce27864,
         # this query is coming out instead which is equivalent, but not
         # totally sure where this happens
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+
+            self.assert_compile(
+                # adding Sub2 to the entities list helps it,
+                # otherwise the joins for Sub2.ep1/ep2 don't have columns
+                # to latch onto.   Can't really make it better than this
+                s.query(Parent, Sub2)
+                .join(Parent.sub1)
+                .join(Sub1.sub2)
+                .from_self()
+                .join(Sub2.ep1)
+                .join(Sub2.ep2),
+                "SELECT anon_1.parent_id AS anon_1_parent_id, "
+                "anon_1.parent_data AS anon_1_parent_data, "
+                "anon_1.sub2_id AS anon_1_sub2_id, "
+                "anon_1.base2_base1_id AS anon_1_base2_base1_id, "
+                "anon_1.base2_data AS anon_1_base2_data, "
+                "anon_1.sub2_subdata AS anon_1_sub2_subdata "
+                "FROM (SELECT parent.id AS parent_id, "
+                "parent.data AS parent_data, "
+                "sub2.id AS sub2_id, "
+                "base2.id AS base2_id, "
+                "base2.base1_id AS base2_base1_id, "
+                "base2.data AS base2_data, "
+                "sub2.subdata AS sub2_subdata "
+                "FROM parent JOIN (base1 JOIN sub1 ON base1.id = sub1.id) "
+                "ON parent.id = sub1.parent_id JOIN "
+                "(base2 JOIN sub2 ON base2.id = sub2.id) "
+                "ON base1.id = base2.base1_id) AS anon_1 "
+                "JOIN ep1 ON anon_1.sub2_id = ep1.base2_id "
+                "JOIN ep2 ON anon_1.sub2_id = ep2.base2_id",
+            )
+
+    def test_seven(self):
+        Parent, Base1, Base2, Sub1, Sub2, EP1, EP2 = self._classes()
+
+        # as of from_self() changing in
+        # I3abfb45dd6e50f84f29d39434caa0b550ce27864,
+        # this query is coming out instead which is equivalent, but not
+        # totally sure where this happens
+
+        subq = (
+            select(Parent, Sub2)
+            .join(Parent.sub1)
+            .join(Sub1.sub2)
+            .apply_labels()
+            .subquery()
+        )
+
+        # another 1.4 supercharged select() statement ;)
+
+        palias = aliased(Parent, subq)
+        sub2alias = aliased(Sub2, subq)
+
+        stmt = (
+            select(palias, sub2alias)
+            .join(sub2alias.ep1)
+            .join(sub2alias.ep2)
+            .apply_labels()
+        )
+
         self.assert_compile(
             # adding Sub2 to the entities list helps it,
             # otherwise the joins for Sub2.ep1/ep2 don't have columns
             # to latch onto.   Can't really make it better than this
-            s.query(Parent, Sub2)
-            .join(Parent.sub1)
-            .join(Sub1.sub2)
-            .from_self()
-            .join(Sub2.ep1)
-            .join(Sub2.ep2),
+            stmt,
             "SELECT anon_1.parent_id AS anon_1_parent_id, "
             "anon_1.parent_data AS anon_1_parent_data, "
             "anon_1.sub2_id AS anon_1_sub2_id, "
index 4adb1a5cb639f4632b35285d7f6273acc9a8744e..65dd9c251e435e65ae3df216fba520cd40826b08 100644 (file)
@@ -12,7 +12,6 @@ from sqlalchemy import testing
 from sqlalchemy import true
 from sqlalchemy.orm import aliased
 from sqlalchemy.orm import Bundle
-from sqlalchemy.orm import create_session
 from sqlalchemy.orm import joinedload
 from sqlalchemy.orm import mapper
 from sqlalchemy.orm import relationship
@@ -24,6 +23,7 @@ from sqlalchemy.testing import AssertsCompiledSQL
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
 from sqlalchemy.testing.assertsql import CompiledSQL
+from sqlalchemy.testing.fixtures import create_session
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
 
@@ -280,12 +280,53 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
             [e2id],
         )
 
-    def test_from_self(self):
+    def test_from_self_legacy(self):
         Engineer = self.classes.Engineer
 
         sess = create_session()
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            self.assert_compile(
+                sess.query(Engineer).from_self(),
+                "SELECT anon_1.employees_employee_id AS "
+                "anon_1_employees_employee_id, "
+                "anon_1.employees_name AS "
+                "anon_1_employees_name, "
+                "anon_1.employees_manager_data AS "
+                "anon_1_employees_manager_data, "
+                "anon_1.employees_engineer_info AS "
+                "anon_1_employees_engineer_info, "
+                "anon_1.employees_type AS "
+                "anon_1_employees_type FROM (SELECT "
+                "employees.employee_id AS "
+                "employees_employee_id, employees.name AS "
+                "employees_name, employees.manager_data AS "
+                "employees_manager_data, "
+                "employees.engineer_info AS "
+                "employees_engineer_info, employees.type "
+                "AS employees_type FROM employees WHERE "
+                "employees.type IN ([POSTCOMPILE_type_1])) AS "
+                "anon_1",
+                use_default_dialect=True,
+            )
+
+    def test_from_subq(self):
+        Engineer = self.classes.Engineer
+
+        stmt = select(Engineer)
+        subq = aliased(Engineer, stmt.apply_labels().subquery())
+
+        # so here we have an extra "WHERE type in ()", because
+        # both the inner and the outer queries have the Engineer entity.
+        # this is expected at the moment but it would be nice if
+        # _enable_single_crit or something similar could propagate here.
+        # legacy from_self() takes care of this because it applies
+        # _enable_single_crit at that moment.
+
+        stmt = select(subq).apply_labels()
         self.assert_compile(
-            sess.query(Engineer).from_self(),
+            stmt,
             "SELECT anon_1.employees_employee_id AS "
             "anon_1_employees_employee_id, "
             "anon_1.employees_name AS "
@@ -304,7 +345,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
             "employees_engineer_info, employees.type "
             "AS employees_type FROM employees WHERE "
             "employees.type IN ([POSTCOMPILE_type_1])) AS "
-            "anon_1",
+            "anon_1 WHERE anon_1.employees_type IN ([POSTCOMPILE_type_2])",
             use_default_dialect=True,
         )
 
@@ -382,14 +423,17 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, fixtures.MappedTest):
 
         sess = create_session()
         col = func.count(literal_column("*"))
-        self.assert_compile(
-            sess.query(Engineer.employee_id).from_self(col),
-            "SELECT count(*) AS count_1 "
-            "FROM (SELECT employees.employee_id AS employees_employee_id "
-            "FROM employees "
-            "WHERE employees.type IN ([POSTCOMPILE_type_1])) AS anon_1",
-            use_default_dialect=True,
-        )
+        with testing.expect_deprecated(
+            r"The Query.from_self\(\) function/method"
+        ):
+            self.assert_compile(
+                sess.query(Engineer.employee_id).from_self(col),
+                "SELECT count(*) AS count_1 "
+                "FROM (SELECT employees.employee_id AS employees_employee_id "
+                "FROM employees "
+                "WHERE employees.type IN ([POSTCOMPILE_type_1])) AS anon_1",
+                use_default_dialect=True,
+            )
 
     def test_select_from_count(self):
         Manager, Engineer = (self.classes.Manager, self.classes.Engineer)
index 08dad2e1b7c3826cb71225396ee4acb3941ee7cd..48a8b99a6b00df47c3691537b8f6a92662a58ef9 100644 (file)
@@ -2134,7 +2134,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 class DeclarativeBind(fixtures.TestBase):
     def test_declarative_base(self):
         with testing.expect_deprecated_20(
-            'The "bind" argument to declarative_base is'
+            "The ``bind`` argument to declarative_base is "
             "deprecated and will be removed in SQLAlchemy 2.0.",
         ):
             Base = declarative_base(bind=testing.db)
@@ -2143,7 +2143,7 @@ class DeclarativeBind(fixtures.TestBase):
 
     def test_as_declarative(self):
         with testing.expect_deprecated_20(
-            'The "bind" argument to declarative_base is'
+            "The ``bind`` argument to as_declarative is "
             "deprecated and will be removed in SQLAlchemy 2.0.",
         ):
 
index 74fe8876d184535f8ed67f82d96c4018076ac071..4bef1df7f3c917674dc01309637a0e9b83974fb0 100644 (file)
@@ -27,7 +27,7 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
 
     @classmethod
     def setup_class(cls):
-        metadata = MetaData(testing.db)
+        metadata = MetaData()
         global info_table
         info_table = Table(
             "infos",
@@ -36,24 +36,29 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
             Column("info", String(30)),
         )
 
-        info_table.create()
-
-        info_table.insert().execute(
-            {"pk": 1, "info": "pk_1_data"},
-            {"pk": 2, "info": "pk_2_data"},
-            {"pk": 3, "info": "pk_3_data"},
-            {"pk": 4, "info": "pk_4_data"},
-            {"pk": 5, "info": "pk_5_data"},
-            {"pk": 6, "info": "pk_6_data"},
-        )
+        with testing.db.begin() as conn:
+            info_table.create(conn)
+
+            conn.execute(
+                info_table.insert(),
+                [
+                    {"pk": 1, "info": "pk_1_data"},
+                    {"pk": 2, "info": "pk_2_data"},
+                    {"pk": 3, "info": "pk_3_data"},
+                    {"pk": 4, "info": "pk_4_data"},
+                    {"pk": 5, "info": "pk_5_data"},
+                    {"pk": 6, "info": "pk_6_data"},
+                ],
+            )
 
     @classmethod
     def teardown_class(cls):
-        info_table.drop()
+        with testing.db.begin() as conn:
+            info_table.drop(conn)
 
     @testing.fails_on("firebird", "FIXME: unknown")
     @testing.requires.subqueries
-    def test_case(self):
+    def test_case(self, connection):
         inner = select(
             case(
                 (info_table.c.pk < 3, "lessthan3"),
@@ -63,7 +68,7 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
             info_table.c.info,
         ).select_from(info_table)
 
-        inner_result = inner.execute().fetchall()
+        inner_result = connection.execute(inner).all()
 
         # Outputs:
         # lessthan3 1 pk_1_data
@@ -86,7 +91,7 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
 
         outer = select(inner.alias("q_inner"))
 
-        outer_result = outer.execute().fetchall()
+        outer_result = connection.execute(outer).all()
 
         assert outer_result == [
             ("lessthan3", 1, "pk_1_data"),
@@ -107,7 +112,7 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
             info_table.c.info,
         ).select_from(info_table)
 
-        else_result = w_else.execute().fetchall()
+        else_result = connection.execute(w_else).all()
 
         eq_(
             else_result,
@@ -149,7 +154,7 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
             "CASE WHEN (test.col1 = :col1_1) THEN :param_1 ELSE :param_2 END",
         )
 
-    def test_text_doesnt_explode(self):
+    def test_text_doesnt_explode(self, connection):
 
         for s in [
             select(
@@ -169,7 +174,7 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL):
             ).order_by(info_table.c.info),
         ]:
             eq_(
-                s.execute().fetchall(),
+                connection.execute(s).all(),
                 [("no",), ("no",), ("no",), ("yes",), ("no",), ("no",)],
             )
 
index f9bec7914e35b9b65d0583af09e931024eac0e0e..6cb1c38412d577e95bf91d82c373711afe7b56fb 100644 (file)
@@ -351,9 +351,9 @@ class DefaultObjectTest(fixtures.TestBase):
             assert_raises_message(
                 sa.exc.ArgumentError,
                 r"SQL expression for WHERE/HAVING role expected, "
-                r"got \[(?:Sequence|ColumnDefault|DefaultClause)\('y'.*\)\]",
-                t.select,
-                [const],
+                r"got (?:Sequence|ColumnDefault|DefaultClause)\('y'.*\)",
+                t.select().where,
+                const,
             )
             assert_raises_message(
                 sa.exc.ArgumentError,
@@ -1006,29 +1006,31 @@ class PKIncrementTest(fixtures.TablesTest):
 
     # TODO: add coverage for increment on a secondary column in a key
     @testing.fails_on("firebird", "Data type unknown")
-    def _test_autoincrement(self, bind):
+    def _test_autoincrement(self, connection):
         aitable = self.tables.aitable
 
         ids = set()
-        rs = bind.execute(aitable.insert(), int1=1)
+        rs = connection.execute(aitable.insert(), int1=1)
         last = rs.inserted_primary_key[0]
         self.assert_(last)
         self.assert_(last not in ids)
         ids.add(last)
 
-        rs = bind.execute(aitable.insert(), str1="row 2")
+        rs = connection.execute(aitable.insert(), str1="row 2")
         last = rs.inserted_primary_key[0]
         self.assert_(last)
         self.assert_(last not in ids)
         ids.add(last)
 
-        rs = bind.execute(aitable.insert(), int1=3, str1="row 3")
+        rs = connection.execute(aitable.insert(), int1=3, str1="row 3")
         last = rs.inserted_primary_key[0]
         self.assert_(last)
         self.assert_(last not in ids)
         ids.add(last)
 
-        rs = bind.execute(aitable.insert(values={"int1": func.length("four")}))
+        rs = connection.execute(
+            aitable.insert().values({"int1": func.length("four")})
+        )
         last = rs.inserted_primary_key[0]
         self.assert_(last)
         self.assert_(last not in ids)
@@ -1045,7 +1047,7 @@ class PKIncrementTest(fixtures.TablesTest):
         )
 
         eq_(
-            list(bind.execute(aitable.select().order_by(aitable.c.id))),
+            list(connection.execute(aitable.select().order_by(aitable.c.id))),
             [
                 (testing.db.dialect.default_sequence_base, 1, None),
                 (testing.db.dialect.default_sequence_base + 1, None, "row 2"),
@@ -1055,7 +1057,8 @@ class PKIncrementTest(fixtures.TablesTest):
         )
 
     def test_autoincrement_autocommit(self):
-        self._test_autoincrement(testing.db)
+        with testing.db.connect() as conn:
+            self._test_autoincrement(conn)
 
     def test_autoincrement_transaction(self):
         with testing.db.begin() as conn:
index 2e3ba4245912c2d6c4d0cca7addfef8b7f4b4a87..934022560f461110b5eab958a031226dea156fe1 100644 (file)
@@ -57,7 +57,7 @@ class DeleteTest(_DeleteTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            delete(table1table1.c.myid == 7),
+            delete(table1).where(table1.c.myid == 7),
             "DELETE FROM mytable WHERE mytable.myid = :myid_1",
         )
 
@@ -118,7 +118,7 @@ class DeleteTest(_DeleteTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         # test a non-correlated WHERE clause
         s = select(table2.c.othername).where(table2.c.otherid == 7)
         self.assert_compile(
-            delete(table1table1.c.name == s.scalar_subquery()),
+            delete(table1).where(table1.c.name == s.scalar_subquery()),
             "DELETE FROM mytable "
             "WHERE mytable.name = ("
             "SELECT myothertable.othername "
@@ -133,7 +133,7 @@ class DeleteTest(_DeleteTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         # test one that is actually correlated...
         s = select(table2.c.othername).where(table2.c.otherid == table1.c.myid)
         self.assert_compile(
-            table1.delete(table1.c.name == s.scalar_subquery()),
+            table1.delete().where(table1.c.name == s.scalar_subquery()),
             "DELETE FROM mytable "
             "WHERE mytable.name = ("
             "SELECT myothertable.othername "
index a72974dbbef6d87f38aec1af54390bf33274c02e..30e4338b5d540ac5874a6bd0c9c95aacb0791e5e 100644 (file)
@@ -1,5 +1,8 @@
 #! coding: utf-8
 
+import itertools
+import random
+
 from sqlalchemy import alias
 from sqlalchemy import and_
 from sqlalchemy import bindparam
@@ -28,9 +31,11 @@ from sqlalchemy import util
 from sqlalchemy import VARCHAR
 from sqlalchemy.engine import default
 from sqlalchemy.sql import coercions
+from sqlalchemy.sql import literal
 from sqlalchemy.sql import operators
 from sqlalchemy.sql import quoted_name
 from sqlalchemy.sql import roles
+from sqlalchemy.sql import update
 from sqlalchemy.sql import visitors
 from sqlalchemy.sql.selectable import SelectStatementGrouping
 from sqlalchemy.testing import assert_raises
@@ -46,6 +51,7 @@ from sqlalchemy.testing import mock
 from sqlalchemy.testing import not_in
 from sqlalchemy.testing.schema import Column
 from sqlalchemy.testing.schema import Table
+from .test_update import _UpdateFromTestBase
 
 
 class ToMetaDataTest(fixtures.TestBase):
@@ -1675,7 +1681,7 @@ class DefaultTest(fixtures.TestBase):
             eq_(conn.execute(select(table)).first(), (5, 12))
 
 
-class DMLTest(fixtures.TestBase, AssertsCompiledSQL):
+class DMLTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
     __dialect__ = "default"
 
     def test_insert_inline_kw_defaults(self):
@@ -1770,6 +1776,259 @@ class DMLTest(fixtures.TestBase, AssertsCompiledSQL):
             stmt, "UPDATE foo SET bar=%s LIMIT 10", dialect="mysql"
         )
 
+    def test_update_whereclause(self):
+        table1 = table(
+            "mytable", Column("myid", Integer), Column("name", String(30)),
+        )
+
+        with testing.expect_deprecated_20(
+            "The update.whereclause parameter will be "
+            "removed in SQLAlchemy 2.0"
+        ):
+            self.assert_compile(
+                table1.update(table1.c.myid == 7),
+                "UPDATE mytable SET myid=:myid, name=:name "
+                "WHERE mytable.myid = :myid_1",
+            )
+
+    def test_update_values(self):
+        table1 = table(
+            "mytable", Column("myid", Integer), Column("name", String(30)),
+        )
+
+        with testing.expect_deprecated_20(
+            "The update.values parameter will be removed in SQLAlchemy 2.0"
+        ):
+            self.assert_compile(
+                table1.update(values={table1.c.myid: 7}),
+                "UPDATE mytable SET myid=:myid",
+            )
+
+    def test_delete_whereclause(self):
+        table1 = table("mytable", Column("myid", Integer),)
+
+        with testing.expect_deprecated_20(
+            "The delete.whereclause parameter will be "
+            "removed in SQLAlchemy 2.0"
+        ):
+            self.assert_compile(
+                table1.delete(table1.c.myid == 7),
+                "DELETE FROM mytable WHERE mytable.myid = :myid_1",
+            )
+
+    def test_update_ordered_parameters_fire_onupdate(self):
+        table = self.tables.update_w_default
+
+        values = [(table.c.y, table.c.x + 5), ("x", 10)]
+
+        with testing.expect_deprecated_20(
+            "The update.preserve_parameter_order parameter will be "
+            "removed in SQLAlchemy 2.0."
+        ):
+            self.assert_compile(
+                table.update(preserve_parameter_order=True).values(values),
+                "UPDATE update_w_default "
+                "SET ycol=(update_w_default.x + :x_1), "
+                "x=:x, data=:data",
+            )
+
+    def test_update_ordered_parameters_override_onupdate(self):
+        table = self.tables.update_w_default
+
+        values = [
+            (table.c.y, table.c.x + 5),
+            (table.c.data, table.c.x + 10),
+            ("x", 10),
+        ]
+
+        with testing.expect_deprecated_20(
+            "The update.preserve_parameter_order parameter will be "
+            "removed in SQLAlchemy 2.0."
+        ):
+            self.assert_compile(
+                table.update(preserve_parameter_order=True).values(values),
+                "UPDATE update_w_default "
+                "SET ycol=(update_w_default.x + :x_1), "
+                "data=(update_w_default.x + :x_2), x=:x",
+            )
+
+    def test_update_ordered_parameters_oldstyle_1(self):
+        table1 = self.tables.mytable
+
+        # Confirm that we can pass values as list value pairs
+        # note these are ordered *differently* from table.c
+        values = [
+            (table1.c.name, table1.c.name + "lala"),
+            (table1.c.myid, func.do_stuff(table1.c.myid, literal("hoho"))),
+        ]
+
+        with testing.expect_deprecated_20(
+            "The update.preserve_parameter_order parameter will be "
+            "removed in SQLAlchemy 2.0.",
+            "The update.whereclause parameter will be "
+            "removed in SQLAlchemy 2.0",
+            "The update.values parameter will be removed in SQLAlchemy 2.0",
+        ):
+            self.assert_compile(
+                update(
+                    table1,
+                    (table1.c.myid == func.hoho(4))
+                    & (
+                        table1.c.name
+                        == literal("foo") + table1.c.name + literal("lala")
+                    ),
+                    preserve_parameter_order=True,
+                    values=values,
+                ),
+                "UPDATE mytable "
+                "SET "
+                "name=(mytable.name || :name_1), "
+                "myid=do_stuff(mytable.myid, :param_1) "
+                "WHERE "
+                "mytable.myid = hoho(:hoho_1) AND "
+                "mytable.name = :param_2 || mytable.name || :param_3",
+            )
+
+    def test_update_ordered_parameters_oldstyle_2(self):
+        table1 = self.tables.mytable
+
+        # Confirm that we can pass values as list value pairs
+        # note these are ordered *differently* from table.c
+        values = [
+            (table1.c.name, table1.c.name + "lala"),
+            ("description", "some desc"),
+            (table1.c.myid, func.do_stuff(table1.c.myid, literal("hoho"))),
+        ]
+
+        with testing.expect_deprecated_20(
+            "The update.preserve_parameter_order parameter will be "
+            "removed in SQLAlchemy 2.0.",
+            "The update.whereclause parameter will be "
+            "removed in SQLAlchemy 2.0",
+        ):
+            self.assert_compile(
+                update(
+                    table1,
+                    (table1.c.myid == func.hoho(4))
+                    & (
+                        table1.c.name
+                        == literal("foo") + table1.c.name + literal("lala")
+                    ),
+                    preserve_parameter_order=True,
+                ).values(values),
+                "UPDATE mytable "
+                "SET "
+                "name=(mytable.name || :name_1), "
+                "description=:description, "
+                "myid=do_stuff(mytable.myid, :param_1) "
+                "WHERE "
+                "mytable.myid = hoho(:hoho_1) AND "
+                "mytable.name = :param_2 || mytable.name || :param_3",
+            )
+
+    def test_update_preserve_order_reqs_listtups(self):
+        table1 = self.tables.mytable
+
+        with testing.expect_deprecated_20(
+            "The update.preserve_parameter_order parameter will be "
+            "removed in SQLAlchemy 2.0."
+        ):
+            testing.assert_raises_message(
+                ValueError,
+                r"When preserve_parameter_order is True, values\(\) "
+                r"only accepts a list of 2-tuples",
+                table1.update(preserve_parameter_order=True).values,
+                {"description": "foo", "name": "bar"},
+            )
+
+    @testing.fixture
+    def randomized_param_order_update(self):
+        from sqlalchemy.sql.dml import UpdateDMLState
+
+        super_process_ordered_values = UpdateDMLState._process_ordered_values
+
+        # this fixture is needed for Python 3.6 and above to work around
+        # dictionaries being insert-ordered.  in python 2.7 the previous
+        # logic fails pretty easily without this fixture.
+        def _process_ordered_values(self, statement):
+            super_process_ordered_values(self, statement)
+
+            tuples = list(self._dict_parameters.items())
+            random.shuffle(tuples)
+            self._dict_parameters = dict(tuples)
+
+        dialect = default.StrCompileDialect()
+        dialect.paramstyle = "qmark"
+        dialect.positional = True
+
+        with mock.patch.object(
+            UpdateDMLState, "_process_ordered_values", _process_ordered_values
+        ):
+            yield
+
+    def random_update_order_parameters():
+        from sqlalchemy import ARRAY
+
+        t = table(
+            "foo",
+            column("data1", ARRAY(Integer)),
+            column("data2", ARRAY(Integer)),
+            column("data3", ARRAY(Integer)),
+            column("data4", ARRAY(Integer)),
+        )
+
+        idx_to_value = [
+            (t.c.data1, 5, 7),
+            (t.c.data2, 10, 18),
+            (t.c.data3, 8, 4),
+            (t.c.data4, 12, 14),
+        ]
+
+        def combinations():
+            while True:
+                random.shuffle(idx_to_value)
+                yield list(idx_to_value)
+
+        return testing.combinations(
+            *[
+                (t, combination)
+                for i, combination in zip(range(10), combinations())
+            ],
+            argnames="t, idx_to_value"
+        )
+
+    @random_update_order_parameters()
+    def test_update_to_expression_ppo(
+        self, randomized_param_order_update, t, idx_to_value
+    ):
+        dialect = default.StrCompileDialect()
+        dialect.paramstyle = "qmark"
+        dialect.positional = True
+
+        with testing.expect_deprecated_20(
+            "The update.preserve_parameter_order parameter will be "
+            "removed in SQLAlchemy 2.0."
+        ):
+            stmt = t.update(preserve_parameter_order=True).values(
+                [(col[idx], val) for col, idx, val in idx_to_value]
+            )
+
+        self.assert_compile(
+            stmt,
+            "UPDATE foo SET %s"
+            % (
+                ", ".join(
+                    "%s[?]=?" % col.key for col, idx, val in idx_to_value
+                )
+            ),
+            dialect=dialect,
+            checkpositional=tuple(
+                itertools.chain.from_iterable(
+                    (idx, val) for col, idx, val in idx_to_value
+                )
+            ),
+        )
+
 
 class TableDeprecationTest(fixtures.TestBase):
     def test_mustexists(self):
index c67b45203550a3c0399c637be0aa6ea9df7e93d7..970c39cefd4d833d18c04957e2e363f1060fa6b1 100644 (file)
@@ -625,7 +625,7 @@ class ClauseTest(fixtures.TestBase, AssertsCompiledSQL):
 
         assert sql_util.ClauseAdapter(u).traverse(t1) is u
 
-    def test_binds(self):
+    def test_bindparams(self):
         """test that unique bindparams change their name upon clone()
         to prevent conflicts"""
 
@@ -1513,7 +1513,7 @@ class ClauseAdapterTest(fixtures.TestBase, AssertsCompiledSQL):
         t1alias = t1.alias("t1alias")
         vis = sql_util.ClauseAdapter(t1alias)
         self.assert_compile(
-            vis.traverse(case([(t1.c.col1 == 5, t1.c.col2)], else_=t1.c.col1)),
+            vis.traverse(case((t1.c.col1 == 5, t1.c.col2), else_=t1.c.col1)),
             "CASE WHEN (t1alias.col1 = :col1_1) THEN "
             "t1alias.col2 ELSE t1alias.col1 END",
         )
@@ -1523,7 +1523,7 @@ class ClauseAdapterTest(fixtures.TestBase, AssertsCompiledSQL):
         vis = sql_util.ClauseAdapter(t1alias)
         self.assert_compile(
             vis.traverse(
-                case([(5, t1.c.col2)], value=t1.c.col1, else_=t1.c.col1)
+                case((5, t1.c.col2), value=t1.c.col1, else_=t1.c.col1)
             ),
             "CASE t1alias.col1 WHEN :param_1 THEN "
             "t1alias.col2 ELSE t1alias.col1 END",
@@ -2152,7 +2152,7 @@ class ValuesBaseTest(fixtures.TestBase, AssertsCompiledSQL):
             "VALUES (:col1, :col2, :col3)",
         )
 
-        i2 = t1.insert(prefixes=["squiznart"])
+        i2 = t1.insert().prefix_with("squiznart")
         self.assert_compile(
             i2,
             "INSERT squiznart INTO table1 (col1, col2, col3) "
@@ -2223,7 +2223,7 @@ class ValuesBaseTest(fixtures.TestBase, AssertsCompiledSQL):
         )
 
     def test_inline_values_single(self):
-        i = t1.insert(values={"col1": 5})
+        i = t1.insert().values({"col1": 5})
 
         compile_state = i._compile_state_factory(i, None)
 
@@ -2231,7 +2231,7 @@ class ValuesBaseTest(fixtures.TestBase, AssertsCompiledSQL):
         is_(compile_state._has_multi_parameters, False)
 
     def test_inline_values_multi(self):
-        i = t1.insert(values=[{"col1": 5}, {"col1": 6}])
+        i = t1.insert().values([{"col1": 5}, {"col1": 6}])
 
         compile_state = i._compile_state_factory(i, None)
 
@@ -2354,7 +2354,7 @@ class ValuesBaseTest(fixtures.TestBase, AssertsCompiledSQL):
         )
 
     def test_update_no_support_multi_constructor(self):
-        stmt = t1.update(values=[{"col1": 5}, {"col1": 7}])
+        stmt = t1.update().values([{"col1": 5}, {"col1": 7}])
 
         assert_raises_message(
             exc.InvalidRequestError,
index 73954a8afc1080e2be48a66853d61a27e4b939f8..3c6140b81c8ef47cbff89790ab84d20bb2810b27 100644 (file)
@@ -990,30 +990,32 @@ class ExecuteTest(fixtures.TestBase):
             Column("stuff", String(20), onupdate="thisisstuff"),
         )
         meta.create_all(connection)
-        connection.execute(t.insert(values=dict(value=func.length("one"))))
+        connection.execute(t.insert().values(value=func.length("one")))
         eq_(connection.execute(t.select()).first().value, 3)
-        connection.execute(t.update(values=dict(value=func.length("asfda"))))
+        connection.execute(t.update().values(value=func.length("asfda")))
         eq_(connection.execute(t.select()).first().value, 5)
 
         r = connection.execute(
-            t.insert(values=dict(value=func.length("sfsaafsda")))
+            t.insert().values(value=func.length("sfsaafsda"))
         )
         id_ = r.inserted_primary_key[0]
-        eq_(connection.execute(t.select(t.c.id == id_)).first().value, 9)
-        connection.execute(t.update(values={t.c.value: func.length("asdf")}))
+        eq_(
+            connection.execute(t.select().where(t.c.id == id_)).first().value,
+            9,
+        )
+        connection.execute(t.update().values({t.c.value: func.length("asdf")}))
         eq_(connection.execute(t.select()).first().value, 4)
         connection.execute(t2.insert())
-        connection.execute(t2.insert(values=dict(value=func.length("one"))))
+        connection.execute(t2.insert().values(value=func.length("one")))
         connection.execute(
-            t2.insert(values=dict(value=func.length("asfda") + -19)),
-            stuff="hi",
+            t2.insert().values(value=func.length("asfda") + -19), stuff="hi",
         )
 
         res = sorted(connection.execute(select(t2.c.value, t2.c.stuff)))
         eq_(res, [(-14, "hi"), (3, None), (7, None)])
 
         connection.execute(
-            t2.update(values=dict(value=func.length("asdsafasd"))),
+            t2.update().values(value=func.length("asdsafasd")),
             stuff="some stuff",
         )
         eq_(
@@ -1023,23 +1025,18 @@ class ExecuteTest(fixtures.TestBase):
 
         connection.execute(t2.delete())
 
-        connection.execute(
-            t2.insert(values=dict(value=func.length("one") + 8))
-        )
+        connection.execute(t2.insert().values(value=func.length("one") + 8))
         eq_(connection.execute(t2.select()).first().value, 11)
 
-        connection.execute(t2.update(values=dict(value=func.length("asfda"))))
+        connection.execute(t2.update().values(value=func.length("asfda")))
         eq_(
             connection.execute(select(t2.c.value, t2.c.stuff)).first(),
             (5, "thisisstuff"),
         )
 
         connection.execute(
-            t2.update(
-                values={
-                    t2.c.value: func.length("asfdaasdf"),
-                    t2.c.stuff: "foo",
-                }
+            t2.update().values(
+                {t2.c.value: func.length("asfdaasdf"), t2.c.stuff: "foo"}
             )
         )
 
index 3cdf291ec18fde54bbfea5562f70b8e53bfe562c..541ffc4e966780609102d6d557428804859e7308 100644 (file)
@@ -164,7 +164,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         checkparams = {"myid": 3, "name": "jack"}
 
         self.assert_compile(
-            insert(table1, dict(myid=3, name="jack")),
+            insert(table1).values(myid=3, name="jack"),
             "INSERT INTO mytable (myid, name) VALUES (:myid, :name)",
             checkparams=checkparams,
         )
@@ -194,7 +194,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
 
         checkparams = {"myid": 3, "name": "jack", "unknowncol": "oops"}
 
-        stmt = insert(table1, values=checkparams)
+        stmt = insert(table1).values(checkparams)
         assert_raises_message(
             exc.CompileError,
             "Unconsumed column names: unknowncol",
@@ -210,7 +210,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             {"myid": 4, "name": "someone", "unknowncol": "oops"},
         ]
 
-        stmt = insert(table1, values=checkparams)
+        stmt = insert(table1).values(checkparams)
         assert_raises_message(
             exc.CompileError,
             "Unconsumed column names: unknowncol",
@@ -228,7 +228,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         }
 
         self.assert_compile(
-            insert(table1, (3, "jack", "mydescription")),
+            insert(table1).values([3, "jack", "mydescription"]),
             "INSERT INTO mytable (myid, name, description) "
             "VALUES (:myid, :name, :description)",
             checkparams=checkparams,
@@ -238,7 +238,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            insert(table1, values=dict(myid=func.lala())),
+            insert(table1).values(myid=func.lala()),
             "INSERT INTO mytable (myid) VALUES (lala())",
         )
 
@@ -251,7 +251,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         }
 
         self.assert_compile(
-            insert(table1values),
+            insert(table1).values(values),
             "INSERT INTO mytable (myid, name) VALUES (:userid, :username)",
         )
 
@@ -262,7 +262,7 @@ class InsertTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         values2 = {table1.c.name: bindparam("username")}
 
         self.assert_compile(
-            insert(table1, values=values1).values(values2),
+            insert(table1).values(values1).values(values2),
             "INSERT INTO mytable (myid, name) VALUES (:userid, :username)",
         )
 
index c4266603ecba0aa2e4b04fdd87c8c7550528e339..45a8bccf538e905716be0e4b3b423deca54bad55 100644 (file)
@@ -36,23 +36,29 @@ class InsertExecTest(fixtures.TablesTest):
         )
 
     @testing.requires.multivalues_inserts
-    def test_multivalues_insert(self):
+    def test_multivalues_insert(self, connection):
         users = self.tables.users
-        users.insert(
-            values=[
-                {"user_id": 7, "user_name": "jack"},
-                {"user_id": 8, "user_name": "ed"},
-            ]
-        ).execute()
-        rows = users.select().order_by(users.c.user_id).execute().fetchall()
+        connection.execute(
+            users.insert().values(
+                [
+                    {"user_id": 7, "user_name": "jack"},
+                    {"user_id": 8, "user_name": "ed"},
+                ]
+            )
+        )
+        rows = connection.execute(
+            users.select().order_by(users.c.user_id)
+        ).all()
         eq_(rows[0], (7, "jack"))
         eq_(rows[1], (8, "ed"))
-        users.insert(values=[(9, "jack"), (10, "ed")]).execute()
-        rows = users.select().order_by(users.c.user_id).execute().fetchall()
+        connection.execute(users.insert().values([(9, "jack"), (10, "ed")]))
+        rows = connection.execute(
+            users.select().order_by(users.c.user_id)
+        ).all()
         eq_(rows[2], (9, "jack"))
         eq_(rows[3], (10, "ed"))
 
-    def test_insert_heterogeneous_params(self):
+    def test_insert_heterogeneous_params(self, connection):
         """test that executemany parameters are asserted to match the
         parameter set of the first."""
         users = self.tables.users
@@ -63,16 +69,22 @@ class InsertExecTest(fixtures.TablesTest):
             "bind parameter 'user_name', in "
             "parameter group 2\n"
             r"\[SQL: u?INSERT INTO users",
-            users.insert().execute,
-            {"user_id": 7, "user_name": "jack"},
-            {"user_id": 8, "user_name": "ed"},
-            {"user_id": 9},
+            connection.execute,
+            users.insert(),
+            [
+                {"user_id": 7, "user_name": "jack"},
+                {"user_id": 8, "user_name": "ed"},
+                {"user_id": 9},
+            ],
         )
 
         # this succeeds however.   We aren't yet doing
         # a length check on all subsequent parameters.
-        users.insert().execute(
-            {"user_id": 7}, {"user_id": 8, "user_name": "ed"}, {"user_id": 9}
+        connection.execute(
+            users.insert(),
+            {"user_id": 7},
+            {"user_id": 8, "user_name": "ed"},
+            {"user_id": 9},
         )
 
     def _test_lastrow_accessor(self, table_, values, assertvalues):
@@ -94,26 +106,29 @@ class InsertExecTest(fixtures.TablesTest):
                 ):
                     is_(bool(comp.returning), True)
 
-            result = engine.execute(table_.insert(), **values)
-            ret = values.copy()
-
-            for col, id_ in zip(
-                table_.primary_key, result.inserted_primary_key
-            ):
-                ret[col.key] = id_
-
-            if result.lastrow_has_defaults():
-                criterion = and_(
-                    *[
-                        col == id_
-                        for col, id_ in zip(
-                            table_.primary_key, result.inserted_primary_key
-                        )
-                    ]
-                )
-                row = engine.execute(table_.select(criterion)).first()
-                for c in table_.c:
-                    ret[c.key] = row._mapping[c]
+            with engine.begin() as connection:
+                result = connection.execute(table_.insert(), **values)
+                ret = values.copy()
+
+                for col, id_ in zip(
+                    table_.primary_key, result.inserted_primary_key
+                ):
+                    ret[col.key] = id_
+
+                if result.lastrow_has_defaults():
+                    criterion = and_(
+                        *[
+                            col == id_
+                            for col, id_ in zip(
+                                table_.primary_key, result.inserted_primary_key
+                            )
+                        ]
+                    )
+                    row = connection.execute(
+                        table_.select().where(criterion)
+                    ).first()
+                    for c in table_.c:
+                        ret[c.key] = row._mapping[c]
             return ret
 
         if testing.against("firebird", "postgresql", "oracle", "mssql"):
@@ -275,15 +290,16 @@ class InsertExecTest(fixtures.TablesTest):
             Column("x", Integer, primary_key=True),
             Column("y", Integer),
         )
-        t.create(eng)
-        r = eng.execute(t.insert().values(y=5))
-        eq_(r.inserted_primary_key, (0,))
+        with eng.begin() as conn:
+            t.create(conn)
+            r = conn.execute(t.insert().values(y=5))
+            eq_(r.inserted_primary_key, (0,))
 
     @testing.fails_on(
         "sqlite", "sqlite autoincrement doesn't work with composite pks"
     )
     @testing.provide_metadata
-    def test_misordered_lastrow(self):
+    def test_misordered_lastrow(self, connection):
         metadata = self.metadata
 
         related = Table(
@@ -312,37 +328,39 @@ class InsertExecTest(fixtures.TablesTest):
             mariadb_engine="MyISAM",
         )
 
-        metadata.create_all()
-        r = related.insert().values(id=12).execute()
+        metadata.create_all(connection)
+        r = connection.execute(related.insert().values(id=12))
         id_ = r.inserted_primary_key[0]
         eq_(id_, 12)
 
-        r = t6.insert().values(manual_id=id_).execute()
+        r = connection.execute(t6.insert().values(manual_id=id_))
         eq_(r.inserted_primary_key, (12, 1))
 
-    def test_implicit_id_insert_select_columns(self):
+    def test_implicit_id_insert_select_columns(self, connection):
         users = self.tables.users
         stmt = users.insert().from_select(
             (users.c.user_id, users.c.user_name),
             users.select().where(users.c.user_id == 20),
         )
 
-        testing.db.execute(stmt)
+        r = connection.execute(stmt)
+        eq_(r.inserted_primary_key, (None,))
 
-    def test_implicit_id_insert_select_keys(self):
+    def test_implicit_id_insert_select_keys(self, connection):
         users = self.tables.users
         stmt = users.insert().from_select(
             ["user_id", "user_name"],
             users.select().where(users.c.user_id == 20),
         )
 
-        testing.db.execute(stmt)
+        r = connection.execute(stmt)
+        eq_(r.inserted_primary_key, (None,))
 
     @testing.requires.empty_inserts
     @testing.requires.returning
-    def test_no_inserted_pk_on_returning(self):
+    def test_no_inserted_pk_on_returning(self, connection):
         users = self.tables.users
-        result = testing.db.execute(
+        result = connection.execute(
             users.insert().returning(users.c.user_id, users.c.user_name)
         )
         assert_raises_message(
@@ -399,52 +417,60 @@ class TableInsertTest(fixtures.TablesTest):
         return t
 
     def _test(
-        self, stmt, row, returning=None, inserted_primary_key=False, table=None
+        self,
+        connection,
+        stmt,
+        row,
+        returning=None,
+        inserted_primary_key=False,
+        table=None,
     ):
-        with testing.db.connect() as conn:
-            r = conn.execute(stmt)
+        r = connection.execute(stmt)
 
-            if returning:
-                returned = r.first()
-                eq_(returned, returning)
-            elif inserted_primary_key is not False:
-                eq_(r.inserted_primary_key, inserted_primary_key)
+        if returning:
+            returned = r.first()
+            eq_(returned, returning)
+        elif inserted_primary_key is not False:
+            eq_(r.inserted_primary_key, inserted_primary_key)
 
-            if table is None:
-                table = self.tables.foo
+        if table is None:
+            table = self.tables.foo
 
-            eq_(conn.execute(table.select()).first(), row)
+        eq_(connection.execute(table.select()).first(), row)
 
-    def _test_multi(self, stmt, rows, data):
-        testing.db.execute(stmt, rows)
+    def _test_multi(self, connection, stmt, rows, data):
+        connection.execute(stmt, rows)
         eq_(
-            testing.db.execute(
+            connection.execute(
                 self.tables.foo.select().order_by(self.tables.foo.c.id)
-            ).fetchall(),
+            ).all(),
             data,
         )
 
     @testing.requires.sequences
-    def test_explicit_sequence(self):
+    def test_explicit_sequence(self, connection):
         t = self._fixture()
         self._test(
+            connection,
             t.insert().values(
                 id=func.next_value(Sequence("t_id_seq")), data="data", x=5
             ),
             (testing.db.dialect.default_sequence_base, "data", 5),
         )
 
-    def test_uppercase(self):
+    def test_uppercase(self, connection):
         t = self.tables.foo
         self._test(
+            connection,
             t.insert().values(id=1, data="data", x=5),
             (1, "data", 5),
             inserted_primary_key=(1,),
         )
 
-    def test_uppercase_inline(self):
+    def test_uppercase_inline(self, connection):
         t = self.tables.foo
         self._test(
+            connection,
             t.insert().inline().values(id=1, data="data", x=5),
             (1, "data", 5),
             inserted_primary_key=(1,),
@@ -454,64 +480,71 @@ class TableInsertTest(fixtures.TablesTest):
         "mssql+pyodbc",
         "Pyodbc + SQL Server + Py3K, some decimal handling issue",
     )
-    def test_uppercase_inline_implicit(self):
+    def test_uppercase_inline_implicit(self, connection):
         t = self.tables.foo
         self._test(
+            connection,
             t.insert().inline().values(data="data", x=5),
             (1, "data", 5),
             inserted_primary_key=(None,),
         )
 
-    def test_uppercase_implicit(self):
+    def test_uppercase_implicit(self, connection):
         t = self.tables.foo
         self._test(
+            connection,
             t.insert().values(data="data", x=5),
             (testing.db.dialect.default_sequence_base, "data", 5),
             inserted_primary_key=(testing.db.dialect.default_sequence_base,),
         )
 
-    def test_uppercase_direct_params(self):
+    def test_uppercase_direct_params(self, connection):
         t = self.tables.foo
         self._test(
+            connection,
             t.insert().values(id=1, data="data", x=5),
             (1, "data", 5),
             inserted_primary_key=(1,),
         )
 
     @testing.requires.returning
-    def test_uppercase_direct_params_returning(self):
+    def test_uppercase_direct_params_returning(self, connection):
         t = self.tables.foo
         self._test(
+            connection,
             t.insert().values(id=1, data="data", x=5).returning(t.c.id, t.c.x),
             (1, "data", 5),
             returning=(1, 5),
         )
 
     @testing.requires.sql_expressions_inserted_as_primary_key
-    def test_sql_expr_lastrowid(self):
+    def test_sql_expr_lastrowid(self, connection):
 
         # see also test.orm.test_unitofwork.py
         # ClauseAttributesTest.test_insert_pk_expression
         t = self.tables.foo_no_seq
         self._test(
+            connection,
             t.insert().values(id=literal(5) + 10, data="data", x=5),
             (15, "data", 5),
             inserted_primary_key=(15,),
             table=self.tables.foo_no_seq,
         )
 
-    def test_direct_params(self):
+    def test_direct_params(self, connection):
         t = self._fixture()
         self._test(
+            connection,
             t.insert().values(id=1, data="data", x=5),
             (1, "data", 5),
             inserted_primary_key=(),
         )
 
     @testing.requires.returning
-    def test_direct_params_returning(self):
+    def test_direct_params_returning(self, connection):
         t = self._fixture()
         self._test(
+            connection,
             t.insert().values(id=1, data="data", x=5).returning(t.c.id, t.c.x),
             (testing.db.dialect.default_sequence_base, "data", 5),
             returning=(testing.db.dialect.default_sequence_base, 5),
@@ -523,9 +556,10 @@ class TableInsertTest(fixtures.TablesTest):
     # does not indicate the Sequence
     @testing.fails_if(testing.requires.sequences)
     @testing.requires.emulated_lastrowid
-    def test_implicit_pk(self):
+    def test_implicit_pk(self, connection):
         t = self._fixture()
         self._test(
+            connection,
             t.insert().values(data="data", x=5),
             (testing.db.dialect.default_sequence_base, "data", 5),
             inserted_primary_key=(),
@@ -533,9 +567,10 @@ class TableInsertTest(fixtures.TablesTest):
 
     @testing.fails_if(testing.requires.sequences)
     @testing.requires.emulated_lastrowid
-    def test_implicit_pk_multi_rows(self):
+    def test_implicit_pk_multi_rows(self, connection):
         t = self._fixture()
         self._test_multi(
+            connection,
             t.insert(),
             [
                 {"data": "d1", "x": 5},
@@ -547,9 +582,10 @@ class TableInsertTest(fixtures.TablesTest):
 
     @testing.fails_if(testing.requires.sequences)
     @testing.requires.emulated_lastrowid
-    def test_implicit_pk_inline(self):
+    def test_implicit_pk_inline(self, connection):
         t = self._fixture()
         self._test(
+            connection,
             t.insert().inline().values(data="data", x=5),
             (testing.db.dialect.default_sequence_base, "data", 5),
             inserted_primary_key=(),
index 731f8fcb5cee0c992da2ac970e90ac3a9157289b..e3fdff8069f5f83ee73cfb1faaa560566f15a5c2 100644 (file)
@@ -273,15 +273,20 @@ class MaxIdentTest(fixtures.TestBase, AssertsCompiledSQL):
         # version) generate a subquery for limits/offsets. ensure that the
         # generated result map corresponds to the selected table, not the
         # select query
-        s = table1.select(
-            use_labels=True, order_by=[table1.c.this_is_the_primarykey_column]
-        ).limit(2)
+        s = (
+            table1.select()
+            .apply_labels()
+            .order_by(table1.c.this_is_the_primarykey_column)
+            .limit(2)
+        )
         self._assert_labeled_table1_select(s)
 
     def test_result_map_subquery(self):
         table1 = self.table1
-        s = table1.select(table1.c.this_is_the_primarykey_column == 4).alias(
-            "foo"
+        s = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias("foo")
         )
         s2 = select(s)
         compiled = s2.compile(dialect=self._length_fixture())
@@ -302,7 +307,11 @@ class MaxIdentTest(fixtures.TestBase, AssertsCompiledSQL):
         table1 = self.table1
         dialect = self._length_fixture()
 
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias()
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias()
+        )
         s = select(q).apply_labels()
 
         self.assert_compile(
@@ -348,7 +357,7 @@ class MaxIdentTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_column_bind_labels_1(self):
         table1 = self.table1
 
-        s = table1.select(table1.c.this_is_the_primarykey_column == 4)
+        s = table1.select().where(table1.c.this_is_the_primarykey_column == 4)
         self.assert_compile(
             s,
             "SELECT some_large_named_table.this_is_the_primarykey_column, "
@@ -375,7 +384,7 @@ class MaxIdentTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_column_bind_labels_2(self):
         table1 = self.table1
 
-        s = table1.select(
+        s = table1.select().where(
             or_(
                 table1.c.this_is_the_primarykey_column == 4,
                 table1.c.this_is_the_primarykey_column == 2,
@@ -473,8 +482,10 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
 
     def test_adjustable_1(self):
         table1 = self.table1
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias(
-            "foo"
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias("foo")
         )
         x = select(q)
         compile_dialect = default.DefaultDialect(label_length=10)
@@ -501,8 +512,10 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_adjustable_2(self):
         table1 = self.table1
 
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias(
-            "foo"
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias("foo")
         )
         x = select(q)
 
@@ -531,8 +544,10 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
         table1 = self.table1
 
         compile_dialect = default.DefaultDialect(label_length=4)
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias(
-            "foo"
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias("foo")
         )
         x = select(q)
 
@@ -559,7 +574,11 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_adjustable_4(self):
         table1 = self.table1
 
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias()
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias()
+        )
         x = select(q).apply_labels()
 
         compile_dialect = default.DefaultDialect(label_length=10)
@@ -586,7 +605,11 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
 
     def test_adjustable_5(self):
         table1 = self.table1
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias()
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias()
+        )
         x = select(q).apply_labels()
 
         compile_dialect = default.DefaultDialect(label_length=4)
@@ -615,7 +638,8 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
         table1 = self.table1
 
         q = (
-            table1.select(table1.c.this_is_the_primarykey_column == 4)
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
             .apply_labels()
             .alias("foo")
         )
@@ -642,8 +666,10 @@ class LabelLengthTest(fixtures.TestBase, AssertsCompiledSQL):
     def test_adjustable_result_schema_column_2(self):
         table1 = self.table1
 
-        q = table1.select(table1.c.this_is_the_primarykey_column == 4).alias(
-            "foo"
+        q = (
+            table1.select()
+            .where(table1.c.this_is_the_primarykey_column == 4)
+            .alias("foo")
         )
         x = select(q)
 
index 2fb50f37d04fc6425887794302bd40b82f5f5bd4..26d4969c87c85729acbd72eda973bbb31b19cab4 100644 (file)
@@ -370,7 +370,7 @@ class ReturnDefaultsTest(fixtures.TablesTest):
     def test_arg_insert_pk(self, connection):
         t1 = self.tables.t1
         result = connection.execute(
-            t1.insert(return_defaults=[t1.c.insdef]).values(upddef=1)
+            t1.insert().return_defaults(t1.c.insdef).values(upddef=1)
         )
         eq_(
             [
@@ -394,7 +394,7 @@ class ReturnDefaultsTest(fixtures.TablesTest):
         t1 = self.tables.t1
         connection.execute(t1.insert().values(upddef=1))
         result = connection.execute(
-            t1.update(return_defaults=[t1.c.upddef]).values(data="d1")
+            t1.update().return_defaults(t1.c.upddef).values(data="d1")
         )
         eq_(
             [result.returned_defaults._mapping[k] for k in (t1.c.upddef,)], [1]
index a5e57a78afe7d2615d2b761c818b954b9941f481..8be5868dbf720bc4c6dcc8524d7509ed3dbeb6eb 100644 (file)
@@ -195,13 +195,12 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         # test against a straight text subquery
-        u = update(
-            table1,
-            values={
+        u = update(table1).values(
+            {
                 table1.c.name: text(
                     "(select name from mytable where id=mytable.id)"
                 )
-            },
+            }
         )
         self.assert_compile(
             u,
@@ -213,13 +212,12 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         mt = table1.alias()
-        u = update(
-            table1,
-            values={
+        u = update(table1).values(
+            {
                 table1.c.name: select(mt.c.name)
                 .where(mt.c.myid == table1.c.myid)
                 .scalar_subquery()
-            },
+            }
         )
         self.assert_compile(
             u,
@@ -238,7 +236,11 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             .where(table2.c.otherid == table1.c.myid)
             .scalar_subquery()
         )
-        u = update(table1, table1.c.name == "jack", values={table1.c.name: s})
+        u = (
+            update(table1)
+            .where(table1.c.name == "jack")
+            .values({table1.c.name: s})
+        )
         self.assert_compile(
             u,
             "UPDATE mytable SET name=(SELECT myothertable.otherid, "
@@ -253,7 +255,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
 
         # test a non-correlated WHERE clause
         s = select(table2.c.othername).where(table2.c.otherid == 7)
-        u = update(table1table1.c.name == s.scalar_subquery())
+        u = update(table1).where(table1.c.name == s.scalar_subquery())
         self.assert_compile(
             u,
             "UPDATE mytable SET myid=:myid, name=:name, "
@@ -268,7 +270,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
 
         # test one that is actually correlated...
         s = select(table2.c.othername).where(table2.c.otherid == table1.c.myid)
-        u = table1.update(table1.c.name == s.scalar_subquery())
+        u = table1.update().where(table1.c.name == s.scalar_subquery())
         self.assert_compile(
             u,
             "UPDATE mytable SET myid=:myid, name=:name, "
@@ -420,7 +422,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(table1table1.c.myid == 7),
+            update(table1).where(table1.c.myid == 7),
             "UPDATE mytable SET name=:name WHERE mytable.myid = :myid_1",
             params={table1.c.name: "fred"},
         )
@@ -440,7 +442,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(table1table1.c.myid == 7),
+            update(table1).where(table1.c.myid == 7),
             "UPDATE mytable SET name=:name WHERE mytable.myid = :myid_1",
             params={"name": "fred"},
         )
@@ -449,7 +451,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(table1, values={table1.c.name: table1.c.myid}),
+            update(table1).values({table1.c.name: table1.c.myid}),
             "UPDATE mytable SET name=mytable.myid",
         )
 
@@ -457,11 +459,9 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(
-                table1,
-                whereclause=table1.c.name == bindparam("crit"),
-                values={table1.c.name: "hi"},
-            ),
+            update(table1)
+            .where(table1.c.name == bindparam("crit"))
+            .values({table1.c.name: "hi"},),
             "UPDATE mytable SET name=:name WHERE mytable.name = :crit",
             params={"crit": "notthere"},
             checkparams={"crit": "notthere", "name": "hi"},
@@ -471,11 +471,9 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(
-                table1,
-                table1.c.myid == 12,
-                values={table1.c.name: table1.c.myid},
-            ),
+            update(table1)
+            .where(table1.c.myid == 12)
+            .values({table1.c.name: table1.c.myid},),
             "UPDATE mytable "
             "SET name=mytable.myid, description=:description "
             "WHERE mytable.myid = :myid_1",
@@ -487,7 +485,9 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(table1, table1.c.myid == 12, values={table1.c.myid: 9}),
+            update(table1)
+            .where(table1.c.myid == 12)
+            .values({table1.c.myid: 9}),
             "UPDATE mytable "
             "SET myid=:myid, description=:description "
             "WHERE mytable.myid = :myid_1",
@@ -498,7 +498,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         table1 = self.tables.mytable
 
         self.assert_compile(
-            update(table1table1.c.myid == 12),
+            update(table1).where(table1.c.myid == 12),
             "UPDATE mytable SET myid=:myid WHERE mytable.myid = :myid_1",
             params={"myid": 18},
             checkparams={"myid": 18, "myid_1": 12},
@@ -507,7 +507,11 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
     def test_update_9(self):
         table1 = self.tables.mytable
 
-        s = table1.update(table1.c.myid == 12, values={table1.c.name: "lala"})
+        s = (
+            table1.update()
+            .where(table1.c.myid == 12)
+            .values({table1.c.name: "lala"})
+        )
         c = s.compile(column_keys=["id", "name"])
         eq_(str(s), str(c))
 
@@ -517,7 +521,7 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         v1 = {table1.c.name: table1.c.myid}
         v2 = {table1.c.name: table1.c.name + "foo"}
         self.assert_compile(
-            update(table1, table1.c.myid == 12, values=v1).values(v2),
+            update(table1).where(table1.c.myid == 12).values(v1).values(v2),
             "UPDATE mytable "
             "SET "
             "name=(mytable.name || :name_1), "
@@ -535,15 +539,15 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         }
 
         self.assert_compile(
-            update(
-                table1,
+            update(table1)
+            .where(
                 (table1.c.myid == func.hoho(4))
                 & (
                     table1.c.name
                     == literal("foo") + table1.c.name + literal("lala")
-                ),
-                values=values,
-            ),
+                )
+            )
+            .values(values),
             "UPDATE mytable "
             "SET "
             "myid=do_stuff(mytable.myid, :param_1), "
@@ -586,35 +590,6 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             column_keys=["j"],
         )
 
-    def test_update_ordered_parameters_oldstyle_1(self):
-        table1 = self.tables.mytable
-
-        # Confirm that we can pass values as list value pairs
-        # note these are ordered *differently* from table.c
-        values = [
-            (table1.c.name, table1.c.name + "lala"),
-            (table1.c.myid, func.do_stuff(table1.c.myid, literal("hoho"))),
-        ]
-        self.assert_compile(
-            update(
-                table1,
-                (table1.c.myid == func.hoho(4))
-                & (
-                    table1.c.name
-                    == literal("foo") + table1.c.name + literal("lala")
-                ),
-                preserve_parameter_order=True,
-                values=values,
-            ),
-            "UPDATE mytable "
-            "SET "
-            "name=(mytable.name || :name_1), "
-            "myid=do_stuff(mytable.myid, :param_1) "
-            "WHERE "
-            "mytable.myid = hoho(:hoho_1) AND "
-            "mytable.name = :param_2 || mytable.name || :param_3",
-        )
-
     def test_update_ordered_parameters_newstyle_1(self):
         table1 = self.tables.mytable
 
@@ -643,36 +618,6 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             "mytable.name = :param_2 || mytable.name || :param_3",
         )
 
-    def test_update_ordered_parameters_oldstyle_2(self):
-        table1 = self.tables.mytable
-
-        # Confirm that we can pass values as list value pairs
-        # note these are ordered *differently* from table.c
-        values = [
-            (table1.c.name, table1.c.name + "lala"),
-            ("description", "some desc"),
-            (table1.c.myid, func.do_stuff(table1.c.myid, literal("hoho"))),
-        ]
-        self.assert_compile(
-            update(
-                table1,
-                (table1.c.myid == func.hoho(4))
-                & (
-                    table1.c.name
-                    == literal("foo") + table1.c.name + literal("lala")
-                ),
-                preserve_parameter_order=True,
-            ).values(values),
-            "UPDATE mytable "
-            "SET "
-            "name=(mytable.name || :name_1), "
-            "description=:description, "
-            "myid=do_stuff(mytable.myid, :param_1) "
-            "WHERE "
-            "mytable.myid = hoho(:hoho_1) AND "
-            "mytable.name = :param_2 || mytable.name || :param_3",
-        )
-
     def test_update_ordered_parameters_newstyle_2(self):
         table1 = self.tables.mytable
 
@@ -684,14 +629,15 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             (table1.c.myid, func.do_stuff(table1.c.myid, literal("hoho"))),
         ]
         self.assert_compile(
-            update(
-                table1,
+            update(table1)
+            .where(
                 (table1.c.myid == func.hoho(4))
                 & (
                     table1.c.name
                     == literal("foo") + table1.c.name + literal("lala")
                 ),
-            ).ordered_values(*values),
+            )
+            .ordered_values(*values),
             "UPDATE mytable "
             "SET "
             "name=(mytable.name || :name_1), "
@@ -741,42 +687,6 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             stmt.compile,
         )
 
-    def test_update_ordered_parameters_fire_onupdate(self):
-        table = self.tables.update_w_default
-
-        values = [(table.c.y, table.c.x + 5), ("x", 10)]
-
-        self.assert_compile(
-            table.update(preserve_parameter_order=True).values(values),
-            "UPDATE update_w_default SET ycol=(update_w_default.x + :x_1), "
-            "x=:x, data=:data",
-        )
-
-    def test_update_ordered_parameters_override_onupdate(self):
-        table = self.tables.update_w_default
-
-        values = [
-            (table.c.y, table.c.x + 5),
-            (table.c.data, table.c.x + 10),
-            ("x", 10),
-        ]
-
-        self.assert_compile(
-            table.update(preserve_parameter_order=True).values(values),
-            "UPDATE update_w_default SET ycol=(update_w_default.x + :x_1), "
-            "data=(update_w_default.x + :x_2), x=:x",
-        )
-
-    def test_update_preserve_order_reqs_listtups(self):
-        table1 = self.tables.mytable
-        testing.assert_raises_message(
-            ValueError,
-            r"When preserve_parameter_order is True, values\(\) "
-            r"only accepts a list of 2-tuples",
-            table1.update(preserve_parameter_order=True).values,
-            {"description": "foo", "name": "bar"},
-        )
-
     def test_update_ordereddict(self):
         table1 = self.tables.mytable
 
@@ -790,15 +700,15 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
         )
 
         self.assert_compile(
-            update(
-                table1,
+            update(table1)
+            .where(
                 (table1.c.myid == func.hoho(4))
                 & (
                     table1.c.name
                     == literal("foo") + table1.c.name + literal("lala")
                 ),
-                values=values,
-            ),
+            )
+            .values(values),
             "UPDATE mytable "
             "SET "
             "myid=do_stuff(mytable.myid, :param_1), "
@@ -954,35 +864,6 @@ class UpdateTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL):
             ),
         )
 
-    @random_update_order_parameters()
-    def test_update_to_expression_ppo(
-        self, randomized_param_order_update, t, idx_to_value
-    ):
-        dialect = default.StrCompileDialect()
-        dialect.paramstyle = "qmark"
-        dialect.positional = True
-
-        # deprecated pattern here
-        stmt = t.update(preserve_parameter_order=True).values(
-            [(col[idx], val) for col, idx, val in idx_to_value]
-        )
-
-        self.assert_compile(
-            stmt,
-            "UPDATE foo SET %s"
-            % (
-                ", ".join(
-                    "%s[?]=?" % col.key for col, idx, val in idx_to_value
-                )
-            ),
-            dialect=dialect,
-            checkpositional=tuple(
-                itertools.chain.from_iterable(
-                    (idx, val) for col, idx, val in idx_to_value
-                )
-            ),
-        )
-
     def test_update_to_expression_three(self):
         # this test is from test_defaults but exercises a particular
         # parameter ordering issue
@@ -1076,9 +957,9 @@ class UpdateFromCompileTest(
         # against the alias, but we name the table-bound column
         # in values.   The behavior here isn't really defined
         self.assert_compile(
-            update(talias1, talias1.c.myid == 7).values(
-                {table1.c.name: "fred"}
-            ),
+            update(talias1)
+            .where(talias1.c.myid == 7)
+            .values({table1.c.name: "fred"}),
             "UPDATE mytable AS t1 "
             "SET name=:name "
             "WHERE t1.myid = :myid_1",
@@ -1093,9 +974,9 @@ class UpdateFromCompileTest(
         # which is causing the "table1.c.name" param to be handled
         # as an "extra table", hence we see the full table name rendered.
         self.assert_compile(
-            update(talias1, table1.c.myid == 7).values(
-                {table1.c.name: "fred"}
-            ),
+            update(talias1)
+            .where(table1.c.myid == 7)
+            .values({table1.c.name: "fred"}),
             "UPDATE mytable AS t1 "
             "SET name=:mytable_name "
             "FROM mytable "
@@ -1108,9 +989,9 @@ class UpdateFromCompileTest(
         talias1 = table1.alias("t1")
 
         self.assert_compile(
-            update(talias1, table1.c.myid == 7).values(
-                {table1.c.name: "fred"}
-            ),
+            update(talias1)
+            .where(table1.c.myid == 7)
+            .values({table1.c.name: "fred"}),
             "UPDATE mytable AS t1, mytable SET mytable.name=%s "
             "WHERE mytable.myid = %s",
             checkparams={"mytable_name": "fred", "myid_1": 7},
@@ -1212,9 +1093,13 @@ class UpdateFromCompileTest(
 
         checkparams = {"email_address_1": "e1", "id_1": 7, "name": "newname"}
 
-        cols = [addresses.c.id, addresses.c.user_id, addresses.c.email_address]
-
-        subq = select(cols).where(addresses.c.id == 7).alias()
+        subq = (
+            select(
+                addresses.c.id, addresses.c.user_id, addresses.c.email_address
+            )
+            .where(addresses.c.id == 7)
+            .alias()
+        )
         self.assert_compile(
             users.update()
             .values(name="newname")
diff --git a/tox.ini b/tox.ini
index ab5428f7246d7b820ed07c0a7202f2026479dd5c..aeef37b91e7c28e65d699a2f51b7873d94b38cb7 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -56,6 +56,7 @@ setenv=
     PYTHONPATH=
     PYTHONNOUSERSITE=1
     MEMUSAGE=--nomemory
+    SQLALCHEMY_WARN_20=true
     BASECOMMAND=python -m pytest --log-info=sqlalchemy.testing
 
     WORKERS={env:TOX_WORKERS:-n4  --max-worker-restart=5}