Example #1
0
    def test_unsupported_cast_literal_bind(self):
        expr = cast(column("foo", Integer) + 5, Float)

        with expect_warnings("Datatype FLOAT does not support CAST on MySQL;"):
            self.assert_compile(expr, "(foo + 5)", literal_binds=True)

        dialect = mysql.MySQLDialect()
        dialect.server_version_info = (3, 9, 8)
        with expect_warnings("Current MySQL version does not support CAST"):
            eq_(
                str(
                    expr.compile(dialect=dialect,
                                 compile_kwargs={"literal_binds": True})),
                "(foo + 5)",
            )
    def test_foreignkey_missing_insert(self):
        Table("t1", self.metadata, Column("id", Integer, primary_key=True))
        t2 = Table(
            "t2",
            self.metadata,
            Column("id", Integer, ForeignKey("t1.id"), primary_key=True),
        )
        self.metadata.create_all()

        # want to ensure that "null value in column "id" violates not-
        # null constraint" is raised (IntegrityError on psycoopg2, but
        # ProgrammingError on pg8000), and not "ProgrammingError:
        # (ProgrammingError) relationship "t2_id_seq" does not exist".
        # the latter corresponds to autoincrement behavior, which is not
        # the case here due to the foreign key.

        for eng in [
                engines.testing_engine(options={"implicit_returning": False}),
                engines.testing_engine(options={"implicit_returning": True}),
        ]:
            with expect_warnings(
                    ".*has no Python-side or server-side default.*"):
                assert_raises(
                    (exc.IntegrityError, exc.ProgrammingError),
                    eng.execute,
                    t2.insert(),
                )
Example #3
0
    def test_no_default_isolation_level(self):
        from sqlalchemy_1_3.testing import mock

        engine = engines.testing_engine()

        real_isolation_level = testing.db.dialect.get_isolation_level

        def fake_isolation_level(connection):
            connection = mock.Mock(
                cursor=mock.Mock(
                    return_value=mock.Mock(
                        fetchone=mock.Mock(return_value=None)
                    )
                )
            )
            return real_isolation_level(connection)

        with mock.patch.object(
            engine.dialect, "get_isolation_level", fake_isolation_level
        ):
            with expect_warnings(
                "Could not retrieve transaction isolation level for MySQL "
                "connection."
            ):
                engine.connect()
Example #4
0
    def test_skip_not_describable(self):
        @event.listens_for(self.metadata, "before_drop")
        def cleanup(*arg, **kw):
            with testing.db.connect() as conn:
                conn.execute("DROP TABLE IF EXISTS test_t1")
                conn.execute("DROP TABLE IF EXISTS test_t2")
                conn.execute("DROP VIEW IF EXISTS test_v")

        with testing.db.connect() as conn:
            conn.execute("CREATE TABLE test_t1 (id INTEGER)")
            conn.execute("CREATE TABLE test_t2 (id INTEGER)")
            conn.execute("CREATE VIEW test_v AS SELECT id FROM test_t1")
            conn.execute("DROP TABLE test_t1")

            m = MetaData()
            with expect_warnings(
                    "Skipping .* Table or view named .?test_v.? could not be "
                    "reflected: .* references invalid table"):
                m.reflect(views=True, bind=conn)
            eq_(m.tables["test_t2"].name, "test_t2")

            assert_raises_message(
                exc.UnreflectableTableError,
                "references invalid table",
                Table,
                "test_v",
                MetaData(),
                autoload_with=conn,
            )
Example #5
0
    def test_reconnect_on_reentrant_plus_closewresult(self):
        conn = self.db.connect(close_with_result=True)

        self.dbapi.shutdown("rollback")

        # raises error
        with expect_warnings(
                "An exception has occurred during handling .*"
                "something broke on execute but we didn't lose the connection",
                py2konly=True,
        ):
            assert_raises_message(
                tsa.exc.DBAPIError,
                "Lost the DB connection on rollback",
                conn.execute,
                select([1]),
            )

        assert conn.closed
        assert conn.invalidated

        assert_raises_message(
            tsa.exc.StatementError,
            "This Connection is closed",
            conn.execute,
            select([1]),
        )
    def test_trans_reset_agent_broken_ensure(self):
        eng = testing_engine()
        conn = eng.connect()
        trans = conn.begin()
        assert conn.connection._reset_agent is trans
        trans.is_active = False

        with expect_warnings("Reset agent is not active"):
            conn.close()
