def test_bind_create_drop_constructor_bound(self): for bind in (testing.db, testing.db.connect()): if isinstance(bind, engine.Connection): bind.begin() try: for args in (([bind], {}), ([], {"bind": bind})): with testing.expect_deprecated_20( "The MetaData.bind argument is deprecated "): metadata = MetaData(*args[0], **args[1]) table = Table("test_table", metadata, Column("foo", Integer)) assert metadata.bind is table.bind is bind with testing.expect_deprecated_20( "The ``bind`` argument for schema methods " "that invoke SQL"): metadata.create_all() is_true(inspect(bind).has_table(table.name)) with testing.expect_deprecated_20( "The ``bind`` argument for schema methods " "that invoke SQL"): metadata.drop_all() with testing.expect_deprecated_20( "The ``bind`` argument for schema methods " "that invoke SQL"): table.create() with testing.expect_deprecated_20( "The ``bind`` argument for schema methods " "that invoke SQL"): table.drop() is_false(inspect(bind).has_table(table.name)) finally: if isinstance(bind, engine.Connection): bind.close()
def test_explicit_connectionless_execute(self): table = Table("t", self.metadata, Column("a", Integer)) table.create(testing.db) stmt = table.insert().values(a=1) with testing.expect_deprecated_20( r"The Engine.execute\(\) method is considered legacy", ): testing.db.execute(stmt) stmt = select(table) with testing.expect_deprecated_20( r"The Engine.execute\(\) method is considered legacy", ): eq_(testing.db.execute(stmt).fetchall(), [(1, )])
def test_implicit_execute(self): table = Table("t", self.metadata, Column("a", Integer)) table.create(testing.db) stmt = table.insert().values(a=1) with testing.expect_deprecated_20( r"The Executable.execute\(\) function/method is considered legacy", ): stmt.execute() stmt = select([table]) with testing.expect_deprecated_20( r"The Executable.execute\(\) function/method is considered legacy", ): eq_(stmt.execute().fetchall(), [(1, )])
def test_bind_clauseelement(self): metadata = MetaData() table = Table("test_table", metadata, Column("foo", Integer)) metadata.create_all(bind=testing.db) try: for elem in [ table.select, lambda **kwargs: sa.func.current_timestamp(**kwargs).select(), # func.current_timestamp().select, lambda **kwargs: text("select * from test_table", **kwargs), ]: for bind in (testing.db, testing.db.connect()): try: with testing.expect_deprecated_20( "The .*bind argument is deprecated" ): e = elem(bind=bind) assert e.bind is bind e.execute().close() finally: if isinstance(bind, engine.Connection): bind.close() e = elem() assert e.bind is None assert_raises(exc.UnboundExecutionError, e.execute) finally: if isinstance(bind, engine.Connection): bind.close() metadata.drop_all(bind=testing.db)
def test_implicit_autocommit_driversql(self): with testing.db.connect() as conn: with testing.expect_deprecated_20( "The current statement is being autocommitted " "using implicit autocommit."): conn.exec_driver_sql( "insert into inserttable (data) values ('thedata')")
def test_statement_text_coercion(self): with testing.expect_deprecated_20( "Using plain strings to indicate SQL statements"): is_true( expect(roles.CoerceTextStatementRole, "select * from table").compare( text("select * from table")))
def test_reflecttable(self): inspector = inspect(testing.db) metadata = self.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)
def test_branched_connection_execution_options(self): engine = engines.testing_engine("sqlite://") conn = engine.connect() c2 = conn.execution_options(foo="bar") with testing.expect_deprecated_20( r"The Connection.connect\(\) function/method is considered "): c2_branch = c2.connect() eq_(c2_branch._execution_options, {"foo": "bar"})
def test_run_transaction_retry(self): def txn_body(sess): rs = sess.execute(text("select acct, balance from account where acct = 1")) sess.execute(text("select crdb_internal.force_retry('1s')")) return [r for r in rs] with testing.expect_deprecated_20("The Session.autocommit parameter is deprecated"): Session = sessionmaker(testing.db) rs = run_transaction(Session, txn_body) assert rs[0] == (1, 100)
def test_kwargs(self, connection): users = self.tables.users with testing.expect_deprecated_20( r"The connection.execute\(\) method in " "SQLAlchemy 2.0 will accept parameters as a single "): connection.execute(users.insert(), user_id=5, user_name="some name") eq_(connection.execute(select(users)).all(), [(5, "some name")])
def test_implicit_autocommit_compiled(self): users = self.tables.users with testing.db.connect() as conn: with testing.expect_deprecated_20( "The current statement is being autocommitted " "using implicit autocommit." ): conn.execute( users.insert(), {"user_id": 1, "user_name": "user3"} )
def test_bind_create_drop_err_metadata(self): metadata = MetaData() Table("test_table", metadata, Column("foo", Integer)) for meth in [metadata.create_all, metadata.drop_all]: with testing.expect_deprecated_20( "The ``bind`` argument for schema methods that invoke SQL" ): assert_raises_message( exc.UnboundExecutionError, "MetaData object is not bound to an Engine or Connection.", meth, )
def test_branch_invalidate_state(self): with self.engine.connect() as c1: with testing.expect_deprecated_20( r"The Connection.connect\(\) method is considered legacy"): c1_branch = c1.connect() eq_(c1_branch.execute(select(1)).scalar(), 1) self.engine.test_shutdown() _assert_invalidated(c1_branch.execute, select(1)) assert not c1_branch.closed assert not c1_branch._still_open_and_dbapi_connection_is_valid
def test_bind_clauseelement(self, metadata): table = Table("test_table", metadata, Column("foo", Integer)) metadata.create_all(bind=testing.db) for elem in [ table.select, lambda **kwargs: sa.func.current_timestamp(**kwargs).select(), # func.current_timestamp().select, lambda **kwargs: text("select * from test_table", **kwargs), ]: with testing.db.connect() as bind: with testing.expect_deprecated_20( "The .*bind argument is deprecated"): e = elem(bind=bind) assert e.bind is bind
def test_bind_close_conn(self): e = testing.db conn = e.connect() with testing.expect_deprecated_20( r"The Connection.connect\(\) function/method is considered", r"The .close\(\) method on a so-called 'branched' connection is " r"deprecated as of 1.4, as are 'branched' connections overall, " r"and will be removed in a future release.", ): with conn.connect() as c2: assert not c2.closed assert not conn.closed assert c2.closed
def test_ok(self): class Foo(object): __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)
def test_bound_cls_registry_decorated(self): reg = registry(_bind=testing.db) @reg.mapped class User(object): __tablename__ = "user" id = Column(Integer, primary_key=True) s = Session() with testing.expect_deprecated_20( "This Session located a target engine via bound metadata" ): is_(s.get_bind(User), testing.db)
def test_ddl_execute(self): engine = create_engine("sqlite:///") cx = engine.connect() table = self.users ddl = DDL("SELECT 1") eng_msg = r"The Engine.execute\(\) method is considered legacy" ddl_msg = r"The DDL.execute\(\) method is considered legacy" for spec in ( (engine.execute, ddl, eng_msg), (engine.execute, ddl, table, eng_msg), (ddl.execute, engine, ddl_msg), (ddl.execute, engine, table, ddl_msg), (ddl.execute, cx, ddl_msg), (ddl.execute, cx, table, ddl_msg), ): fn = spec[0] arg = spec[1:-1] warning = spec[-1] with testing.expect_deprecated_20(warning): r = fn(*arg) eq_(list(r), [(1,)]) for fn, kw in ((ddl.execute, {}), (ddl.execute, dict(target=table))): with testing.expect_deprecated_20(ddl_msg): assert_raises(exc.UnboundExecutionError, fn, **kw) for bind in engine, cx: ddl.bind = bind for fn, kw in ( (ddl.execute, {}), (ddl.execute, dict(target=table)), ): with testing.expect_deprecated_20(ddl_msg): r = fn(**kw) eq_(list(r), [(1,)])
def test_single_scalar(self, connection): users = self.tables.users_autoinc with testing.expect_deprecated_20( r"The connection.execute\(\) method in " "SQLAlchemy 2.0 will accept parameters as a single "): # TODO: I'm not even sure what this exec format is or how # it worked if at all connection.execute(users.insert(), "some name") eq_( connection.execute(select(users).order_by(users.c.user_id)).all(), [(1, None)], )
def test_bound_declarative_base(self): with testing.expect_deprecated( "The ``bind`` argument to declarative_base" ): Base = declarative_base(testing.db) class User(Base): __tablename__ = "user" id = Column(Integer, primary_key=True) s = Session() with testing.expect_deprecated_20( "This Session located a target engine via bound metadata" ): is_(s.get_bind(User), testing.db)
def test_branched_invalidate_parent_to_branch(self): with self.engine.connect() as c1: with testing.expect_deprecated_20( r"The Connection.connect\(\) method is considered legacy"): c1_branch = c1.connect() eq_(c1_branch.execute(select(1)).scalar(), 1) self.engine.test_shutdown() _assert_invalidated(c1.execute, select(1)) assert c1.invalidated assert c1_branch.invalidated c1._revalidate_connection() assert not c1.invalidated assert not c1_branch.invalidated
def callback(barrier): Session = sessionmaker(testing.db) def txn_body(session): accounts = list( session.query(Account).filter(Account.acct.in_((1, 2))).order_by(Account.acct) ) barrier() if accounts[0].balance > accounts[1].balance: accounts[0].balance -= 100 accounts[1].balance += 100 else: accounts[0].balance += 100 accounts[1].balance -= 100 with testing.expect_deprecated_20("The Session.autocommit parameter is deprecated"): run_transaction(Session, txn_body)
def test_single_entity_flag_is_legacy_w_future(self): Data = self.classes.Data sess = Session(testing.db, future=True) # flag has no effect b1 = Bundle("b1", Data.d1, Data.d2, single_entity=True) 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() eq_( rows, [(("d3d1", "d3d2"), ), (("d4d1", "d4d2"), ), (("d5d1", "d5d2"), )], )
def test_positional_dicts(self, connection): users = self.tables.users with testing.expect_deprecated_20( r"The connection.execute\(\) method in " "SQLAlchemy 2.0 will accept parameters as a single " ): connection.execute( users.insert(), {"user_id": 5, "user_name": "some name"}, {"user_id": 6, "user_name": "some other name"}, ) eq_( connection.execute(select(users).order_by(users.c.user_id)).all(), [(5, "some name"), (6, "some other name")], )
def test_branched_invalidate_branch_to_parent(self): with self.engine.connect() as c1: with patch.object(self.engine.pool, "logger") as logger: with testing.expect_deprecated_20( r"The Connection.connect\(\) method is considered legacy" ): c1_branch = c1.connect() eq_(c1_branch.execute(select(1)).scalar(), 1) self.engine.test_shutdown() _assert_invalidated(c1_branch.execute, select(1)) assert c1.invalidated assert c1_branch.invalidated c1_branch._revalidate_connection() assert not c1.invalidated assert not c1_branch.invalidated assert "Invalidate connection" in logger.mock_calls[0][1][0]
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")
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_deprecate_databases(self): with testing.expect_deprecated_20( "The `database` package is deprecated and will be removed in v2.0 " ): import_("sqlalchemy.databases")
def _string_deprecation_expect(): return testing.expect_deprecated_20( r"Passing a string to Connection.execute\(\) is deprecated " r"and will be removed in version 2.0")
def define_tables(cls, metadata): global Table1, Table1B, Table2, Table3, Data table1 = Table( "table1", metadata, Column( "id", Integer, primary_key=True, test_needs_autoincrement=True ), Column( "related_id", Integer, ForeignKey("table1.id"), nullable=True ), Column("type", String(30)), Column("name", String(30)), ) table2 = Table( "table2", metadata, Column("id", Integer, ForeignKey("table1.id"), primary_key=True), ) table3 = Table( "table3", metadata, Column("id", Integer, ForeignKey("table1.id"), primary_key=True), ) data = Table( "data", metadata, Column( "id", Integer, primary_key=True, test_needs_autoincrement=True ), Column("node_id", Integer, ForeignKey("table1.id")), Column("data", String(30)), ) # 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(object): def __init__(self, name, data=None): self.name = name if data is not None: self.data = data def __repr__(self): return "%s(%s, %s, %s)" % ( self.__class__.__name__, self.id, repr(str(self.name)), repr(self.data), ) class Table1B(Table1): pass class Table2(Table1): pass class Table3(Table1): pass class Data(object): def __init__(self, data): self.data = data def __repr__(self): return "%s(%s, %s)" % ( self.__class__.__name__, self.id, repr(str(self.data)), ) try: # this is how the mapping used to work. ensure that this raises an # error now table1_mapper = mapper( 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(mapper(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 # EagerLoader raises the "self-referential" # exception now. since eager loading would never work for that # relationship anyway, its better that the user # gets an exception instead of it silently not eager loading. # NOTE: using "nxt" instead of "next" to avoid 2to3 turning it into # __next__() for some reason. table1_mapper = mapper( Table1, table1, # select_table=join, polymorphic_on=table1.c.type, polymorphic_identity="table1", properties={ "nxt": relationship( Table1, backref=backref( "prev", remote_side=table1.c.id, uselist=False ), uselist=False, primaryjoin=table1.c.id == table1.c.related_id, ), "data": relationship( mapper(Data, data), lazy="joined", order_by=data.c.id ), }, ) mapper(Table1B, inherits=table1_mapper, polymorphic_identity="table1b") mapper( Table2, table2, inherits=table1_mapper, polymorphic_identity="table2", ) mapper( Table3, table3, inherits=table1_mapper, polymorphic_identity="table3", ) configure_mappers() assert table1_mapper.primary_key == ( table1.c.id, ), table1_mapper.primary_key