コード例 #1
0
    def test_limit_offset_for_update(self, metadata, connection):
        # oracle can't actually do the ROWNUM thing with FOR UPDATE
        # very well.

        t = Table(
            "t1",
            metadata,
            Column("id", Integer, primary_key=True),
            Column("data", Integer),
        )
        metadata.create_all(connection)

        connection.execute(
            t.insert(),
            [
                {
                    "id": 1,
                    "data": 1
                },
                {
                    "id": 2,
                    "data": 7
                },
                {
                    "id": 3,
                    "data": 12
                },
                {
                    "id": 4,
                    "data": 15
                },
                {
                    "id": 5,
                    "data": 32
                },
            ],
        )

        # here, we can't use ORDER BY.
        # as of #8221, this fails also.  limit w/o order by is useless
        # in any case.
        stmt = t.select().with_for_update().limit(2)
        if testing.against("oracle>=12"):
            with expect_raises_message(exc.DatabaseError, "ORA-02014"):
                connection.execute(stmt).fetchall()
        else:
            eq_(
                connection.execute(stmt).fetchall(),
                [(1, 1), (2, 7)],
            )

        # here, its impossible.  But we'd prefer it to raise ORA-02014
        # instead of issuing a syntax error.
        with expect_raises_message(exc.DatabaseError, "ORA-02014"):
            connection.execute(t.select().with_for_update().limit(2).offset(3))
コード例 #2
0
    def test_abs_concrete_extension_warn_for_overlap(self):
        class Employee(AbstractConcreteBase, Base, fixtures.ComparableEntity):
            name = Column(String(50))
            __mapper_args__ = {
                "polymorphic_identity": "employee",
                "concrete": True,
            }

        class Manager(Employee):
            __tablename__ = "manager"
            employee_id = Column(Integer,
                                 primary_key=True,
                                 test_needs_autoincrement=True)
            type = Column(String(50))
            __mapper_args__ = {
                "polymorphic_identity": "manager",
                "concrete": True,
            }

        with expect_raises_message(
                sa_exc.InvalidRequestError,
                "Polymorphic union can't use 'type' as the discriminator "
                "column due to mapped column "
                r"Column\('type', String\(length=50\), table=<manager>\); "
                "please "
                "apply the 'typecolname' argument; this is available on "
                "ConcreteBase as '_concrete_discriminator_name'",
        ):
            configure_mappers()
コード例 #3
0
    def test_no_order_by_text(self):
        stmt = select(text("foo")).order_by("foo")

        with expect_raises_message(
                exc.CompileError,
                r"Can't resolve label reference for ORDER BY / GROUP BY / ",
        ):
            stmt.compile()
コード例 #4
0
    def test_star_must_be_alone(self):
        self._downgrade_fixture()
        User = self.classes.User

        with expect_raises_message(
                sa.exc.ArgumentError,
                "Wildcard token cannot be followed by another entity",
        ):
            subqueryload("*", User.addresses)
コード例 #5
0
ファイル: test_dialect.py プロジェクト: kkirsche/sqlalchemy
    def test_minimum_version(self):
        with expect_raises_message(
                exc.InvalidRequestError,
                "oracledb version 1 and above are supported",
        ):
            oracledb.OracleDialect_oracledb(dbapi=Mock(version="0.1.5"))

        dialect = oracledb.OracleDialect_oracledb(dbapi=Mock(version="7.1.0"))
        eq_(dialect.oracledb_ver, (7, 1, 0))
コード例 #6
0
ファイル: test_dialect.py プロジェクト: kkirsche/sqlalchemy
    def test_minimum_version(self):
        with expect_raises_message(
                exc.InvalidRequestError,
                "cx_Oracle version 7 and above are supported",
        ):
            cx_oracle.OracleDialect_cx_oracle(dbapi=Mock(version="5.1.5"))

        dialect = cx_oracle.OracleDialect_cx_oracle(dbapi=Mock(
            version="7.1.0"))
        eq_(dialect.cx_oracle_ver, (7, 1, 0))
コード例 #7
0
    def test_star_cant_be_followed(self):
        self._downgrade_fixture()
        User = self.classes.User
        Order = self.classes.Order

        with expect_raises_message(
                sa.exc.ArgumentError,
                "Wildcard token cannot be followed by another entity",
        ):
            subqueryload(User.addresses).joinedload("*").selectinload(
                Order.items)
コード例 #8
0
    def test_custom_op_no_impl(self):
        """test #3162"""

        User = self.classes.User

        with expect_raises_message(
                evaluator.UnevaluatableError,
                r"Custom operator '\^\^' can't be evaluated in "
                "Python unless it specifies",
        ):
            compiler.process(User.name.op("^^")("bar"))
