From 01c50c64e302c193733cef7fb146fbab8eaa44bd Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 3 Jan 2022 13:49:26 -0500 Subject: Remove all remaining removed_in_20 warnings slated for removal Finalize all remaining removed-in-2.0 changes so that we can begin doing pep-484 typing without old things getting in the way (we will also have to do public_factory). note there are a few "moved_in_20()" and "became_legacy_in_20()" warnings still in place. The SQLALCHEMY_WARN_20 variable is now removed. Also removed here are the legacy "in place mutators" for Select statements, and some keyword-only argument signatures in Core have been added. Also in the big change department, the ORM mapper() function is removed entirely; the Mapper class is otherwise unchanged, just the public-facing API function. Mappers are now always given a registry in which to participate, however the argument signature of Mapper is not changed. ideally "registry" would be the first positional argument. Fixes: #7257 Change-Id: Ic70c57b9f1cf7eb996338af5183b11bdeb3e1623 --- test/aaa_profiling/test_memusage.py | 4 +- test/aaa_profiling/test_misc.py | 2 +- test/aaa_profiling/test_orm.py | 6 +- test/base/test_except.py | 1 - test/dialect/mysql/test_deprecations.py | 19 - test/engine/test_deprecations.py | 33 -- test/ext/declarative/test_deprecations.py | 21 - test/ext/test_horizontal_shard.py | 22 +- test/orm/declarative/test_basic.py | 8 +- test/orm/inheritance/test_poly_linked_list.py | 62 +-- test/orm/test_bind.py | 6 +- test/orm/test_bundle.py | 6 +- test/orm/test_cascade.py | 72 +-- test/orm/test_composites.py | 8 +- test/orm/test_core_compilation.py | 9 - test/orm/test_deprecations.py | 623 ++++-------------------- test/orm/test_events.py | 38 +- test/orm/test_lazy_relations.py | 2 +- test/orm/test_load_on_fks.py | 31 ++ test/orm/test_mapper.py | 2 +- test/orm/test_naturalpks.py | 4 +- test/orm/test_query.py | 2 +- test/orm/test_session.py | 23 +- test/orm/test_transaction.py | 338 ++++--------- test/orm/test_versioning.py | 6 +- test/sql/test_case_statement.py | 17 +- test/sql/test_deprecations.py | 669 -------------------------- test/sql/test_roles.py | 14 +- test/sql/test_selectable.py | 11 + test/sql/test_types.py | 7 - 30 files changed, 334 insertions(+), 1732 deletions(-) (limited to 'test') diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py index 316e7d7d4..10ec4d307 100644 --- a/test/aaa_profiling/test_memusage.py +++ b/test/aaa_profiling/test_memusage.py @@ -1449,7 +1449,9 @@ class CycleTest(_fixtures.FixtureTest): @assert_cycles(4) def go(): - result = s.connection(mapper=User).execute(stmt) + result = s.connection(bind_arguments=dict(mapper=User)).execute( + stmt + ) while True: row = result.fetchone() if row is None: diff --git a/test/aaa_profiling/test_misc.py b/test/aaa_profiling/test_misc.py index c0508a3cf..13848a7bd 100644 --- a/test/aaa_profiling/test_misc.py +++ b/test/aaa_profiling/test_misc.py @@ -46,7 +46,7 @@ class EnumTest(fixtures.TestBase): @profiling.function_call_count() def test_create_enum_from_pep_435_w_expensive_members(self): - Enum(self.SomeEnum) + Enum(self.SomeEnum, omit_aliases=False) class CacheKeyTest(fixtures.TestBase): diff --git a/test/aaa_profiling/test_orm.py b/test/aaa_profiling/test_orm.py index 128a78714..cfc697d5e 100644 --- a/test/aaa_profiling/test_orm.py +++ b/test/aaa_profiling/test_orm.py @@ -94,7 +94,7 @@ class MergeTest(NoCache, fixtures.MappedTest): # down from 185 on this this is a small slice of a usually # bigger operation so using a small variance - sess2._legacy_transaction() # autobegin + sess2.connection() # autobegin @profiling.function_call_count(variance=0.20) def go1(): @@ -104,7 +104,7 @@ class MergeTest(NoCache, fixtures.MappedTest): # third call, merge object already present. almost no calls. - sess2._legacy_transaction() # autobegin + sess2.connection() # autobegin @profiling.function_call_count(variance=0.10, warmup=1) def go2(): @@ -124,7 +124,7 @@ class MergeTest(NoCache, fixtures.MappedTest): # using sqlite3 the C extension took it back up to approx. 1257 # (py2.6) - sess2._legacy_transaction() # autobegin + sess2.connection() # autobegin @profiling.function_call_count(variance=0.10) def go(): diff --git a/test/base/test_except.py b/test/base/test_except.py index e73160cd8..c7ef304b3 100644 --- a/test/base/test_except.py +++ b/test/base/test_except.py @@ -505,7 +505,6 @@ ALL_EXC = [ sa_exceptions.SADeprecationWarning, sa_exceptions.Base20DeprecationWarning, sa_exceptions.LegacyAPIWarning, - sa_exceptions.RemovedIn20Warning, sa_exceptions.MovedIn20Warning, sa_exceptions.SAWarning, ], diff --git a/test/dialect/mysql/test_deprecations.py b/test/dialect/mysql/test_deprecations.py index 32ec5e300..e66037d90 100644 --- a/test/dialect/mysql/test_deprecations.py +++ b/test/dialect/mysql/test_deprecations.py @@ -1,11 +1,8 @@ from sqlalchemy import select from sqlalchemy import table from sqlalchemy.dialects.mysql import base as mysql -from sqlalchemy.dialects.mysql import ENUM -from sqlalchemy.dialects.mysql import SET from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import expect_deprecated -from sqlalchemy.testing import expect_deprecated_20 from sqlalchemy.testing import fixtures @@ -22,19 +19,3 @@ class CompileTest(AssertsCompiledSQL, fixtures.TestBase): "dialect and will be removed in a future release" ): self.assert_compile(s, "SELECT FOO * FROM foo") - - -class DeprecateQuoting(fixtures.TestBase): - def test_enum_warning(self): - ENUM("a", "b") - with expect_deprecated_20( - "The 'quoting' parameter to :class:`.mysql.ENUM` is deprecated." - ): - ENUM("a", quoting="foo") - - def test_set_warning(self): - SET("a", "b") - with expect_deprecated_20( - "The 'quoting' parameter to :class:`.mysql.SET` is deprecated.*" - ): - SET("a", quoting="foo") diff --git a/test/engine/test_deprecations.py b/test/engine/test_deprecations.py index 454a6c629..8dc1f0f48 100644 --- a/test/engine/test_deprecations.py +++ b/test/engine/test_deprecations.py @@ -5,9 +5,7 @@ import sqlalchemy as tsa from sqlalchemy import create_engine from sqlalchemy import event from sqlalchemy import exc -from sqlalchemy import ForeignKey from sqlalchemy import insert -from sqlalchemy import inspect from sqlalchemy import Integer from sqlalchemy import MetaData from sqlalchemy import pool @@ -228,37 +226,6 @@ def select1(db): return str(select(1).compile(dialect=db.dialect)) -class DeprecatedReflectionTest(fixtures.TablesTest): - @classmethod - def define_tables(cls, metadata): - Table( - "user", - metadata, - Column("id", Integer, primary_key=True), - Column("name", String(50)), - ) - Table( - "address", - metadata, - Column("id", Integer, primary_key=True), - Column("user_id", ForeignKey("user.id")), - Column("email", String(50)), - ) - - def test_reflecttable(self): - inspector = inspect(testing.db) - metadata = MetaData() - - table = Table("user", metadata) - with testing.expect_deprecated_20( - r"The Inspector.reflecttable\(\) method is considered " - ): - res = inspector.reflecttable(table, None) - exp = inspector.reflect_table(table, None) - - eq_(res, exp) - - class EngineEventsTest(fixtures.TestBase): __requires__ = ("ad_hoc_engines",) __backend__ = True diff --git a/test/ext/declarative/test_deprecations.py b/test/ext/declarative/test_deprecations.py index 58ad2fced..a4192fddb 100644 --- a/test/ext/declarative/test_deprecations.py +++ b/test/ext/declarative/test_deprecations.py @@ -1,34 +1,13 @@ import sqlalchemy as sa from sqlalchemy import inspect from sqlalchemy.ext import declarative as legacy_decl -from sqlalchemy.ext.declarative import instrument_declarative -from sqlalchemy.orm import Mapper from sqlalchemy.testing import eq_ from sqlalchemy.testing import expect_deprecated_20 from sqlalchemy.testing import fixtures -from sqlalchemy.testing import is_ from sqlalchemy.testing import is_false from sqlalchemy.testing import is_true -class TestInstrumentDeclarative(fixtures.TestBase): - def test_ok(self): - class Foo: - __tablename__ = "foo" - id = sa.Column(sa.Integer, primary_key=True) - - meta = sa.MetaData() - reg = {} - with expect_deprecated_20( - "the instrument_declarative function is deprecated" - ): - instrument_declarative(Foo, reg, meta) - - mapper = sa.inspect(Foo) - is_true(isinstance(mapper, Mapper)) - is_(mapper.class_, Foo) - - class DeprecatedImportsTest(fixtures.TestBase): def _expect_warning(self, name): return expect_deprecated_20( diff --git a/test/ext/test_horizontal_shard.py b/test/ext/test_horizontal_shard.py index a59956062..7cc6a6f79 100644 --- a/test/ext/test_horizontal_shard.py +++ b/test/ext/test_horizontal_shard.py @@ -695,30 +695,22 @@ class DistinctEngineShardTest(ShardTest, fixtures.MappedTest): for i in range(1, 5): os.remove("shard%d_%s.db" % (i, provision.FOLLOWER_IDENT)) - @testing.combinations((True,), (False,)) - @testing.uses_deprecated("Using plain strings") - def test_plain_core_textual_lookup_w_shard(self, use_legacy_text): + def test_plain_core_textual_lookup_w_shard(self): sess = self._fixture_data() - if use_legacy_text: - stmt = "SELECT * FROM weather_locations" - else: - stmt = text("SELECT * FROM weather_locations") + stmt = text("SELECT * FROM weather_locations") eq_( - sess.execute(stmt, shard_id="asia").fetchall(), + sess.execute( + stmt, bind_arguments=dict(shard_id="asia") + ).fetchall(), [(1, "Asia", "Tokyo")], ) - @testing.combinations((True,), (False,)) - @testing.uses_deprecated("Using plain strings") - def test_plain_core_textual_lookup(self, use_legacy_text): + def test_plain_core_textual_lookup(self): sess = self._fixture_data() - if use_legacy_text: - stmt = "SELECT * FROM weather_locations WHERE id=1" - else: - stmt = text("SELECT * FROM weather_locations WHERE id=1") + stmt = text("SELECT * FROM weather_locations WHERE id=1") eq_( sess.execute(stmt).fetchall(), [(1, "Asia", "Tokyo")], diff --git a/test/orm/declarative/test_basic.py b/test/orm/declarative/test_basic.py index a5c1ba08a..87ef2e62f 100644 --- a/test/orm/declarative/test_basic.py +++ b/test/orm/declarative/test_basic.py @@ -25,7 +25,7 @@ from sqlalchemy.orm import deferred from sqlalchemy.orm import descriptor_props from sqlalchemy.orm import exc as orm_exc from sqlalchemy.orm import joinedload -from sqlalchemy.orm import mapper +from sqlalchemy.orm import Mapper from sqlalchemy.orm import registry from sqlalchemy.orm import relationship from sqlalchemy.orm import Session @@ -1489,7 +1489,7 @@ class DeclarativeTest(DeclarativeTestBase): def test_custom_mapper_attribute(self): def mymapper(cls, tbl, **kwargs): - m = sa.orm.mapper(cls, tbl, **kwargs) + m = sa.orm.Mapper(cls, tbl, **kwargs) m.CHECK = True return m @@ -1504,7 +1504,7 @@ class DeclarativeTest(DeclarativeTestBase): def test_custom_mapper_argument(self): def mymapper(cls, tbl, **kwargs): - m = sa.orm.mapper(cls, tbl, **kwargs) + m = sa.orm.Mapper(cls, tbl, **kwargs) m.CHECK = True return m @@ -2214,7 +2214,7 @@ class DeclarativeTest(DeclarativeTestBase): canary = mock.Mock() - @event.listens_for(mapper, "instrument_class") + @event.listens_for(Mapper, "instrument_class") def instrument_class(mp, cls): canary.instrument_class(mp, cls) diff --git a/test/orm/inheritance/test_poly_linked_list.py b/test/orm/inheritance/test_poly_linked_list.py index a501e027a..9e973cc74 100644 --- a/test/orm/inheritance/test_poly_linked_list.py +++ b/test/orm/inheritance/test_poly_linked_list.py @@ -1,9 +1,7 @@ from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy import String -from sqlalchemy import testing from sqlalchemy.orm import backref -from sqlalchemy.orm import clear_mappers from sqlalchemy.orm import configure_mappers from sqlalchemy.orm import relationship from sqlalchemy.testing import fixtures @@ -54,24 +52,13 @@ class PolymorphicCircularTest(fixtures.MappedTest): @classmethod def setup_mappers(cls): - global Table1, Table1B, Table2, Table3, Data table1, table2, table3, data = cls.tables( "table1", "table2", "table3", "data" ) - # join = polymorphic_union( - # { - # 'table3' : table1.join(table3), - # 'table2' : table1.join(table2), - # 'table1' : table1.select(table1.c.type.in_(['table1', 'table1b'])), - # }, None, 'pjoin') - - with testing.expect_deprecated_20( - r"The Join.alias\(\) method is considered legacy" - ): - join = table1.outerjoin(table2).outerjoin(table3).alias("pjoin") - # join = None - - class Table1: + + Base = cls.Basic + + class Table1(Base): def __init__(self, name, data=None): self.name = name if data is not None: @@ -94,7 +81,7 @@ class PolymorphicCircularTest(fixtures.MappedTest): class Table3(Table1): pass - class Data: + class Data(Base): def __init__(self, data): self.data = data @@ -105,35 +92,6 @@ class PolymorphicCircularTest(fixtures.MappedTest): repr(str(self.data)), ) - try: - # this is how the mapping used to work. ensure that this raises an - # error now - table1_mapper = cls.mapper_registry.map_imperatively( - Table1, - table1, - select_table=join, - polymorphic_on=table1.c.type, - polymorphic_identity="table1", - properties={ - "nxt": relationship( - Table1, - backref=backref( - "prev", foreignkey=join.c.id, uselist=False - ), - uselist=False, - primaryjoin=join.c.id == join.c.related_id, - ), - "data": relationship( - cls.mapper_registry.map_imperatively(Data, data) - ), - }, - ) - configure_mappers() - assert False - except Exception: - assert True - clear_mappers() - # currently, the "eager" relationships degrade to lazy relationships # due to the polymorphic load. # the "nxt" relationship used to have a "lazy='joined'" on it, but the @@ -190,12 +148,17 @@ class PolymorphicCircularTest(fixtures.MappedTest): ), table1_mapper.primary_key def test_one(self): + Table1, Table2 = self.classes("Table1", "Table2") self._testlist([Table1, Table2, Table1, Table2]) def test_two(self): + Table3 = self.classes.Table3 self._testlist([Table3]) def test_three(self): + Table1, Table1B, Table2, Table3 = self.classes( + "Table1", "Table1B", "Table2", "Table3" + ) self._testlist( [ Table2, @@ -211,6 +174,9 @@ class PolymorphicCircularTest(fixtures.MappedTest): ) def test_four(self): + Table1, Table1B, Table2, Table3, Data = self.classes( + "Table1", "Table1B", "Table2", "Table3", "Data" + ) self._testlist( [ Table2("t2", [Data("data1"), Data("data2")]), @@ -221,6 +187,8 @@ class PolymorphicCircularTest(fixtures.MappedTest): ) def _testlist(self, classes): + Table1 = self.classes.Table1 + sess = fixture_session() # create objects in a linked list diff --git a/test/orm/test_bind.py b/test/orm/test_bind.py index 1d5af5064..ec62430ad 100644 --- a/test/orm/test_bind.py +++ b/test/orm/test_bind.py @@ -286,7 +286,7 @@ class BindIntegrationTest(_fixtures.FixtureTest): sess.bind_mapper(Address, e2) engine = {"e1": e1, "e2": e2, "e3": e3}[expected] - conn = sess.connection(**testcase) + conn = sess.connection(bind_arguments=testcase) is_(conn.engine, engine) sess.close() @@ -355,7 +355,7 @@ class BindIntegrationTest(_fixtures.FixtureTest): canary.get_bind(**kw) return Session.get_bind(self, **kw) - sess = GetBindSession(e3, future=True) + sess = GetBindSession(e3) sess.bind_mapper(User, e1) sess.bind_mapper(Address, e2) @@ -422,7 +422,7 @@ class BindIntegrationTest(_fixtures.FixtureTest): c = testing.db.connect() sess = Session(bind=c) sess.begin() - transaction = sess._legacy_transaction() + transaction = sess.get_transaction() u = User(name="u1") sess.add(u) sess.flush() diff --git a/test/orm/test_bundle.py b/test/orm/test_bundle.py index 92c4c19c2..6d613091d 100644 --- a/test/orm/test_bundle.py +++ b/test/orm/test_bundle.py @@ -318,11 +318,7 @@ class BundleTest(fixtures.MappedTest, AssertsCompiledSQL): stmt = select(b1).filter(b1.c.d1.between("d3d1", "d5d1")) - with testing.expect_deprecated_20( - "The Bundle.single_entity flag has no effect when " - "using 2.0 style execution." - ): - rows = sess.execute(stmt).all() + rows = sess.execute(stmt).all() eq_( rows, [(("d3d1", "d3d2"),), (("d4d1", "d4d2"),), (("d5d1", "d5d2"),)], diff --git a/test/orm/test_cascade.py b/test/orm/test_cascade.py index 51ed50255..5a74d6ad9 100644 --- a/test/orm/test_cascade.py +++ b/test/orm/test_cascade.py @@ -1076,8 +1076,6 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): m2o_cascade=True, o2m=False, m2o=False, - o2m_cascade_backrefs=True, - m2o_cascade_backrefs=True, ): Address, addresses, users, User = ( @@ -1092,12 +1090,10 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): addresses_rel = { "addresses": relationship( Address, - cascade_backrefs=o2m_cascade_backrefs, cascade=o2m_cascade and "save-update" or "", backref=backref( "user", cascade=m2o_cascade and "save-update" or "", - cascade_backrefs=m2o_cascade_backrefs, ), ) } @@ -1107,7 +1103,6 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): "addresses": relationship( Address, cascade=o2m_cascade and "save-update" or "", - cascade_backrefs=o2m_cascade_backrefs, ) } user_rel = {} @@ -1116,7 +1111,6 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): "user": relationship( User, cascade=m2o_cascade and "save-update" or "", - cascade_backrefs=m2o_cascade_backrefs, ) } addresses_rel = {} @@ -1137,8 +1131,6 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): bkd_cascade=True, fwd=False, bkd=False, - fwd_cascade_backrefs=True, - bkd_cascade_backrefs=True, ): keywords, items, item_keywords, Keyword, Item = ( @@ -1155,12 +1147,10 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): "keywords": relationship( Keyword, secondary=item_keywords, - cascade_backrefs=fwd_cascade_backrefs, cascade=fwd_cascade and "save-update" or "", backref=backref( "items", cascade=bkd_cascade and "save-update" or "", - cascade_backrefs=bkd_cascade_backrefs, ), ) } @@ -1171,7 +1161,6 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): Keyword, secondary=item_keywords, cascade=fwd_cascade and "save-update" or "", - cascade_backrefs=fwd_cascade_backrefs, ) } items_rel = {} @@ -1181,7 +1170,6 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): Item, secondary=item_keywords, cascade=bkd_cascade and "save-update" or "", - cascade_backrefs=bkd_cascade_backrefs, ) } keywords_rel = {} @@ -1404,11 +1392,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.flush() a1 = Address(email_address="a1") - with testing.expect_deprecated( - '"Address" object is being merged into a Session along ' - 'the backref cascade path for relationship "User.addresses"' - ): - a1.user = u1 + a1.user = u1 sess.add(a1) sess.expunge(u1) assert u1 not in sess @@ -1469,11 +1453,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest): sess.flush() a1 = Address(email_address="a1") - with testing.expect_deprecated( - '"Address" object is being merged into a Session along the ' - 'backref cascade path for relationship "User.addresses"' - ): - a1.user = u1 + a1.user = u1 sess.add(a1) sess.expunge(u1) assert u1 not in sess @@ -2761,20 +2741,14 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): cls.mapper_registry.map_imperatively( User, users, - properties={ - "addresses": relationship( - Address, backref="user", cascade_backrefs=False - ) - }, + properties={"addresses": relationship(Address, backref="user")}, ) cls.mapper_registry.map_imperatively( Dingaling, dingalings, properties={ - "address": relationship( - Address, backref="dingalings", cascade_backrefs=False - ) + "address": relationship(Address, backref="dingalings") }, ) @@ -2805,7 +2779,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): assert a1 not in sess - def test_o2m_flag_on_backref(self): + def test_o2m_on_backref_no_cascade(self): Dingaling, Address = self.classes.Dingaling, self.classes.Address sess = fixture_session() @@ -2814,15 +2788,9 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): sess.add(a1) d1 = Dingaling() - with testing.expect_deprecated( - '"Dingaling" object is being merged into a Session along the ' - 'backref cascade path for relationship "Address.dingalings"' - ): - d1.address = a1 + d1.address = a1 assert d1 in a1.dingalings - assert d1 in sess - - sess.commit() + assert d1 not in sess def test_m2o_basic(self): Dingaling, Address = self.classes.Dingaling, self.classes.Address @@ -2836,7 +2804,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): a1.dingalings.append(d1) assert a1 not in sess - def test_m2o_flag_on_backref(self): + def test_m2o_on_backref_no_cascade(self): User, Address = self.classes.User, self.classes.Address sess = fixture_session() @@ -2845,14 +2813,10 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest): sess.add(a1) u1 = User(name="u1") - with testing.expect_deprecated( - '"User" object is being merged into a Session along the backref ' - 'cascade path for relationship "Address.user"' - ): - u1.addresses.append(a1) - assert u1 in sess + u1.addresses.append(a1) + assert u1 not in sess - def test_m2o_commit_warns(self): + def test_m2o_commit_no_cascade(self): Dingaling, Address = self.classes.Dingaling, self.classes.Address sess = fixture_session() @@ -3844,7 +3808,9 @@ class O2MConflictTest(fixtures.MappedTest): "child": relationship( Child, uselist=False, - backref=backref("parent", cascade_backrefs=False), + backref=backref( + "parent", + ), ) }, ) @@ -3910,7 +3876,7 @@ class O2MConflictTest(fixtures.MappedTest): Child, uselist=False, cascade="all, delete, delete-orphan", - backref=backref("parent", cascade_backrefs=False), + backref=backref("parent"), ) }, ) @@ -3937,7 +3903,6 @@ class O2MConflictTest(fixtures.MappedTest): single_parent=True, backref=backref("child", uselist=False), cascade="all,delete,delete-orphan", - cascade_backrefs=False, ) }, ) @@ -3963,7 +3928,6 @@ class O2MConflictTest(fixtures.MappedTest): single_parent=True, backref=backref("child", uselist=True), cascade="all,delete,delete-orphan", - cascade_backrefs=False, ) }, ) @@ -4499,7 +4463,6 @@ class CollectionCascadesNoBackrefTest(fixtures.TestBase): "B", backref="a", collection_class=collection_class, - cascade_backrefs=False, ) @registry.mapped @@ -4522,13 +4485,12 @@ class CollectionCascadesNoBackrefTest(fixtures.TestBase): (attribute_mapped_collection("key"), "update_kw"), argnames="collection_class,methname", ) - @testing.combinations((True,), (False,), argnames="future") def test_cascades_on_collection( - self, cascade_fixture, collection_class, methname, future + self, cascade_fixture, collection_class, methname ): A, B = cascade_fixture(collection_class) - s = Session(future=future) + s = Session() a1 = A() s.add(a1) diff --git a/test/orm/test_composites.py b/test/orm/test_composites.py index 67ffae75d..19e090e0e 100644 --- a/test/orm/test_composites.py +++ b/test/orm/test_composites.py @@ -90,14 +90,14 @@ class PointTest(fixtures.MappedTest, testing.AssertsCompiledSQL): }, ) - def _fixture(self, future=False): + def _fixture(self): Graph, Edge, Point = ( self.classes.Graph, self.classes.Edge, self.classes.Point, ) - sess = Session(testing.db, future=future) + sess = Session(testing.db) g = Graph( id=1, edges=[ @@ -231,7 +231,7 @@ class PointTest(fixtures.MappedTest, testing.AssertsCompiledSQL): def test_bulk_update_sql(self): Edge, Point = (self.classes.Edge, self.classes.Point) - sess = self._fixture(future=True) + sess = self._fixture() e1 = sess.execute( select(Edge).filter(Edge.start == Point(14, 5)) @@ -256,7 +256,7 @@ class PointTest(fixtures.MappedTest, testing.AssertsCompiledSQL): def test_bulk_update_evaluate(self): Edge, Point = (self.classes.Edge, self.classes.Point) - sess = self._fixture(future=True) + sess = self._fixture() e1 = sess.execute( select(Edge).filter(Edge.start == Point(14, 5)) diff --git a/test/orm/test_core_compilation.py b/test/orm/test_core_compilation.py index 28f42797e..2b0c570c4 100644 --- a/test/orm/test_core_compilation.py +++ b/test/orm/test_core_compilation.py @@ -35,7 +35,6 @@ from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ -from sqlalchemy.testing.assertions import expect_raises_message from sqlalchemy.testing.fixtures import fixture_session from sqlalchemy.testing.util import resolve_lambda from sqlalchemy.util.langhelpers import hybridproperty @@ -232,14 +231,6 @@ class ColumnsClauseFromsTest(QueryTest, AssertsCompiledSQL): ) eq_(len(froms), 1) - def test_with_only_columns_unknown_kw(self): - User, Address = self.classes("User", "Address") - - stmt = select(User.id) - - with expect_raises_message(TypeError, "unknown parameters: foo"): - stmt.with_only_columns(User.id, foo="bar") - @testing.combinations((True,), (False,)) def test_replace_into_select_from_maintains_existing(self, use_flag): User, Address = self.classes("User", "Address") diff --git a/test/orm/test_deprecations.py b/test/orm/test_deprecations.py index 64db9a893..a567534c3 100644 --- a/test/orm/test_deprecations.py +++ b/test/orm/test_deprecations.py @@ -1,4 +1,3 @@ -from contextlib import nullcontext from unittest.mock import call from unittest.mock import Mock @@ -16,12 +15,10 @@ from sqlalchemy import select from sqlalchemy import String from sqlalchemy import testing from sqlalchemy import text -from sqlalchemy import true from sqlalchemy.engine import default from sqlalchemy.engine import result_tuple from sqlalchemy.orm import aliased from sqlalchemy.orm import attributes -from sqlalchemy.orm import backref from sqlalchemy.orm import clear_mappers from sqlalchemy.orm import collections from sqlalchemy.orm import column_property @@ -31,12 +28,9 @@ from sqlalchemy.orm import contains_eager from sqlalchemy.orm import defaultload from sqlalchemy.orm import defer from sqlalchemy.orm import deferred -from sqlalchemy.orm import eagerload from sqlalchemy.orm import foreign from sqlalchemy.orm import instrumentation from sqlalchemy.orm import joinedload -from sqlalchemy.orm import mapper -from sqlalchemy.orm import relation from sqlalchemy.orm import relationship from sqlalchemy.orm import scoped_session from sqlalchemy.orm import Session @@ -46,7 +40,6 @@ from sqlalchemy.orm import synonym from sqlalchemy.orm import undefer from sqlalchemy.orm import with_parent from sqlalchemy.orm import with_polymorphic -from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.collections import collection from sqlalchemy.orm.util import polymorphic_union from sqlalchemy.testing import assert_raises_message @@ -67,13 +60,11 @@ from .inheritance import _poly_fixtures from .inheritance._poly_fixtures import Manager from .inheritance._poly_fixtures import Person from .test_deferred import InheritanceTest as _deferred_InheritanceTest -from .test_dynamic import _DynamicFixture from .test_events import _RemoveListeners from .test_options import PathTest as OptionsPathTest from .test_options import PathTest from .test_options import QueryTest as OptionsQueryTest from .test_query import QueryTest -from .test_transaction import _LocalFixture from ..sql.test_compare import CacheKeyFixture if True: @@ -413,35 +404,6 @@ class DeprecatedQueryTest(_fixtures.FixtureTest, AssertsCompiledSQL): "subquery object." ) - def test_deprecated_negative_slices(self): - User = self.classes.User - - sess = fixture_session() - q = sess.query(User).order_by(User.id) - - with testing.expect_deprecated( - "Support for negative indexes for SQL index / slice operators" - ): - eq_(q[-5:-2], [User(id=7), User(id=8)]) - - with testing.expect_deprecated( - "Support for negative indexes for SQL index / slice operators" - ): - eq_(q[-1], User(id=10)) - - with testing.expect_deprecated( - "Support for negative indexes for SQL index / slice operators" - ): - eq_(q[-2], User(id=9)) - - with testing.expect_deprecated( - "Support for negative indexes for SQL index / slice operators" - ): - eq_(q[:-2], [User(id=7), User(id=8)]) - - # this doesn't evaluate anything because it's a net-negative - eq_(q[-2:-5], []) - def test_deprecated_select_coercion_join_target(self): User = self.classes.User addresses = self.tables.addresses @@ -460,44 +422,6 @@ class DeprecatedQueryTest(_fixtures.FixtureTest, AssertsCompiledSQL): "ON users.id = anon_1.user_id", ) - def test_deprecated_negative_slices_compile(self): - User = self.classes.User - - sess = fixture_session() - q = sess.query(User).order_by(User.id) - - with testing.expect_deprecated( - "Support for negative indexes for SQL index / slice operators" - ): - self.assert_sql( - testing.db, - lambda: q[-5:-2], - [ - ( - "SELECT users.id AS users_id, users.name " - "AS users_name " - "FROM users ORDER BY users.id", - {}, - ) - ], - ) - - with testing.expect_deprecated( - "Support for negative indexes for SQL index / slice operators" - ): - self.assert_sql( - testing.db, - lambda: q[-5:], - [ - ( - "SELECT users.id AS users_id, users.name " - "AS users_name " - "FROM users ORDER BY users.id", - {}, - ) - ], - ) - def test_invalid_column(self): User = self.classes.User @@ -629,129 +553,91 @@ class LazyLoadOptSpecificityTest(fixtures.DeclarativeMappedTest): self.assert_sql_count(testing.db, go, expected) -class DynamicTest(_DynamicFixture, _fixtures.FixtureTest): - def test_negative_slice_access_raises(self): - User, Address = self._user_address_fixture() - sess = fixture_session() - u1 = sess.get(User, 8) +class DeprecatedInhTest(_poly_fixtures._Polymorphic): + def test_with_polymorphic(self): + Person = _poly_fixtures.Person + Engineer = _poly_fixtures.Engineer - with testing.expect_deprecated_20( - "Support for negative indexes for SQL index / slice" - ): - eq_(u1.addresses[-1], Address(id=4)) + with DeprecatedQueryTest._expect_implicit_subquery(): + p_poly = with_polymorphic(Person, [Engineer], select(Person)) - with testing.expect_deprecated_20( - "Support for negative indexes for SQL index / slice" - ): - eq_(u1.addresses[-5:-2], [Address(id=2)]) + is_true( + sa.inspect(p_poly).selectable.compare(select(Person).subquery()) + ) - with testing.expect_deprecated_20( - "Support for negative indexes for SQL index / slice" - ): - eq_(u1.addresses[-2], Address(id=3)) - with testing.expect_deprecated_20( - "Support for negative indexes for SQL index / slice" - ): - eq_(u1.addresses[:-2], [Address(id=2)]) +class DeprecatedMapperTest( + fixtures.RemovesEvents, _fixtures.FixtureTest, AssertsCompiledSQL +): + __dialect__ = "default" + def test_listen_on_mapper_mapper_event_fn(self, registry): + from sqlalchemy.orm import mapper -class SessionTest(fixtures.RemovesEvents, _LocalFixture): - def test_transaction_attr(self): - s1 = Session(testing.db) + m1 = Mock() - with testing.expect_deprecated_20( - "The Session.transaction attribute is considered legacy as " - "of the 1.x series" + with expect_deprecated( + r"The `sqlalchemy.orm.mapper\(\)` symbol is deprecated and " + "will be removed" ): - s1.transaction - def test_textual_execute(self, connection): - """test that Session.execute() converts to text()""" + @event.listens_for(mapper, "before_configured") + def go(): + m1() - users = self.tables.users + @registry.mapped + class MyClass: + __tablename__ = "t1" + id = Column(Integer, primary_key=True) - with Session(bind=connection) as sess: - sess.execute(users.insert(), dict(id=7, name="jack")) + registry.configure() + eq_(m1.mock_calls, [call()]) - with testing.expect_deprecated_20( - "Using plain strings to indicate SQL statements " - "without using the text" - ): - # use :bindparam style - eq_( - sess.execute( - "select * from users where id=:id", {"id": 7} - ).fetchall(), - [(7, "jack")], - ) + def test_listen_on_mapper_instrumentation_event_fn(self, registry): + from sqlalchemy.orm import mapper - with testing.expect_deprecated_20( - "Using plain strings to indicate SQL statements " - "without using the text" - ): - # use :bindparam style - eq_( - sess.scalar( - "select id from users where id=:id", {"id": 7} - ), - 7, - ) + m1 = Mock() - def test_session_str(self): - s1 = Session(testing.db) - str(s1) + with expect_deprecated( + r"The `sqlalchemy.orm.mapper\(\)` symbol is deprecated and " + "will be removed" + ): - @testing.combinations( - {"mapper": None}, - {"clause": None}, - {"bind_arguments": {"mapper": None}, "clause": None}, - {"bind_arguments": {}, "clause": None}, - ) - def test_bind_kwarg_deprecated(self, kw): - s1 = Session(testing.db) - - for meth in s1.execute, s1.scalar: - m1 = mock.Mock(side_effect=s1.get_bind) - with mock.patch.object(s1, "get_bind", m1): - expr = text("select 1") - - with testing.expect_deprecated_20( - r"Passing bind arguments to Session.execute\(\) as " - "keyword " - "arguments is deprecated and will be removed SQLAlchemy " - "2.0" - ): - meth(expr, **kw) - - bind_arguments = kw.pop("bind_arguments", None) - if bind_arguments: - bind_arguments.update(kw) - - if "clause" not in kw: - bind_arguments["clause"] = expr - eq_(m1.mock_calls, [call(**bind_arguments)]) - else: - if "clause" not in kw: - kw["clause"] = expr - eq_(m1.mock_calls, [call(**kw)]) + @event.listens_for(mapper, "init") + def go(target, args, kwargs): + m1(target, args, kwargs) + @registry.mapped + class MyClass: + __tablename__ = "t1" + id = Column(Integer, primary_key=True) -class DeprecatedInhTest(_poly_fixtures._Polymorphic): - def test_with_polymorphic(self): - Person = _poly_fixtures.Person - Engineer = _poly_fixtures.Engineer + mc = MyClass(id=5) + eq_(m1.mock_calls, [call(mc, (), {"id": 5})]) - with DeprecatedQueryTest._expect_implicit_subquery(): - p_poly = with_polymorphic(Person, [Engineer], select(Person)) + def test_we_couldnt_remove_mapper_yet(self): + """test that the mapper() function is present but raises an + informative error when used. - is_true( - sa.inspect(p_poly).selectable.compare(select(Person).subquery()) - ) + The function itself was to be removed as of 2.0, however we forgot + to mark deprecated the use of the function as an event target, + so it needs to stay around for another cycle at least. + """ -class DeprecatedMapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): - __dialect__ = "default" + class MyClass: + pass + + t1 = Table("t1", MetaData(), Column("id", Integer, primary_key=True)) + + from sqlalchemy.orm import mapper + + with assertions.expect_raises_message( + sa_exc.InvalidRequestError, + r"The 'sqlalchemy.orm.mapper\(\)' function is removed as of " + "SQLAlchemy 2.0.", + ): + mapper(MyClass, t1) def test_deferred_scalar_loader_name_change(self): class Foo: @@ -1392,7 +1278,6 @@ class ViewonlyFlagWarningTest(fixtures.MappedTest): ("passive_updates", False), ("enable_typechecks", False), ("active_history", True), - ("cascade_backrefs", False), ) def test_viewonly_warning(self, flag, value): Order = self.classes.Order @@ -1504,7 +1389,7 @@ class NonPrimaryMapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): non_primary=True, ) - def test_illegal_non_primary_legacy(self): + def test_illegal_non_primary_legacy(self, registry): users, Address, addresses, User = ( self.tables.users, self.classes.Address, @@ -1512,18 +1397,12 @@ class NonPrimaryMapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): self.classes.User, ) - with testing.expect_deprecated( - "Calling the mapper.* function directly outside of a declarative " - ): - mapper(User, users) - with testing.expect_deprecated( - "Calling the mapper.* function directly outside of a declarative " - ): - mapper(Address, addresses) + registry.map_imperatively(User, users) + registry.map_imperatively(Address, addresses) with testing.expect_deprecated( "The mapper.non_primary parameter is deprecated" ): - m = mapper( # noqa F841 + m = registry.map_imperatively( # noqa F841 User, users, non_primary=True, @@ -1536,22 +1415,19 @@ class NonPrimaryMapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): configure_mappers, ) - def test_illegal_non_primary_2_legacy(self): + def test_illegal_non_primary_2_legacy(self, registry): User, users = self.classes.User, self.tables.users - with testing.expect_deprecated( - "The mapper.non_primary parameter is deprecated" - ): - assert_raises_message( - sa.exc.InvalidRequestError, - "Configure a primary mapper first", - mapper, - User, - users, - non_primary=True, - ) + assert_raises_message( + sa.exc.InvalidRequestError, + "Configure a primary mapper first", + registry.map_imperatively, + User, + users, + non_primary=True, + ) - def test_illegal_non_primary_3_legacy(self): + def test_illegal_non_primary_3_legacy(self, registry): users, addresses = self.tables.users, self.tables.addresses class Base: @@ -1560,21 +1436,16 @@ class NonPrimaryMapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): class Sub(Base): pass - with testing.expect_deprecated( - "Calling the mapper.* function directly outside of a declarative " - ): - mapper(Base, users) - with testing.expect_deprecated( - "The mapper.non_primary parameter is deprecated", - ): - assert_raises_message( - sa.exc.InvalidRequestError, - "Configure a primary mapper first", - mapper, - Sub, - addresses, - non_primary=True, - ) + registry.map_imperatively(Base, users) + + assert_raises_message( + sa.exc.InvalidRequestError, + "Configure a primary mapper first", + registry.map_imperatively, + Sub, + addresses, + non_primary=True, + ) class InstancesTest(QueryTest, AssertsCompiledSQL): @@ -1776,78 +1647,6 @@ class InstancesTest(QueryTest, AssertsCompiledSQL): self.assert_sql_count(testing.db, go, 1) -class TestDeprecation20(QueryTest): - def test_relation(self): - User = self.classes.User - with testing.expect_deprecated_20(".*relationship"): - relation(User.addresses) - - def test_eagerloading(self): - User = self.classes.User - with testing.expect_deprecated_20(".*joinedload"): - eagerload(User.addresses) - - -class DistinctOrderByImplicitTest(QueryTest, AssertsCompiledSQL): - __dialect__ = "default" - - def test_columns_augmented_roundtrip_three(self): - User, Address = self.classes.User, self.classes.Address - - sess = fixture_session() - - q = ( - sess.query(User.id, User.name.label("foo"), Address.id) - .join(Address, true()) - .filter(User.name == "jack") - .filter(User.id + Address.user_id > 0) - .distinct() - .order_by(User.id, User.name, Address.email_address) - ) - - # even though columns are added, they aren't in the result - with testing.expect_deprecated( - "ORDER BY columns added implicitly due to " - ): - eq_( - q.all(), - [ - (7, "jack", 3), - (7, "jack", 4), - (7, "jack", 2), - (7, "jack", 5), - (7, "jack", 1), - ], - ) - for row in q: - eq_(row._mapping.keys(), ["id", "foo", "id"]) - - def test_columns_augmented_sql_one(self): - User, Address = self.classes.User, self.classes.Address - - sess = fixture_session() - - q = ( - sess.query(User.id, User.name.label("foo"), Address.id) - .distinct() - .order_by(User.id, User.name, Address.email_address) - ) - - # Address.email_address is added because of DISTINCT, - # however User.id, User.name are not b.c. they're already there, - # even though User.name is labeled - with testing.expect_deprecated( - "ORDER BY columns added implicitly due to " - ): - self.assert_compile( - q, - "SELECT DISTINCT users.id AS users_id, users.name AS foo, " - "addresses.id AS addresses_id, addresses.email_address AS " - "addresses_email_address FROM users, addresses " - "ORDER BY users.id, users.name, addresses.email_address", - ) - - class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): run_inserts = None @@ -2804,252 +2603,6 @@ class ParentTest(QueryTest, AssertsCompiledSQL): ) -class CollectionCascadesDespiteBackrefTest(fixtures.TestBase): - """test old cascade_backrefs behavior - - see test/orm/test_cascade.py::class CollectionCascadesNoBackrefTest - for the future version - - """ - - @testing.fixture - def cascade_fixture(self, registry): - def go(collection_class): - @registry.mapped - class A: - __tablename__ = "a" - - id = Column(Integer, primary_key=True) - bs = relationship( - "B", backref="a", collection_class=collection_class - ) - - @registry.mapped - class B: - __tablename__ = "b_" - id = Column(Integer, primary_key=True) - a_id = Column(ForeignKey("a.id")) - key = Column(String) - - return A, B - - yield go - - @testing.combinations( - (set, "add"), - (list, "append"), - (attribute_mapped_collection("key"), "__setitem__"), - (attribute_mapped_collection("key"), "setdefault"), - (attribute_mapped_collection("key"), "update_dict"), - (attribute_mapped_collection("key"), "update_kw"), - argnames="collection_class,methname", - ) - @testing.combinations((True,), (False,), argnames="future") - def test_cascades_on_collection( - self, cascade_fixture, collection_class, methname, future - ): - A, B = cascade_fixture(collection_class) - - s = Session(future=future) - - a1 = A() - s.add(a1) - - b1 = B(key="b1") - b2 = B(key="b2") - b3 = B(key="b3") - - if future: - dep_ctx = nullcontext - else: - - def dep_ctx(): - return assertions.expect_deprecated_20( - '"B" object is being merged into a Session along the ' - 'backref cascade path for relationship "A.bs"' - ) - - with dep_ctx(): - b1.a = a1 - with dep_ctx(): - b3.a = a1 - - if future: - assert b1 not in s - assert b3 not in s - else: - assert b1 in s - assert b3 in s - - if methname == "__setitem__": - meth = getattr(a1.bs, methname) - meth(b1.key, b1) - meth(b2.key, b2) - elif methname == "setdefault": - meth = getattr(a1.bs, methname) - meth(b1.key, b1) - meth(b2.key, b2) - elif methname == "update_dict" and isinstance(a1.bs, dict): - a1.bs.update({b1.key: b1, b2.key: b2}) - elif methname == "update_kw" and isinstance(a1.bs, dict): - a1.bs.update(b1=b1, b2=b2) - else: - meth = getattr(a1.bs, methname) - meth(b1) - meth(b2) - - assert b1 in s - assert b2 in s - - # future version: - if future: - assert b3 not in s # the event never triggers from reverse - else: - # old behavior - assert b3 in s - - -class LoadOnFKsTest(fixtures.DeclarativeMappedTest): - @classmethod - def setup_classes(cls): - Base = cls.DeclarativeBasic - - class Parent(Base): - __tablename__ = "parent" - __table_args__ = {"mysql_engine": "InnoDB"} - - id = Column( - Integer, primary_key=True, test_needs_autoincrement=True - ) - - class Child(Base): - __tablename__ = "child" - __table_args__ = {"mysql_engine": "InnoDB"} - - id = Column( - Integer, primary_key=True, test_needs_autoincrement=True - ) - parent_id = Column(Integer, ForeignKey("parent.id")) - - parent = relationship(Parent, backref=backref("children")) - - @testing.fixture - def parent_fixture(self, connection): - Parent, Child = self.classes("Parent", "Child") - - sess = fixture_session(bind=connection, autoflush=False) - p1 = Parent() - p2 = Parent() - c1, c2 = Child(), Child() - c1.parent = p1 - sess.add_all([p1, p2]) - assert c1 in sess - - yield sess, p1, p2, c1, c2 - - sess.close() - - def test_enable_rel_loading_on_persistent_allows_backref_event( - self, parent_fixture - ): - sess, p1, p2, c1, c2 = parent_fixture - Parent, Child = self.classes("Parent", "Child") - - c3 = Child() - sess.enable_relationship_loading(c3) - c3.parent_id = p1.id - with assertions.expect_deprecated_20( - '"Child" object is being merged into a Session along the ' - 'backref cascade path for relationship "Parent.children"' - ): - c3.parent = p1 - - # backref fired off when c3.parent was set, - # because the "old" value was None - # change as of [ticket:3708] - assert c3 in p1.children - - def test_enable_rel_loading_allows_backref_event(self, parent_fixture): - sess, p1, p2, c1, c2 = parent_fixture - Parent, Child = self.classes("Parent", "Child") - - c3 = Child() - sess.enable_relationship_loading(c3) - c3.parent_id = p1.id - - with assertions.expect_deprecated_20( - '"Child" object is being merged into a Session along the ' - 'backref cascade path for relationship "Parent.children"' - ): - c3.parent = p1 - - # backref fired off when c3.parent was set, - # because the "old" value was None - # change as of [ticket:3708] - assert c3 in p1.children - - -class LazyTest(_fixtures.FixtureTest): - run_inserts = "once" - run_deletes = None - - def test_backrefs_dont_lazyload(self): - users, Address, addresses, User = ( - self.tables.users, - self.classes.Address, - self.tables.addresses, - self.classes.User, - ) - - self.mapper_registry.map_imperatively( - User, - users, - properties={"addresses": relationship(Address, backref="user")}, - ) - self.mapper_registry.map_imperatively(Address, addresses) - sess = fixture_session(autoflush=False) - ad = sess.query(Address).filter_by(id=1).one() - assert ad.user.id == 7 - - def go(): - ad.user = None - assert ad.user is None - - self.assert_sql_count(testing.db, go, 0) - - u1 = sess.query(User).filter_by(id=7).one() - - def go(): - assert ad not in u1.addresses - - self.assert_sql_count(testing.db, go, 1) - - sess.expire(u1, ["addresses"]) - - def go(): - assert ad in u1.addresses - - self.assert_sql_count(testing.db, go, 1) - - sess.expire(u1, ["addresses"]) - ad2 = Address() - - def go(): - with assertions.expect_deprecated_20( - ".* object is being merged into a Session along the " - "backref cascade path for relationship " - ): - ad2.user = u1 - assert ad2.user is u1 - - self.assert_sql_count(testing.db, go, 0) - - def go(): - assert ad2 in u1.addresses - - self.assert_sql_count(testing.db, go, 1) - - class MergeResultTest(_fixtures.FixtureTest): run_setup_mappers = "once" run_inserts = "once" diff --git a/test/orm/test_events.py b/test/orm/test_events.py index 3437d7942..92ef241ed 100644 --- a/test/orm/test_events.py +++ b/test/orm/test_events.py @@ -24,7 +24,6 @@ from sqlalchemy.orm import instrumentation from sqlalchemy.orm import joinedload from sqlalchemy.orm import lazyload from sqlalchemy.orm import Mapper -from sqlalchemy.orm import mapper from sqlalchemy.orm import mapperlib from sqlalchemy.orm import query from sqlalchemy.orm import relationship @@ -672,11 +671,10 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): def init_e(target, args, kwargs): canary.append(("init_e", target)) - event.listen(mapper, "init", init_a) - event.listen(Mapper, "init", init_b) - event.listen(class_mapper(A), "init", init_c) - event.listen(A, "init", init_d) - event.listen(A, "init", init_e, propagate=True) + event.listen(Mapper, "init", init_a) + event.listen(class_mapper(A), "init", init_b) + event.listen(A, "init", init_c) + event.listen(A, "init", init_d, propagate=True) a = A() eq_( @@ -686,14 +684,13 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): ("init_b", a), ("init_c", a), ("init_d", a), - ("init_e", a), ], ) # test propagate flag canary[:] = [] b = B() - eq_(canary, [("init_a", b), ("init_b", b), ("init_e", b)]) + eq_(canary, [("init_a", b), ("init_d", b)]) def listen_all(self, mapper, **kw): canary = [] @@ -809,10 +806,10 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): canary = Mock() - event.listen(mapper, "before_configured", canary.listen1) - event.listen(mapper, "before_configured", canary.listen2, insert=True) - event.listen(mapper, "before_configured", canary.listen3) - event.listen(mapper, "before_configured", canary.listen4, insert=True) + event.listen(Mapper, "before_configured", canary.listen1) + event.listen(Mapper, "before_configured", canary.listen2, insert=True) + event.listen(Mapper, "before_configured", canary.listen3) + event.listen(Mapper, "before_configured", canary.listen4, insert=True) configure_mappers() @@ -864,7 +861,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): def load(obj, ctx): canary.append("load") - event.listen(mapper, "load", load) + event.listen(Mapper, "load", load) s = fixture_session() u = User(name="u1") @@ -1065,7 +1062,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): assert_raises_message( sa.exc.SAWarning, r"before_configured' and 'after_configured' ORM events only " - r"invoke with the mapper\(\) function or Mapper class as " + r"invoke with the Mapper class as " r"the target.", event.listen, User, @@ -1076,7 +1073,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): assert_raises_message( sa.exc.SAWarning, r"before_configured' and 'after_configured' ORM events only " - r"invoke with the mapper\(\) function or Mapper class as " + r"invoke with the Mapper class as " r"the target.", event.listen, User, @@ -1092,8 +1089,8 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): self.mapper_registry.map_imperatively(User, users) - event.listen(mapper, "before_configured", m1) - event.listen(mapper, "after_configured", m2) + event.listen(Mapper, "before_configured", m1) + event.listen(Mapper, "after_configured", m2) inspect(User)._post_inspect @@ -1135,7 +1132,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest): canary.init() # mapper level event - @event.listens_for(mapper, "instrument_class") + @event.listens_for(Mapper, "instrument_class") def instrument_class(mp, class_): canary.instrument_class(class_) @@ -2256,9 +2253,8 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest): sess.rollback() eq_(assertions, [True, True]) - @testing.combinations((True,), (False,)) - def test_autobegin_no_reentrant(self, future): - s1 = fixture_session(future=future) + def test_autobegin_no_reentrant(self): + s1 = fixture_session() canary = Mock() diff --git a/test/orm/test_lazy_relations.py b/test/orm/test_lazy_relations.py index cb83bb6f7..ee6d53652 100644 --- a/test/orm/test_lazy_relations.py +++ b/test/orm/test_lazy_relations.py @@ -954,7 +954,7 @@ class LazyTest(_fixtures.FixtureTest): properties={"addresses": relationship(Address, backref="user")}, ) self.mapper_registry.map_imperatively(Address, addresses) - sess = fixture_session(autoflush=False, future=True) + sess = fixture_session(autoflush=False) ad = sess.query(Address).filter_by(id=1).one() assert ad.user.id == 7 diff --git a/test/orm/test_load_on_fks.py b/test/orm/test_load_on_fks.py index fda8be423..f33a6881d 100644 --- a/test/orm/test_load_on_fks.py +++ b/test/orm/test_load_on_fks.py @@ -245,6 +245,37 @@ class LoadOnFKsTest(fixtures.DeclarativeMappedTest): self.assert_sql_count(testing.db, go, 0) + def test_enable_rel_loading_on_persistent_allows_backref_event( + self, parent_fixture + ): + sess, p1, p2, c1, c2 = parent_fixture + Parent, Child = self.classes("Parent", "Child") + + c3 = Child() + sess.enable_relationship_loading(c3) + c3.parent_id = p1.id + c3.parent = p1 + + # backref did not fire off when c3.parent was set. + # originally this was impacted by #3708, now does not happen + # due to backref_cascades behavior being removed + assert c3 not in p1.children + + def test_enable_rel_loading_allows_backref_event(self, parent_fixture): + sess, p1, p2, c1, c2 = parent_fixture + Parent, Child = self.classes("Parent", "Child") + + c3 = Child() + sess.enable_relationship_loading(c3) + c3.parent_id = p1.id + + c3.parent = p1 + + # backref did not fire off when c3.parent was set. + # originally this was impacted by #3708, now does not happen + # due to backref_cascades behavior being removed + assert c3 not in p1.children + def test_backref_doesnt_double(self, parent_fixture): sess, p1, p2, c1, c2 = parent_fixture Parent, Child = self.classes("Parent", "Child") diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py index b491604f3..73288359e 100644 --- a/test/orm/test_mapper.py +++ b/test/orm/test_mapper.py @@ -340,7 +340,7 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL): m = self.mapper(User, users) session = fixture_session() - session.connection(mapper=m) + session.connection(bind_arguments=dict(mapper=m)) def test_incomplete_columns(self): """Loading from a select which does not contain all columns""" diff --git a/test/orm/test_naturalpks.py b/test/orm/test_naturalpks.py index 05df71c6a..f2700513b 100644 --- a/test/orm/test_naturalpks.py +++ b/test/orm/test_naturalpks.py @@ -871,12 +871,12 @@ class ReversePKsTest(fixtures.MappedTest): session.commit() # testing #3108 - session.begin_nested() + nt1 = session.begin_nested() a_published.status = ARCHIVED a_editable.status = PUBLISHED - session.commit() + nt1.commit() session.rollback() eq_(a_published.status, PUBLISHED) diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 9bfeb36d8..a53c90ed4 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -2855,7 +2855,7 @@ class SliceTest(QueryTest): def test_negative_indexes_raise(self): User = self.classes.User - sess = fixture_session(future=True) + sess = fixture_session() q = sess.query(User).order_by(User.id) with expect_raises_message( diff --git a/test/orm/test_session.py b/test/orm/test_session.py index e821a7c20..a53756d63 100644 --- a/test/orm/test_session.py +++ b/test/orm/test_session.py @@ -83,6 +83,23 @@ class ExecutionTest(_fixtures.FixtureTest): [(7,), (8,), (9,)], ) + def test_no_string_execute(self, connection): + + with Session(bind=connection) as sess: + with expect_raises_message( + sa.exc.ArgumentError, + r"Textual SQL expression 'select \* from users where.*' " + "should be explicitly declared", + ): + sess.execute("select * from users where id=:id", {"id": 7}) + + with expect_raises_message( + sa.exc.ArgumentError, + r"Textual SQL expression 'select id from users .*' " + "should be explicitly declared", + ): + sess.scalar("select id from users where id=:id", {"id": 7}) + class TransScopingTest(_fixtures.FixtureTest): run_inserts = None @@ -734,7 +751,7 @@ class SessionStateTest(_fixtures.FixtureTest): assert sess.is_active def test_active_flag_autobegin_future(self): - sess = Session(bind=config.db, future=True) + sess = Session(bind=config.db) assert sess.is_active assert not sess.in_transaction() sess.begin() @@ -752,7 +769,7 @@ class SessionStateTest(_fixtures.FixtureTest): assert sess.is_active sess.begin(_subtrans=True) sess.rollback() - assert not sess.is_active + assert sess.is_active sess.rollback() assert sess.is_active @@ -888,7 +905,7 @@ class SessionStateTest(_fixtures.FixtureTest): ) self.mapper_registry.map_imperatively(Address, addresses) - session = fixture_session(future=True) + session = fixture_session() @event.listens_for(session, "after_flush") def load_collections(session, flush_context): diff --git a/test/orm/test_transaction.py b/test/orm/test_transaction.py index c5d06ba88..96a00ff54 100644 --- a/test/orm/test_transaction.py +++ b/test/orm/test_transaction.py @@ -41,26 +41,14 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): run_inserts = None __backend__ = True - @testing.fixture - def conn(self): - with testing.db.connect() as conn: - yield conn - - @testing.fixture - def future_conn(self): - - engine = testing.db - with engine.connect() as conn: - yield conn - - def test_no_close_transaction_on_flush(self, conn): + def test_no_close_transaction_on_flush(self, connection): User, users = self.classes.User, self.tables.users - c = conn + c = connection self.mapper_registry.map_imperatively(User, users) s = Session(bind=c) s.begin() - tran = s._legacy_transaction() + tran = s.get_transaction() s.add(User(name="first")) s.flush() c.exec_driver_sql("select * from users") @@ -70,15 +58,16 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): u = User(name="third") s.add(u) s.flush() - assert s._legacy_transaction() is tran + assert s.get_transaction() is tran tran.close() - def test_subtransaction_on_external_no_begin(self, conn): + def test_subtransaction_on_external_no_begin(self, connection_no_trans): users, User = self.tables.users, self.classes.User + connection = connection_no_trans self.mapper_registry.map_imperatively(User, users) - trans = conn.begin() - sess = Session(bind=conn, autoflush=True) + trans = connection.begin() + sess = Session(bind=connection, autoflush=True) u = User(name="ed") sess.add(u) sess.flush() @@ -88,12 +77,14 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): sess.close() @testing.requires.savepoints - def test_external_nested_transaction(self, conn): + def test_external_nested_transaction(self, connection_no_trans): users, User = self.tables.users, self.classes.User self.mapper_registry.map_imperatively(User, users) - trans = conn.begin() - sess = Session(bind=conn, autoflush=True) + + connection = connection_no_trans + trans = connection.begin() + sess = Session(bind=connection, autoflush=True) u1 = User(name="u1") sess.add(u1) sess.flush() @@ -107,60 +98,60 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): trans.commit() assert len(sess.query(User).all()) == 1 - def test_subtransaction_on_external_commit_future(self, future_conn): + def test_subtransaction_on_external_commit(self, connection_no_trans): users, User = self.tables.users, self.classes.User self.mapper_registry.map_imperatively(User, users) - conn = future_conn - conn.begin() + connection = connection_no_trans + connection.begin() - sess = Session(bind=conn, autoflush=True) + sess = Session(bind=connection, autoflush=True) u = User(name="ed") sess.add(u) sess.flush() sess.commit() # commit does nothing - conn.rollback() # rolls back + connection.rollback() # rolls back assert len(sess.query(User).all()) == 0 sess.close() - def test_subtransaction_on_external_rollback_future(self, future_conn): + def test_subtransaction_on_external_rollback(self, connection_no_trans): users, User = self.tables.users, self.classes.User self.mapper_registry.map_imperatively(User, users) - conn = future_conn - conn.begin() + connection = connection_no_trans + connection.begin() - sess = Session(bind=conn, autoflush=True) + sess = Session(bind=connection, autoflush=True) u = User(name="ed") sess.add(u) sess.flush() sess.rollback() # rolls back - conn.commit() # nothing to commit + connection.commit() # nothing to commit assert len(sess.query(User).all()) == 0 sess.close() @testing.requires.savepoints - def test_savepoint_on_external_future(self, future_conn): + def test_savepoint_on_external(self, connection_no_trans): users, User = self.tables.users, self.classes.User self.mapper_registry.map_imperatively(User, users) - conn = future_conn - conn.begin() - sess = Session(bind=conn, autoflush=True) + connection = connection_no_trans + connection.begin() + sess = Session(bind=connection, autoflush=True) u1 = User(name="u1") sess.add(u1) sess.flush() - sess.begin_nested() + n1 = sess.begin_nested() u2 = User(name="u2") sess.add(u2) sess.flush() - sess.rollback() + n1.rollback() - conn.commit() + connection.commit() assert len(sess.query(User).all()) == 1 @testing.requires.savepoints @@ -171,10 +162,10 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): session = fixture_session() session.begin() - session.begin_nested() + n1 = session.begin_nested() u1 = User(name="u1") session.add(u1) - session.commit() + n1.commit() assert u1 in session session.rollback() assert u1 not in session @@ -194,9 +185,9 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): session.begin() u1 = session.query(User).first() - session.begin_nested() + n1 = session.begin_nested() session.delete(u1) - session.commit() + n1.commit() assert u1 not in session session.rollback() assert u1 in session @@ -221,34 +212,6 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): assert attributes.instance_state(u1) in nt2._dirty assert attributes.instance_state(u1) not in nt1._dirty - s.commit() - assert attributes.instance_state(u1) in nt2._dirty - assert attributes.instance_state(u1) in nt1._dirty - - s.rollback() - assert attributes.instance_state(u1).expired - eq_(u1.name, "u1") - - @testing.requires.savepoints - def test_dirty_state_transferred_deep_nesting_future(self): - User, users = self.classes.User, self.tables.users - - self.mapper_registry.map_imperatively(User, users) - - with fixture_session(future=True) as s: - u1 = User(name="u1") - s.add(u1) - s.commit() - - nt1 = s.begin_nested() - nt2 = s.begin_nested() - u1.name = "u2" - assert attributes.instance_state(u1) not in nt2._dirty - assert attributes.instance_state(u1) not in nt1._dirty - s.flush() - assert attributes.instance_state(u1) in nt2._dirty - assert attributes.instance_state(u1) not in nt1._dirty - nt2.commit() assert attributes.instance_state(u1) in nt2._dirty assert attributes.instance_state(u1) in nt1._dirty @@ -341,13 +304,13 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): sess.add(u) sess.flush() - sess.begin_nested() # nested transaction + n1 = sess.begin_nested() # nested transaction u2 = User(name="u2") sess.add(u2) sess.flush() - sess.rollback() + n1.rollback() sess.commit() assert len(sess.query(User).all()) == 1 @@ -369,28 +332,6 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): sess.add(u2) sess.flush() - sess.rollback() # rolls back nested only - - sess.commit() - assert len(sess.query(User).all()) == 1 - sess.close() - - @testing.requires.savepoints - def test_nested_autotrans_future(self): - User, users = self.classes.User, self.tables.users - - self.mapper_registry.map_imperatively(User, users) - sess = fixture_session(future=True) - u = User(name="u1") - sess.add(u) - sess.flush() - - sess.begin_nested() # nested transaction - - u2 = User(name="u2") - sess.add(u2) - sess.flush() - sess.rollback() # rolls back the whole trans sess.commit() @@ -423,11 +364,11 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): sess.rollback() sess.begin() - sess.begin_nested() + n1 = sess.begin_nested() u3 = User(name="u3") sess.add(u3) - sess.commit() # commit the nested transaction + n1.commit() # commit the nested transaction sess.rollback() eq_(set(sess.query(User).all()), set([u2])) @@ -686,6 +627,10 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): eq_(session.is_active, False) session.rollback() + is_(session._transaction, None) + + session.connection() + # back to normal eq_(session._transaction._state, _session.ACTIVE) eq_(session.is_active, True) @@ -878,26 +823,18 @@ class SessionTransactionTest(fixtures.RemovesEvents, FixtureTest): sess.add(User(id=5, name="some name")) sess.commit() - def test_no_autocommit_with_explicit_commit(self): + def test_no_autobegin_after_explicit_commit(self): User, users = self.classes.User, self.tables.users self.mapper_registry.map_imperatively(User, users) session = fixture_session() session.add(User(name="ed")) - session._legacy_transaction().commit() - - is_not(session._legacy_transaction(), None) - - def test_no_autocommit_with_explicit_commit_future(self): - User, users = self.classes.User, self.tables.users + session.get_transaction().commit() - self.mapper_registry.map_imperatively(User, users) - session = fixture_session(future=True) - session.add(User(name="ed")) - session._legacy_transaction().commit() + is_(session.get_transaction(), None) - # new in 1.4 - is_(session._legacy_transaction(), None) + session.connection() + is_not(session.get_transaction(), None) class _LocalFixture(FixtureTest): @@ -989,7 +926,6 @@ def subtransaction_recipe_three(self): argnames="target_recipe,recipe_rollsback_early", id_="ns", ) -@testing.combinations((True,), (False,), argnames="future", id_="s") class SubtransactionRecipeTest(FixtureTest): run_inserts = None __backend__ = True @@ -1002,7 +938,7 @@ class SubtransactionRecipeTest(FixtureTest): def test_recipe_heavy_nesting(self, subtransaction_recipe): users = self.tables.users - with fixture_session(future=self.future) as session: + with fixture_session() as session: with subtransaction_recipe(session): session.connection().execute( users.insert().values(name="user1") @@ -1046,7 +982,7 @@ class SubtransactionRecipeTest(FixtureTest): self.mapper_registry.map_imperatively(User, users) with testing.db.connect() as conn: trans = conn.begin() - sess = Session(conn, future=self.future) + sess = Session(conn) with subtransaction_recipe(sess): u = User(name="ed") @@ -1061,7 +997,7 @@ class SubtransactionRecipeTest(FixtureTest): User, users = self.classes.User, self.tables.users self.mapper_registry.map_imperatively(User, users) - with fixture_session(future=self.future) as sess: + with fixture_session() as sess: with subtransaction_recipe(sess): u = User(name="u1") sess.add(u) @@ -1074,7 +1010,7 @@ class SubtransactionRecipeTest(FixtureTest): User, users = self.classes.User, self.tables.users self.mapper_registry.map_imperatively(User, users) - with fixture_session(future=self.future) as sess: + with fixture_session() as sess: sess.begin() with subtransaction_recipe(sess): u = User(name="u1") @@ -1090,7 +1026,7 @@ class SubtransactionRecipeTest(FixtureTest): self.mapper_registry.map_imperatively(User, users) - with fixture_session(future=self.future) as sess: + with fixture_session() as sess: sess.begin() sess.begin_nested() @@ -1111,7 +1047,7 @@ class SubtransactionRecipeTest(FixtureTest): sess.add(User(name="u2")) t2.commit() - assert sess._legacy_transaction() is t1 + assert sess.get_transaction() is t1 def test_recipe_error_on_using_inactive_session_commands( self, subtransaction_recipe @@ -1119,7 +1055,7 @@ class SubtransactionRecipeTest(FixtureTest): users, User = self.tables.users, self.classes.User self.mapper_registry.map_imperatively(User, users) - with fixture_session(future=self.future) as sess: + with fixture_session() as sess: sess.begin() try: @@ -1141,13 +1077,13 @@ class SubtransactionRecipeTest(FixtureTest): assert not sess.in_transaction() def test_recipe_multi_nesting(self, subtransaction_recipe): - with fixture_session(future=self.future) as sess: + with fixture_session() as sess: with subtransaction_recipe(sess): assert sess.in_transaction() try: with subtransaction_recipe(sess): - assert sess._legacy_transaction() + assert sess.get_transaction() raise Exception("force rollback") except: pass @@ -1160,7 +1096,7 @@ class SubtransactionRecipeTest(FixtureTest): assert not sess.in_transaction() def test_recipe_deactive_status_check(self, subtransaction_recipe): - with fixture_session(future=self.future) as sess: + with fixture_session() as sess: sess.begin() with subtransaction_recipe(sess): @@ -1217,12 +1153,12 @@ class CleanSavepointTest(FixtureTest): run_inserts = None __backend__ = True - def _run_test(self, update_fn, future=False): + def _run_test(self, update_fn): User, users = self.classes.User, self.tables.users self.mapper_registry.map_imperatively(User, users) - with fixture_session(future=future) as s: + with fixture_session() as s: u1 = User(name="u1") u2 = User(name="u2") s.add_all([u1, u2]) @@ -1236,12 +1172,8 @@ class CleanSavepointTest(FixtureTest): eq_(u2.name, "u2modified") s.rollback() - if future: - assert s._transaction is None - assert "name" not in u1.__dict__ - else: - assert s._transaction is trans - eq_(u1.__dict__["name"], "u1") + assert s._transaction is None + assert "name" not in u1.__dict__ assert "name" not in u2.__dict__ eq_(u2.name, "u2") @@ -1498,13 +1430,13 @@ class RollbackRecoverTest(_LocalFixture): u1.name = "edward" a1.email_address = "foober" - s.begin_nested() + nt1 = s.begin_nested() s.add(u2) with expect_warnings("New instance"): assert_raises(sa_exc.IntegrityError, s.commit) assert_raises(sa_exc.InvalidRequestError, s.commit) - s.rollback() + nt1.rollback() assert u2 not in s assert a2 not in s assert u1 in s @@ -1534,7 +1466,7 @@ class SavepointTest(_LocalFixture): u2 = User(name="jack") s.add_all([u1, u2]) - s.begin_nested() + nt1 = s.begin_nested() u3 = User(name="wendy") u4 = User(name="foo") u1.name = "edward" @@ -1544,7 +1476,7 @@ class SavepointTest(_LocalFixture): s.query(User.name).order_by(User.id).all(), [("edward",), ("jackward",), ("wendy",), ("foo",)], ) - s.rollback() + nt1.rollback() assert u1.name == "ed" assert u2.name == "jack" eq_(s.query(User.name).order_by(User.id).all(), [("ed",), ("jack",)]) @@ -1575,7 +1507,7 @@ class SavepointTest(_LocalFixture): u2 = User(name="jack") s.add_all([u1, u2]) - s.begin_nested() + nt1 = s.begin_nested() u3 = User(name="wendy") u4 = User(name="foo") u1.name = "edward" @@ -1585,7 +1517,7 @@ class SavepointTest(_LocalFixture): s.query(User.name).order_by(User.id).all(), [("edward",), ("jackward",), ("wendy",), ("foo",)], ) - s.commit() + nt1.commit() def go(): assert u1.name == "edward" @@ -1613,7 +1545,7 @@ class SavepointTest(_LocalFixture): u1.name = "edward" u1.addresses.append(Address(email_address="bar")) - s.begin_nested() + nt1 = s.begin_nested() u2 = User(name="jack", addresses=[Address(email_address="bat")]) s.add(u2) eq_( @@ -1629,7 +1561,7 @@ class SavepointTest(_LocalFixture): User(name="jack", addresses=[Address(email_address="bat")]), ], ) - s.rollback() + nt1.rollback() eq_( s.query(User).order_by(User.id).all(), [ @@ -1751,7 +1683,7 @@ class SavepointTest(_LocalFixture): nested_trans = trans._connections[self.bind][1] nested_trans._do_commit() - is_(s._legacy_transaction(), trans) + is_(s.get_nested_transaction(), trans) with expect_warnings("nested transaction already deassociated"): # this previously would raise @@ -1762,12 +1694,14 @@ class SavepointTest(_LocalFixture): assert u1 not in s.new is_(trans._state, _session.CLOSED) - is_not(s._legacy_transaction(), trans) - is_(s._legacy_transaction()._state, _session.ACTIVE) + is_not(s.get_transaction(), trans) - is_(s._legacy_transaction().nested, False) + s.connection() + is_(s.get_transaction()._state, _session.ACTIVE) + + is_(s.get_transaction().nested, False) - is_(s._legacy_transaction()._parent, None) + is_(s.get_transaction()._parent, None) class AccountingFlagsTest(_LocalFixture): @@ -1851,7 +1785,7 @@ class ContextManagerPlusFutureTest(FixtureTest): def test_explicit_begin(self): with fixture_session() as s1: with s1.begin() as trans: - is_(trans, s1._legacy_transaction()) + is_(trans, s1.get_transaction()) s1.connection() is_(s1._transaction, None) @@ -1866,10 +1800,10 @@ class ContextManagerPlusFutureTest(FixtureTest): ) @testing.requires.savepoints - def test_future_rollback_is_global(self): + def test_rollback_is_global(self): users = self.tables.users - with fixture_session(future=True) as s1: + with fixture_session() as s1: s1.begin() s1.connection().execute(users.insert(), [{"id": 1, "name": "n1"}]) @@ -1890,7 +1824,7 @@ class ContextManagerPlusFutureTest(FixtureTest): # rolls back the whole transaction s1.rollback() - is_(s1._legacy_transaction(), None) + is_(s1.get_transaction(), None) eq_( s1.connection().scalar( @@ -1900,79 +1834,13 @@ class ContextManagerPlusFutureTest(FixtureTest): ) s1.commit() - is_(s1._legacy_transaction(), None) - - @testing.requires.savepoints - def test_old_rollback_is_local(self): - users = self.tables.users - - with fixture_session() as s1: - - t1 = s1.begin() - - s1.connection().execute(users.insert(), [{"id": 1, "name": "n1"}]) - - s1.begin_nested() - - s1.connection().execute( - users.insert(), - [{"id": 2, "name": "n2"}, {"id": 3, "name": "n3"}], - ) - - eq_( - s1.connection().scalar( - select(func.count()).select_from(users) - ), - 3, - ) - - # rolls back only the savepoint - s1.rollback() - - is_(s1._legacy_transaction(), t1) - - eq_( - s1.connection().scalar( - select(func.count()).select_from(users) - ), - 1, - ) - - s1.commit() - eq_( - s1.connection().scalar( - select(func.count()).select_from(users) - ), - 1, - ) - is_not(s1._legacy_transaction(), None) + is_(s1.get_transaction(), None) def test_session_as_ctx_manager_one(self): users = self.tables.users with fixture_session() as sess: - is_not(sess._legacy_transaction(), None) - - sess.connection().execute( - users.insert().values(id=1, name="user1") - ) - - eq_( - sess.connection().execute(users.select()).all(), [(1, "user1")] - ) - - is_not(sess._legacy_transaction(), None) - - is_not(sess._legacy_transaction(), None) - - # did not commit - eq_(sess.connection().execute(users.select()).all(), []) - - def test_session_as_ctx_manager_future_one(self): - users = self.tables.users - - with fixture_session(future=True) as sess: - is_(sess._legacy_transaction(), None) + is_(sess.get_transaction(), None) sess.connection().execute( users.insert().values(id=1, name="user1") @@ -1982,9 +1850,9 @@ class ContextManagerPlusFutureTest(FixtureTest): sess.connection().execute(users.select()).all(), [(1, "user1")] ) - is_not(sess._legacy_transaction(), None) + is_not(sess.get_transaction(), None) - is_(sess._legacy_transaction(), None) + is_(sess.get_transaction(), None) # did not commit eq_(sess.connection().execute(users.select()).all(), []) @@ -1994,23 +1862,7 @@ class ContextManagerPlusFutureTest(FixtureTest): try: with fixture_session() as sess: - is_not(sess._legacy_transaction(), None) - - sess.connection().execute( - users.insert().values(id=1, name="user1") - ) - - raise Exception("force rollback") - except: - pass - is_not(sess._legacy_transaction(), None) - - def test_session_as_ctx_manager_two_future(self): - users = self.tables.users - - try: - with fixture_session(future=True) as sess: - is_(sess._legacy_transaction(), None) + is_(sess.get_transaction(), None) sess.connection().execute( users.insert().values(id=1, name="user1") @@ -2019,7 +1871,7 @@ class ContextManagerPlusFutureTest(FixtureTest): raise Exception("force rollback") except: pass - is_(sess._legacy_transaction(), None) + is_(sess.get_transaction(), None) def test_begin_context_manager(self): users = self.tables.users @@ -2151,15 +2003,13 @@ class ContextManagerPlusFutureTest(FixtureTest): eq_(sess.connection().execute(users.select()).all(), [(1, "user1")]) sess.close() - @testing.combinations((True,), (False,), argnames="future") - def test_interrupt_ctxmanager(self, trans_ctx_manager_fixture, future): + def test_interrupt_ctxmanager(self, trans_ctx_manager_fixture): fn = trans_ctx_manager_fixture - session = fixture_session(future=future) + session = fixture_session() fn(session, trans_on_subject=True, execute_on_subject=True) - @testing.combinations((True,), (False,), argnames="future") @testing.combinations((True,), (False,), argnames="rollback") @testing.combinations((True,), (False,), argnames="expire_on_commit") @testing.combinations( @@ -2170,15 +2020,13 @@ class ContextManagerPlusFutureTest(FixtureTest): argnames="check_operation", ) def test_interrupt_ctxmanager_ops( - self, future, rollback, expire_on_commit, check_operation + self, rollback, expire_on_commit, check_operation ): users, User = self.tables.users, self.classes.User self.mapper_registry.map_imperatively(User, users) - session = fixture_session( - future=future, expire_on_commit=expire_on_commit - ) + session = fixture_session(expire_on_commit=expire_on_commit) with session.begin(): u1 = User(id=7, name="u1") @@ -2266,8 +2114,8 @@ class TransactionFlagsTest(fixtures.TestBase): s1.rollback() - eq_(s1.in_transaction(), True) - is_(s1._transaction, trans) + eq_(s1.in_transaction(), False) + is_(s1._transaction, None) s1.rollback() @@ -2560,7 +2408,7 @@ class NewStyleJoinIntoAnExternalTransactionTest( self.A = A # bind an individual Session to the connection - self.session = Session(bind=self.connection, future=True) + self.session = Session(bind=self.connection) if testing.requires.savepoints.enabled: self.nested = self.connection.begin_nested() diff --git a/test/orm/test_versioning.py b/test/orm/test_versioning.py index 9d14ceba1..b5955e4a6 100644 --- a/test/orm/test_versioning.py +++ b/test/orm/test_versioning.py @@ -748,7 +748,7 @@ class VersionOnPostUpdateTest(fixtures.MappedTest): # outwit the database transaction isolation and SQLA's # expiration at the same time by using different Session on # same transaction - s2 = Session(bind=s.connection(mapper=Node)) + s2 = Session(bind=s.connection(bind_arguments=dict(mapper=Node))) s2.query(Node).filter(Node.id == n2.id).update({"version_id": 3}) s2.commit() @@ -770,7 +770,7 @@ class VersionOnPostUpdateTest(fixtures.MappedTest): ), patch.object( config.db.dialect, "supports_sane_multi_rowcount", False ): - s2 = Session(bind=s.connection(mapper=Node)) + s2 = Session(bind=s.connection(bind_arguments=dict(mapper=Node))) s2.query(Node).filter(Node.id == n2.id).update({"version_id": 3}) s2.commit() @@ -791,7 +791,7 @@ class VersionOnPostUpdateTest(fixtures.MappedTest): # outwit the database transaction isolation and SQLA's # expiration at the same time by using different Session on # same transaction - s2 = Session(bind=s.connection(mapper=Node)) + s2 = Session(bind=s.connection(bind_arguments=dict(mapper=Node))) s2.query(Node).filter(Node.id == n1.id).update({"version_id": 3}) s2.commit() diff --git a/test/sql/test_case_statement.py b/test/sql/test_case_statement.py index db7f16194..6893a9442 100644 --- a/test/sql/test_case_statement.py +++ b/test/sql/test_case_statement.py @@ -215,23 +215,10 @@ class CaseTest(fixtures.TestBase, AssertsCompiledSQL): def test_when_dicts(self, test_case, expected): t = table("test", column("col1")) - whens, value, else_ = testing.resolve_lambda(test_case, t=t) - - def _case_args(whens, value=None, else_=None): - kw = {} - if value is not None: - kw["value"] = value - if else_ is not None: - kw["else_"] = else_ - - return case(whens, **kw) - - # note: 1.3 also does not allow this form - # case([whens], **kw) + when_dict, value, else_ = testing.resolve_lambda(test_case, t=t) self.assert_compile( - _case_args(whens=whens, value=value, else_=else_), - expected, + case(when_dict, value=value, else_=else_), expected ) def test_text_doesnt_explode(self, connection): diff --git a/test/sql/test_deprecations.py b/test/sql/test_deprecations.py index ea075b36d..f07410110 100644 --- a/test/sql/test_deprecations.py +++ b/test/sql/test_deprecations.py @@ -1,12 +1,8 @@ #! coding: utf-8 -import itertools -import random - from sqlalchemy import alias from sqlalchemy import and_ from sqlalchemy import bindparam -from sqlalchemy import case from sqlalchemy import CHAR from sqlalchemy import column from sqlalchemy import exc @@ -29,14 +25,11 @@ from sqlalchemy import text from sqlalchemy.engine import default from sqlalchemy.sql import coercions from sqlalchemy.sql import LABEL_STYLE_TABLENAME_PLUS_COL -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_message from sqlalchemy.testing import assertions from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import eq_ @@ -46,7 +39,6 @@ from sqlalchemy.testing import is_true from sqlalchemy.testing import mock from sqlalchemy.testing.schema import Column from sqlalchemy.testing.schema import Table -from .test_update import _UpdateFromTestBase class ToMetaDataTest(fixtures.TestBase): @@ -313,165 +305,6 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL): ): eq_(stmt.froms, [t1]) - def test_case_list_legacy(self): - t1 = table("t", column("q")) - - with testing.expect_deprecated( - r"The \"whens\" argument to case\(\), when referring " - r"to a sequence of items, is now passed" - ): - stmt = select(t1).where( - case( - [(t1.c.q == 5, "foo"), (t1.c.q == 10, "bar")], else_="bat" - ) - != "bat" - ) - - self.assert_compile( - stmt, - "SELECT t.q FROM t WHERE CASE WHEN (t.q = :q_1) " - "THEN :param_1 WHEN (t.q = :q_2) THEN :param_2 " - "ELSE :param_3 END != :param_4", - ) - - def test_case_whens_kw(self): - t1 = table("t", column("q")) - - with testing.expect_deprecated( - r"The \"whens\" argument to case\(\), when referring " - "to a sequence of items, is now passed" - ): - stmt = select(t1).where( - case( - whens=[(t1.c.q == 5, "foo"), (t1.c.q == 10, "bar")], - else_="bat", - ) - != "bat" - ) - - self.assert_compile( - stmt, - "SELECT t.q FROM t WHERE CASE WHEN (t.q = :q_1) " - "THEN :param_1 WHEN (t.q = :q_2) THEN :param_2 " - "ELSE :param_3 END != :param_4", - ) - - @testing.combinations( - ( - (lambda t: ({"x": "y"}, t.c.col1, None)), - "CASE test.col1 WHEN :param_1 THEN :param_2 END", - ), - ( - (lambda t: ({"x": "y", "p": "q"}, t.c.col1, None)), - "CASE test.col1 WHEN :param_1 THEN :param_2 " - "WHEN :param_3 THEN :param_4 END", - ), - ( - (lambda t: ({t.c.col1 == 7: "x"}, None, 10)), - "CASE WHEN (test.col1 = :col1_1) THEN :param_1 ELSE :param_2 END", - ), - ( - (lambda t: ({t.c.col1 == 7: "x", t.c.col1 == 10: "y"}, None, 10)), - "CASE WHEN (test.col1 = :col1_1) THEN :param_1 " - "WHEN (test.col1 = :col1_2) THEN :param_2 ELSE :param_3 END", - ), - argnames="test_case, expected", - ) - def test_when_kwarg(self, test_case, expected): - t = table("test", column("col1")) - - whens, value, else_ = testing.resolve_lambda(test_case, t=t) - - def _case_args(whens, value=None, else_=None): - kw = {} - if value is not None: - kw["value"] = value - if else_ is not None: - kw["else_"] = else_ - - with testing.expect_deprecated_20( - r'The "whens" argument to case\(\) is now passed using ' - r"positional style only, not as a keyword argument." - ): - - return case(whens=whens, **kw) - - # note: 1.3 also does not allow this form - # case([whens], **kw) - - self.assert_compile( - _case_args(whens=whens, value=value, else_=else_), - expected, - ) - - def test_case_whens_dict_kw(self): - t1 = table("t", column("q")) - with testing.expect_deprecated( - r"The \"whens\" argument to case\(\) is now passed" - ): - stmt = select(t1).where( - case( - whens={t1.c.q == 5: "foo"}, - else_="bat", - ) - != "bat" - ) - self.assert_compile( - stmt, - "SELECT t.q FROM t WHERE CASE WHEN (t.q = :q_1) THEN " - ":param_1 ELSE :param_2 END != :param_3", - ) - - def test_case_kw_arg_detection(self): - # because we support py2k, case() has to parse **kw for now - - assert_raises_message( - TypeError, - "unknown arguments: bat, foo", - case, - (column("x") == 10, 5), - else_=15, - foo="bar", - bat="hoho", - ) - - def test_with_only_generative(self): - table1 = table( - "table1", - column("col1"), - column("col2"), - column("col3"), - column("colx"), - ) - s1 = table1.select().scalar_subquery() - - with testing.expect_deprecated_20( - r"The \"columns\" argument to " - r"Select.with_only_columns\(\), when referring " - "to a sequence of items, is now passed" - ): - stmt = s1.with_only_columns([s1]) - self.assert_compile( - stmt, - "SELECT (SELECT table1.col1, table1.col2, " - "table1.col3, table1.colx FROM table1) AS anon_1", - ) - - def test_from_list_with_columns(self): - table1 = table("t1", column("a")) - table2 = table("t2", column("b")) - s1 = select(table1.c.a, table2.c.b) - self.assert_compile(s1, "SELECT t1.a, t2.b FROM t1, t2") - - with testing.expect_deprecated_20( - r"The \"columns\" argument to " - r"Select.with_only_columns\(\), when referring " - "to a sequence of items, is now passed" - ): - s2 = s1.with_only_columns([table2.c.b]) - - self.assert_compile(s2, "SELECT t2.b FROM t2") - def test_column(self): stmt = select(column("x")) with testing.expect_deprecated( @@ -504,16 +337,6 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL): "ON basefrom.a = joinfrom.a", ) - with testing.expect_deprecated(r"The Select.append_column\(\)"): - replaced.append_column(joinfrom.c.b) - - self.assert_compile( - replaced, - "SELECT basefrom.a, joinfrom.b FROM (SELECT 1 AS a) AS basefrom " - "JOIN (SELECT 1 AS a, 2 AS b) AS joinfrom " - "ON basefrom.a = joinfrom.a", - ) - def test_against_cloned_non_table(self): # test that corresponding column digs across # clone boundaries with anonymous labeled elements @@ -567,31 +390,6 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL): assert u.corresponding_column(s2.c.table2_coly) is u.c.coly assert s2.c.corresponding_column(u.c.coly) is s2.c.table2_coly - def test_join_alias(self): - j1 = self.table1.join(self.table2) - - with testing.expect_deprecated_20( - r"The Join.alias\(\) method is considered legacy" - ): - self.assert_compile( - j1.alias(), - "SELECT table1.col1 AS table1_col1, table1.col2 AS " - "table1_col2, table1.col3 AS table1_col3, table1.colx " - "AS table1_colx, table2.col1 AS table2_col1, " - "table2.col2 AS table2_col2, table2.col3 AS table2_col3, " - "table2.coly AS table2_coly FROM table1 JOIN table2 " - "ON table1.col1 = table2.col2", - ) - - with testing.expect_deprecated_20( - r"The Join.alias\(\) method is considered legacy" - ): - self.assert_compile( - j1.alias(flat=True), - "table1 AS table1_1 JOIN table2 AS table2_1 " - "ON table1_1.col1 = table2_1.col2", - ) - def test_join_against_self_implicit_subquery(self): jj = select(self.table1.c.col1.label("bar_col1")) with testing.expect_deprecated( @@ -613,16 +411,6 @@ class SelectableTest(fixtures.TestBase, AssertsCompiledSQL): ): assert jjj.corresponding_column(jj.c.bar_col1) is jjj_bar_col1 - # test alias of the join - - with testing.expect_deprecated( - r"The Join.alias\(\) method is considered legacy" - ): - j2 = jjj.alias("foo") - assert ( - j2.corresponding_column(self.table1.c.col1) is j2.c.table1_col1 - ) - def test_select_labels(self): a = self.table1.select().set_label_style( LABEL_STYLE_TABLENAME_PLUS_COL @@ -759,104 +547,6 @@ class TextualSelectTest(fixtures.TestBase, AssertsCompiledSQL): eq_(t.c.c.type._type_affinity, String) -class DeprecatedAppendMethTest(fixtures.TestBase, AssertsCompiledSQL): - __dialect__ = "default" - - def _expect_deprecated(self, clsname, methname, newmeth): - return testing.expect_deprecated( - r"The %s.append_%s\(\) method is deprecated " - r"and will be removed in a future release. Use the generative " - r"method %s.%s\(\)." % (clsname, methname, clsname, newmeth) - ) - - def test_append_whereclause(self): - t = table("t", column("q")) - stmt = select(t) - - with self._expect_deprecated("Select", "whereclause", "where"): - stmt.append_whereclause(t.c.q == 5) - - self.assert_compile(stmt, "SELECT t.q FROM t WHERE t.q = :q_1") - - def test_append_having(self): - t = table("t", column("q")) - stmt = select(t).group_by(t.c.q) - - with self._expect_deprecated("Select", "having", "having"): - stmt.append_having(t.c.q == 5) - - self.assert_compile( - stmt, "SELECT t.q FROM t GROUP BY t.q HAVING t.q = :q_1" - ) - - def test_append_order_by(self): - t = table("t", column("q"), column("x")) - stmt = select(t).where(t.c.q == 5) - - with self._expect_deprecated( - "GenerativeSelect", "order_by", "order_by" - ): - stmt.append_order_by(t.c.x) - - self.assert_compile( - stmt, "SELECT t.q, t.x FROM t WHERE t.q = :q_1 ORDER BY t.x" - ) - - def test_append_group_by(self): - t = table("t", column("q")) - stmt = select(t) - - with self._expect_deprecated( - "GenerativeSelect", "group_by", "group_by" - ): - stmt.append_group_by(t.c.q) - - stmt = stmt.having(t.c.q == 5) - - self.assert_compile( - stmt, "SELECT t.q FROM t GROUP BY t.q HAVING t.q = :q_1" - ) - - def test_append_correlation(self): - t1 = table("t1", column("q")) - t2 = table("t2", column("q"), column("p")) - - inner = select(t2.c.p).where(t2.c.q == t1.c.q) - - with self._expect_deprecated("Select", "correlation", "correlate"): - inner.append_correlation(t1) - stmt = select(t1).where(t1.c.q == inner.scalar_subquery()) - - self.assert_compile( - stmt, - "SELECT t1.q FROM t1 WHERE t1.q = " - "(SELECT t2.p FROM t2 WHERE t2.q = t1.q)", - ) - - def test_append_column(self): - t1 = table("t1", column("q"), column("p")) - stmt = select(t1.c.q) - with self._expect_deprecated("Select", "column", "add_columns"): - stmt.append_column(t1.c.p) - self.assert_compile(stmt, "SELECT t1.q, t1.p FROM t1") - - def test_append_prefix(self): - t1 = table("t1", column("q"), column("p")) - stmt = select(t1.c.q) - with self._expect_deprecated("Select", "prefix", "prefix_with"): - stmt.append_prefix("FOO BAR") - self.assert_compile(stmt, "SELECT FOO BAR t1.q FROM t1") - - def test_append_from(self): - t1 = table("t1", column("q")) - t2 = table("t2", column("q")) - - stmt = select(t1) - with self._expect_deprecated("Select", "from", "select_from"): - stmt.append_from(t1.join(t2, t1.c.q == t2.c.q)) - self.assert_compile(stmt, "SELECT t1.q FROM t1 JOIN t2 ON t1.q = t2.q") - - class KeyTargetingTest(fixtures.TablesTest): run_inserts = "once" run_deletes = None @@ -971,365 +661,6 @@ class PKIncrementTest(fixtures.TablesTest): ) -class DMLTest(_UpdateFromTestBase, fixtures.TablesTest, AssertsCompiledSQL): - __dialect__ = "default" - - def test_insert_inline_kw_defaults(self): - m = MetaData() - foo = Table("foo", m, Column("id", Integer)) - - t = Table( - "test", - m, - Column("col1", Integer, default=func.foo(1)), - Column( - "col2", - Integer, - default=select(func.coalesce(func.max(foo.c.id))), - ), - ) - - with testing.expect_deprecated_20( - "The insert.inline parameter will be removed in SQLAlchemy 2.0." - ): - stmt = t.insert(inline=True, values={}) - - self.assert_compile( - stmt, - "INSERT INTO test (col1, col2) VALUES (foo(:foo_1), " - "(SELECT coalesce(max(foo.id)) AS coalesce_1 FROM " - "foo))", - ) - - def test_insert_inline_kw_default(self): - metadata = MetaData() - table = Table( - "sometable", - metadata, - Column("id", Integer, primary_key=True), - Column("foo", Integer, default=func.foobar()), - ) - - with testing.expect_deprecated_20( - "The insert.inline parameter will be removed in SQLAlchemy 2.0." - ): - stmt = table.insert(values={}, inline=True) - - self.assert_compile( - stmt, - "INSERT INTO sometable (foo) VALUES (foobar())", - ) - - with testing.expect_deprecated_20( - "The insert.inline parameter will be removed in SQLAlchemy 2.0." - ): - stmt = table.insert(inline=True) - - self.assert_compile( - stmt, - "INSERT INTO sometable (foo) VALUES (foobar())", - params={}, - ) - - def test_update_inline_kw_defaults(self): - m = MetaData() - foo = Table("foo", m, Column("id", Integer)) - - t = Table( - "test", - m, - Column("col1", Integer, onupdate=func.foo(1)), - Column( - "col2", - Integer, - onupdate=select(func.coalesce(func.max(foo.c.id))), - ), - Column("col3", String(30)), - ) - - with testing.expect_deprecated_20( - "The update.inline parameter will be removed in SQLAlchemy 2.0." - ): - stmt = t.update(inline=True, values={"col3": "foo"}) - - self.assert_compile( - stmt, - "UPDATE test SET col1=foo(:foo_1), col2=(SELECT " - "coalesce(max(foo.id)) AS coalesce_1 FROM foo), " - "col3=:col3", - ) - - def test_update_dialect_kwargs(self): - t = table("foo", column("bar")) - - with testing.expect_deprecated_20("Passing dialect keyword arguments"): - stmt = t.update(mysql_limit=10) - - self.assert_compile( - 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): with testing.expect_deprecated("Deprecated alias of .*must_exist"): diff --git a/test/sql/test_roles.py b/test/sql/test_roles.py index abbef8e28..5c9ed3588 100644 --- a/test/sql/test_roles.py +++ b/test/sql/test_roles.py @@ -226,15 +226,13 @@ class RoleTest(fixtures.TestBase): ): expect(roles.ExpressionElementRole, Thing()) - def test_statement_text_coercion(self): - with testing.expect_deprecated_20( - "Using plain strings to indicate SQL statements" + def test_no_statement_text_coercion(self): + with testing.expect_raises_message( + exc.ArgumentError, + r"Textual SQL expression 'select \* from table' should be " + "explicitly declared", ): - is_true( - expect(roles.StatementRole, "select * from table").compare( - text("select * from table") - ) - ) + expect(roles.StatementRole, "select * from table") def test_select_statement_no_text_coercion(self): assert_raises_message( diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py index c3a2d8d3c..a63ae5be4 100644 --- a/test/sql/test_selectable.py +++ b/test/sql/test_selectable.py @@ -608,6 +608,17 @@ class SelectableTest( "table1.col3, table1.colx FROM table1) AS anon_1", ) + def test_with_only_generative_no_list(self): + s1 = table1.select().scalar_subquery() + + with testing.expect_raises_message( + exc.ArgumentError, + r"The \"columns\" argument to " + r"Select.with_only_columns\(\), when referring " + "to a sequence of items, is now passed", + ): + s1.with_only_columns([s1]) + @testing.combinations( ( [table1.c.col1], diff --git a/test/sql/test_types.py b/test/sql/test_types.py index fb1bdad2e..79b77581d 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -79,7 +79,6 @@ from sqlalchemy.testing import AssertsCompiledSQL from sqlalchemy.testing import AssertsExecutionResults from sqlalchemy.testing import engines from sqlalchemy.testing import eq_ -from sqlalchemy.testing import expect_deprecated_20 from sqlalchemy.testing import expect_raises from sqlalchemy.testing import fixtures from sqlalchemy.testing import is_ @@ -2529,12 +2528,6 @@ class EnumTest(AssertsCompiledSQL, fixtures.TablesTest): [(1, self.SomeEnum.three), (2, self.SomeEnum.three)], ) - def test_omit_warn(self): - with expect_deprecated_20( - r"The provided enum someenum contains the aliases \['four'\]" - ): - Enum(self.SomeEnum) - @testing.combinations( (True, "native"), (False, "non_native"), id_="ai", argnames="native" ) -- cgit v1.2.1