Example #7
0
 def test_no_cast_pre_4(self):
     self.assert_compile(cast(Column("foo", Integer), String),
                         "CAST(foo AS CHAR)")
     dialect = mysql.dialect()
     dialect.server_version_info = (3, 2, 3)
     with expect_warnings("Current MySQL version does not support CAST;"):
         self.assert_compile(cast(Column("foo", Integer), String),
                             "foo",
                             dialect=dialect)
Example #8
0
 def test_cast_grouped_expression_pre_4(self):
     dialect = mysql.dialect()
     dialect.server_version_info = (3, 2, 3)
     with expect_warnings("Current MySQL version does not support CAST;"):
         self.assert_compile(
             cast(sql.column("x") + sql.column("y"), Integer),
             "(x + y)",
             dialect=dialect,
         )
    def test_trans_commit_reset_agent_broken_ensure(self):
        eng = testing_engine(options={"pool_reset_on_return": "commit"})
        conn = eng.connect()
        trans = conn.begin()
        assert conn.connection._reset_agent is trans
        trans.is_active = False

        with expect_warnings("Reset agent is not active"):
            conn.close()
Example #10
0
 def test_anticipate_no_pk_lower_case_table(self):
     t = table(
         "t",
         Column("id", Integer, primary_key=True, autoincrement=False),
         Column("notpk", String(10), nullable=True),
     )
     with expect_warnings("Column 't.id' is marked as a member.*"
                          "may not store NULL.$"):
         self.assert_compile(t.insert(),
                             "INSERT INTO t () VALUES ()",
                             params={})
Example #11
0
 def test_mariadb_check_warning(self, expect_, version):
     dialect = mysql.dialect()
     dialect.server_version_info = version
     if expect_:
         with expect_warnings(
             ".*before 10.2.9 has known issues regarding "
             "CHECK constraints"
         ):
             dialect._warn_for_known_db_issues()
     else:
         dialect._warn_for_known_db_issues()
Example #12
0
    def test_warning_skip_locked(self, connection):

        stuff = self.tables.stuff

        stmt = stuff.select().with_for_update(skip_locked=True)

        with expect_warnings(
            "SKIP LOCKED ignored on non-supporting MariaDB backend. "
            "This will raise an error in SQLAlchemy 1.4."
        ):

            connection.execute(stmt).fetchall()
Example #13
0
 def test_anticipate_no_pk_non_composite_pk(self):
     t = Table(
         "t",
         MetaData(),
         Column("x", Integer, primary_key=True, autoincrement=False),
         Column("q", Integer),
     )
     with expect_warnings("Column 't.x' is marked as a member.*"
                          "may not store NULL.$"):
         self.assert_compile(t.insert(),
                             "INSERT INTO t (q) VALUES (:q)",
                             params={"q": 5})
Example #14
0
    def test_anticipate_no_pk_composite_pk(self):
        t = Table(
            "t",
            MetaData(),
            Column("x", Integer, primary_key=True),
            Column("y", Integer, primary_key=True),
        )

        with expect_warnings("Column 't.y' is marked as a member.*"
                             "Note that as of SQLAlchemy 1.1,"):
            self.assert_compile(t.insert(),
                                "INSERT INTO t (x) VALUES (:x)",
                                params={"x": 5})
Example #15
0
    def test_ensure_is_disconnect_gets_connection(self):
        def is_disconnect(e, conn, cursor):
            # connection is still present
            assert conn.connection is not None
            # the error usually occurs on connection.cursor(),
            # though MySQLdb we get a non-working cursor.
            # assert cursor is None

        self.engine.dialect.is_disconnect = is_disconnect
        conn = self.engine.connect()
        self.engine.test_shutdown()
        with expect_warnings("An exception has occurred during handling .*",
                             py2konly=True):
            assert_raises(tsa.exc.DBAPIError, conn.execute, select([1]))