コード例 #9
0
    def test_no_out_params_w_returning(self, connection, metadata):
        t = Table("t", metadata, Column("x", Integer), Column("y", Integer))
        metadata.create_all(connection)
        stmt = (t.insert().values(x=5, y=10).returning(
            outparam("my_param", Integer), t.c.x))

        with expect_raises_message(
                exc.InvalidRequestError,
                r"Using explicit outparam\(\) objects with "
                r"UpdateBase.returning\(\) in the same Core DML statement "
                "is not supported in the Oracle dialect.",
        ):
            connection.execute(stmt)
コード例 #10
0
    def test_implicit_returning_engine_parameter(self, implicit_returning):
        if implicit_returning is None:
            e = engines.testing_engine()
        else:
            with assertions.expect_deprecated(ce_implicit_returning):
                e = engines.testing_engine(
                    options={"implicit_returning": implicit_returning})

        if implicit_returning is None:
            eq_(
                e.dialect.implicit_returning,
                testing.db.dialect.implicit_returning,
            )
        else:
            eq_(e.dialect.implicit_returning, implicit_returning)

        t = Table(
            "t",
            MetaData(),
            Column("id", Integer, primary_key=True),
            Column("data", String(50)),
        )

        t2 = Table(
            "t",
            MetaData(),
            Column("id", Integer, primary_key=True),
            Column("data", String(50)),
            implicit_returning=False,
        )

        with e.connect() as conn:
            stmt = insert(t).values(data="data")

            if implicit_returning:
                if not testing.requires.returning.enabled:
                    with expect_raises_message(exc.CompileError,
                                               "RETURNING is not supported"):
                        stmt.compile(conn)
                else:
                    eq_(stmt.compile(conn).implicit_returning, [t.c.id])
            elif (implicit_returning is None
                  and testing.db.dialect.implicit_returning):
                eq_(stmt.compile(conn).implicit_returning, [t.c.id])
            else:
                eq_(stmt.compile(conn).implicit_returning, [])

            # table setting it to False disables it
            stmt2 = insert(t2).values(data="data")
            eq_(stmt2.compile(conn).implicit_returning, [])
コード例 #11
0
    def test_engine_from_config_future_false_raises(self):
        dbapi = mock_dbapi

        config = {
            "sqlalchemy.url": "postgresql+psycopg2://scott:tiger@somehost/test"
            "?fooz=somevalue",
            "sqlalchemy.future": "false",
        }

        with expect_raises_message(
            exc.ArgumentError,
            r"The 'future' parameter passed to create_engine\(\) "
            r"may only be set to True.",
        ):
            engine_from_config(config, module=dbapi, _initialize=False)
コード例 #12
0
    def test_selectinload_w_joinedload_after_base_target_fails(
            self, use_of_type):
        A, B, C = self.classes("A", "B", "C")

        s = Session(testing.db)
        partitioned_b = self.partitioned_b

        if use_of_type:
            opt = selectinload(
                A.partitioned_bs.of_type(partitioned_b)).joinedload(B.cs)
        else:
            opt = selectinload(A.partitioned_bs).joinedload(B.cs)

        q = s.query(A).options(opt)

        with expect_raises_message(
                exc.ArgumentError,
                r'Attribute "B.cs" does not link from element "aliased\(B\)"',
        ):
            q._compile_context()
コード例 #13
0
    def test_no_star_orm_combinations(self, exprtype, testcase):
        """test for #8235"""
        User = self.classes.User

        if exprtype == "plain":
            star = "*"
        elif exprtype == "text":
            star = text("*")
        elif exprtype == "literal_column":
            star = literal_column("*")
        else:
            assert False

        args = testing.resolve_lambda(testcase, User=User, star=star)
        stmt = select(*args).select_from(User)

        s = fixture_session()

        with expect_raises_message(
                exc.CompileError,
                r"Can't generate ORM query that includes multiple expressions "
                r"at the same time as '\*';",
        ):
            s.execute(stmt)