Example #16
0
    def test_older_cx_oracle_warning(self, cx_Oracle, cx_oracle_type):
        cx_Oracle.version = "6.3"

        ignore_dialect = cx_oracle.dialect(dbapi=cx_Oracle,
                                           encoding_errors="ignore")
        ignore_outputhandler = (
            ignore_dialect._generate_connection_outputtype_handler())

        cursor = mock.Mock()

        with testing.expect_warnings(
                r"cx_oracle version \(6, 3\) does not support encodingErrors"):
            ignore_outputhandler(cursor, "foo", cx_oracle_type, None, None,
                                 None)
Example #17
0
    def test_computed_update_warning(self):
        test = self.tables.test
        with testing.db.connect() as conn:
            conn.execute(test.insert(), {"id": 1, "foo": 5})

            with testing.expect_warnings(
                    "Computed columns don't work with Oracle UPDATE"):
                result = conn.execute(
                    test.update().values(foo=10).return_defaults())

                # returns the *old* value
                eq_(result.returned_defaults, (47, ))

            eq_(conn.scalar(select([test.c.bar])), 52)
    def test_eq_non_path(self):
        umapper = inspect(self.classes.User)
        amapper = inspect(self.classes.Address)
        u_alias = inspect(aliased(self.classes.User))
        p1 = PathRegistry.coerce((umapper,))
        p2 = PathRegistry.coerce((umapper, umapper.attrs.addresses))
        p3 = PathRegistry.coerce((u_alias, umapper.attrs.addresses))
        p4 = PathRegistry.coerce((u_alias, umapper.attrs.addresses, amapper))
        p5 = PathRegistry.coerce((u_alias,)).token(":*")

        non_object = 54.1432

        for obj in [p1, p2, p3, p4, p5]:
            with expect_warnings(
                "Comparison of PathRegistry to "
                "<.* 'float'> is not supported"
            ):
                is_(obj == non_object, False)

            with expect_warnings(
                "Comparison of PathRegistry to "
                "<.* 'float'> is not supported"
            ):
                is_(obj != non_object, True)
Example #19
0
    def test_non_autoincrement(self, connection):
        # sqlite INT primary keys can be non-unique! (only for ints)
        nonai = Table(
            "nonaitest",
            self.metadata,
            Column("id", Integer, autoincrement=False, primary_key=True),
            Column("data", String(20)),
        )
        nonai.create(connection)

        # just testing SQLite for now, it passes
        with expect_warnings(".*has no Python-side or server-side default.*"):
            # postgresql + mysql strict will fail on first row,
            # mysql in legacy mode fails on second row
            connection.execute(nonai.insert(), dict(data="row 1"))
            connection.execute(nonai.insert(), dict(data="row 2"))
    def test_returning_update_computed_warning(self):
        m = MetaData()
        t1 = Table(
            "t1",
            m,
            Column("id", Integer, primary_key=True),
            Column("foo", Integer),
            Column("bar", Integer, Computed("foo + 42")),
        )

        with testing.expect_warnings(
                "Computed columns don't work with Oracle UPDATE"):
            self.assert_compile(
                t1.update().values(id=1, foo=5).returning(t1.c.bar),
                "UPDATE t1 SET id=:id, foo=:foo RETURNING t1.bar INTO :ret_0",
            )
Example #21
0
 def test_anticipate_no_pk_non_composite_pk_implicit_returning(self):
     t = Table(
         "t",
         MetaData(),
         Column("x", Integer, primary_key=True, autoincrement=False),
         Column("q", Integer),
     )
     d = postgresql.dialect()
     d.implicit_returning = True
     with expect_warnings("Column 't.x' is marked as a member.*"
                          "may not store NULL.$"):
         self.assert_compile(
             t.insert(),
             "INSERT INTO t (q) VALUES (%(q)s)",
             params={"q": 5},
             dialect=d,
         )
Example #22
0
 def test_anticipate_no_pk_composite_pk_prefetch(self):
     t = Table(
         "t",
         MetaData(),
         Column("x", Integer, primary_key=True),
         Column("y", Integer, primary_key=True),
     )
     d = postgresql.dialect()
     d.implicit_returning = False
     with expect_warnings("Column 't.y' is marked as a member.*"
                          "Note that as of SQLAlchemy 1.1,"):
         self.assert_compile(
             t.insert(),
             "INSERT INTO t (x) VALUES (%(x)s)",
             params={"x": 5},
             dialect=d,
         )
Example #23
0
    def test_no_show_variables(self):
        from sqlalchemy_1_3.testing import mock

        engine = engines.testing_engine()

        def my_execute(self, statement, *args, **kw):
            if statement.startswith("SHOW VARIABLES"):
                statement = "SELECT 1 FROM DUAL WHERE 1=0"
            return real_exec(self, statement, *args, **kw)

        real_exec = engine._connection_cls._execute_text
        with mock.patch.object(
            engine._connection_cls, "_execute_text", my_execute
        ):
            with expect_warnings(
                "Could not retrieve SQL_MODE; please ensure the "
                "MySQL user has permissions to SHOW VARIABLES"
            ):
                engine.connect()
    def test_savepoint_release_fails_warning(self):
        with testing.db.connect() as connection:
            connection.begin()

            with expect_warnings(
                "An exception has occurred during handling of a previous "
                "exception.  The previous exception "
                r"is:.*..SQL\:.*RELEASE SAVEPOINT"
            ):

                def go():
                    with connection.begin_nested() as savepoint:
                        connection.dialect.do_release_savepoint(
                            connection, savepoint._savepoint
                        )

                assert_raises_message(
                    exc.DBAPIError, r".*SQL\:.*ROLLBACK TO SAVEPOINT", go
                )
    def test_warning_in_transaction(self):
        eng = testing_engine()
        c1 = eng.connect()
        with expect_warnings(
            "Connection is already established with a Transaction; "
            "setting isolation_level may implicitly rollback or commit "
            "the existing transaction, or have no effect until next "
            "transaction"
        ):
            with c1.begin():
                c1 = c1.execution_options(
                    isolation_level=self._non_default_isolation_level()
                )

                eq_(
                    eng.dialect.get_isolation_level(c1.connection),
                    self._non_default_isolation_level(),
                )
        # stays outside of transaction
        eq_(
            eng.dialect.get_isolation_level(c1.connection),
            self._non_default_isolation_level(),
        )
Example #26
0
    def test_mariadb_for_update(self):
        dialect = mysql.dialect()
        dialect.server_version_info = (10, 1, 1, "MariaDB")

        table1 = table("mytable", column("myid"), column("name"),
                       column("description"))

        self.assert_compile(
            table1.select(table1.c.myid == 7).with_for_update(of=table1),
            "SELECT mytable.myid, mytable.name, mytable.description "
            "FROM mytable WHERE mytable.myid = %s "
            "FOR UPDATE",
            dialect=dialect,
        )

        with testing.expect_warnings("SKIP LOCKED ignored on non-supporting"):
            self.assert_compile(
                table1.select(table1.c.myid == 7).with_for_update(
                    skip_locked=True),
                "SELECT mytable.myid, mytable.name, mytable.description "
                "FROM mytable WHERE mytable.myid = %s "
                "FOR UPDATE",
                dialect=dialect,
            )