コード例 #14
0
    def test_subclass_loadattr(self, first_option, second_option,
                               second_argument, expect_load):
        Parent, Entity, SubEntity = self.classes("Parent", "Entity",
                                                 "SubEntity")

        stmt = select(Parent)

        will_lazyload = first_option in (defaultload, lazyload)

        if second_argument == "name":
            second_argument = SubEntity.name
            opt = first_option(Parent.entity.of_type(SubEntity))
        elif second_argument == "id":
            opt = first_option(Parent.entity)
            second_argument = Entity.id
        else:
            opt = first_option(Parent.entity)

        if second_option is None:
            sub_opt = opt
        elif second_option == "raise":
            sub_opt = opt.defer(second_argument, raiseload=True)
        else:
            sub_opt = getattr(opt, second_option)(second_argument)

        stmt = stmt.options(sub_opt)

        session = fixture_session()
        result = session.execute(stmt).scalars()

        parent_obj = result.first()

        entity_id = parent_obj.__dict__["entity_id"]

        with assertsql.assert_engine(testing.db) as asserter_:
            if expect_load:
                eq_(parent_obj.entity.name, "some name")
            else:
                with expect_raises_message(
                        exc.InvalidRequestError,
                        "'SubEntity.name' is not available due to raiseload=True",
                ):
                    parent_obj.entity.name

        expected = []

        if will_lazyload:
            expected.append(
                CompiledSQL(
                    "SELECT entity.id AS entity_id, "
                    "entity.type AS entity_type FROM entity "
                    "WHERE entity.id = :pk_1",
                    [{
                        "pk_1": entity_id
                    }],
                ))

        if second_option in ("load_only", None) or (
                second_option == "undefer"
                and first_option in (defaultload, lazyload)):
            # load will be a mapper optimized load for the name alone
            expected.append(
                CompiledSQL(
                    "SELECT sub_entity.name AS sub_entity_name "
                    "FROM sub_entity "
                    "WHERE :param_1 = sub_entity.id",
                    [{
                        "param_1": entity_id
                    }],
                ))
        elif second_option == "defer":
            # load will be a deferred load.  this is because the explicit
            # call to the deferred load put a deferred loader on the attribute
            expected.append(
                CompiledSQL(
                    "SELECT sub_entity.name AS sub_entity_name "
                    "FROM sub_entity "
                    "WHERE :param_1 = sub_entity.id",
                    [{
                        "param_1": entity_id
                    }],
                ))

        asserter_.assert_(*expected)
コード例 #15
0
        async def run_test(subject, trans_on_subject, execute_on_subject):
            async with subject.begin() as trans:

                if begin_nested:
                    if not config.requirements.savepoints.enabled:
                        config.skip_test("savepoints not enabled")
                    if execute_on_subject:
                        nested_trans = subject.begin_nested()
                    else:
                        nested_trans = trans.begin_nested()

                    async with nested_trans:
                        if execute_on_subject:
                            await subject.execute(t.insert(), {"data": 10})
                        else:
                            await trans.execute(t.insert(), {"data": 10})

                        # for nested trans, we always commit/rollback on the
                        # "nested trans" object itself.
                        # only Session(future=False) will affect savepoint
                        # transaction for session.commit/rollback

                        if rollback:
                            await nested_trans.rollback()
                        else:
                            await nested_trans.commit()

                        if run_second_execute:
                            with assertions.expect_raises_message(
                                    exc.InvalidRequestError,
                                    "Can't operate on closed transaction "
                                    "inside context manager.  Please complete the "
                                    "context manager "
                                    "before emitting further commands.",
                            ):
                                if execute_on_subject:
                                    await subject.execute(
                                        t.insert(), {"data": 12})
                                else:
                                    await trans.execute(
                                        t.insert(), {"data": 12})

                    # outside the nested trans block, but still inside the
                    # transaction block, we can run SQL, and it will be
                    # committed
                    if execute_on_subject:
                        await subject.execute(t.insert(), {"data": 14})
                    else:
                        await trans.execute(t.insert(), {"data": 14})

                else:
                    if execute_on_subject:
                        await subject.execute(t.insert(), {"data": 10})
                    else:
                        await trans.execute(t.insert(), {"data": 10})

                    if trans_on_subject:
                        if rollback:
                            await subject.rollback()
                        else:
                            await subject.commit()
                    else:
                        if rollback:
                            await trans.rollback()
                        else:
                            await trans.commit()

                    if run_second_execute:
                        with assertions.expect_raises_message(
                                exc.InvalidRequestError,
                                "Can't operate on closed transaction inside "
                                "context "
                                "manager.  Please complete the context manager "
                                "before emitting further commands.",
                        ):
                            if execute_on_subject:
                                await subject.execute(t.insert(), {"data": 12})
                            else:
                                await trans.execute(t.insert(), {"data": 12})

            expected_committed = 0
            if begin_nested:
                # begin_nested variant, we inserted a row after the nested
                # block
                expected_committed += 1
            if not rollback:
                # not rollback variant, our row inserted in the target
                # block itself would be committed
                expected_committed += 1

            if execute_on_subject:
                eq_(
                    await subject.scalar(select(func.count()).select_from(t)),
                    expected_committed,
                )
            else:
                with subject.connect() as conn:
                    eq_(
                        await conn.scalar(select(func.count()).select_from(t)),
                        expected_committed,
                    )
コード例 #16
0
    def test_query_dict_immutable(self, urlstr):
        url_obj = url.make_url(urlstr)

        with expect_raises_message(TypeError, ".*immutable"):
            url_obj.query["foo"] = "hoho"
コード例 #17
0
 def test_determine_local_remote_pairs_o2m_overlap_func_warning(self):
     with expect_raises_message(exc.ArgumentError,
                                "Could not locate any relevant"):
         self._assert_non_simple_warning(
             self._join_fixture_m2o_sub_to_joined_sub_func)