Example #27
0
    def test_reconnect_on_reentrant(self):
        conn = self.db.connect()

        conn.execute(select([1]))

        assert len(self.dbapi.connections) == 1

        self.dbapi.shutdown("rollback")

        # raises error
        with expect_warnings(
                "An exception has occurred during handling .*"
                "something broke on execute but we didn't lose the connection",
                py2konly=True,
        ):
            assert_raises_message(
                tsa.exc.DBAPIError,
                "Lost the DB connection on rollback",
                conn.execute,
                select([1]),
            )

        assert not conn.closed
        assert conn.invalidated
    def test_replace_function_case_sensitive(self):
        reg = functions._registry["_default"]
        cs_reg = functions._case_sensitive_registry["_default"]

        class replaceable_func(GenericFunction):
            type = Integer
            identifier = "REPLACEABLE_FUNC"

        assert isinstance(func.REPLACEABLE_FUNC().type, Integer)
        assert isinstance(func.Replaceable_Func().type, Integer)
        assert isinstance(func.RePlAcEaBlE_fUnC().type, Integer)
        assert isinstance(func.replaceable_func().type, Integer)

        in_("replaceable_func", reg)
        not_in("REPLACEABLE_FUNC", reg)
        not_in("Replaceable_Func", reg)
        in_("replaceable_func", cs_reg)
        eq_(set(cs_reg["replaceable_func"].keys()), set(["REPLACEABLE_FUNC"]))

        with testing.expect_deprecated(
                "GenericFunction 'Replaceable_Func' is already registered with"
                " different letter case, so the previously registered function "
                "'REPLACEABLE_FUNC' is switched into case-sensitive mode. "
                "GenericFunction objects will be fully case-insensitive in a "
                "future release.",
                regex=False,
        ):

            class Replaceable_Func(GenericFunction):
                type = DateTime
                identifier = "Replaceable_Func"

        assert isinstance(func.REPLACEABLE_FUNC().type, Integer)
        assert isinstance(func.Replaceable_Func().type, DateTime)
        assert isinstance(func.RePlAcEaBlE_fUnC().type, NullType)
        assert isinstance(func.replaceable_func().type, NullType)

        eq_(reg["replaceable_func"], functions._CASE_SENSITIVE)
        not_in("REPLACEABLE_FUNC", reg)
        not_in("Replaceable_Func", reg)
        in_("replaceable_func", cs_reg)
        eq_(
            set(cs_reg["replaceable_func"].keys()),
            set(["REPLACEABLE_FUNC", "Replaceable_Func"]),
        )

        with testing.expect_warnings(
                "The GenericFunction 'REPLACEABLE_FUNC' is already registered and "
                "is going to be overriden.",
                regex=False,
        ):

            class replaceable_func_override(GenericFunction):
                type = DateTime
                identifier = "REPLACEABLE_FUNC"

        with testing.expect_deprecated(
                "GenericFunction(s) '['REPLACEABLE_FUNC', 'Replaceable_Func']' "
                "are already registered with different letter cases and might "
                "interact with 'replaceable_func'. GenericFunction objects will "
                "be fully case-insensitive in a future release.",
                regex=False,
        ):

            class replaceable_func_lowercase(GenericFunction):
                type = String
                identifier = "replaceable_func"

        with testing.expect_warnings(
                "The GenericFunction 'Replaceable_Func' is already registered and "
                "is going to be overriden.",
                regex=False,
        ):

            class Replaceable_Func_override(GenericFunction):
                type = Integer
                identifier = "Replaceable_Func"

        assert isinstance(func.REPLACEABLE_FUNC().type, DateTime)
        assert isinstance(func.Replaceable_Func().type, Integer)
        assert isinstance(func.RePlAcEaBlE_fUnC().type, NullType)
        assert isinstance(func.replaceable_func().type, String)

        eq_(reg["replaceable_func"], functions._CASE_SENSITIVE)
        not_in("REPLACEABLE_FUNC", reg)
        not_in("Replaceable_Func", reg)
        in_("replaceable_func", cs_reg)
        eq_(
            set(cs_reg["replaceable_func"].keys()),
            set(["REPLACEABLE_FUNC", "Replaceable_Func", "replaceable_func"]),
        )
Example #29
0
    def test_unsupported_casts(self, type_, expected):

        t = sql.table("t", sql.column("col"))
        with expect_warnings("Datatype .* does not support CAST on MySQL;"):
            self.assert_compile(cast(t.c.col, type_), expected)
Example #30
0
 def test_cast_grouped_expression_non_castable(self):
     with expect_warnings("Datatype FLOAT does not support CAST on MySQL;"):
         self.assert_compile(cast(sql.column("x") + sql.column("y"), Float),
                             "(x + y)")