예제 #1
0
    def test_graceful_fetch_on_non_rows(self):
        """test that calling fetchone() etc. on a result that doesn't
        return rows fails gracefully.

        """

        # these proxies don't work with no cursor.description present.
        # so they don't apply to this test at the moment.
        # result.FullyBufferedResultProxy,
        # result.BufferedRowResultProxy,
        # result.BufferedColumnResultProxy

        users = self.tables.users

        conn = testing.db.connect()
        for meth in [
            lambda r: r.fetchone(),
            lambda r: r.fetchall(),
            lambda r: r.first(),
            lambda r: r.scalar(),
            lambda r: r.fetchmany(),
            lambda r: r._getter('user'),
            lambda r: r._has_key('user'),
        ]:
            trans = conn.begin()
            result = conn.execute(users.insert(), user_id=1)
            assert_raises_message(
                exc.ResourceClosedError,
                "This result object does not return rows. "
                "It has been closed automatically.",
                meth, result,
            )
            trans.rollback()
예제 #2
0
    def test_illegal_operations(self):
        User = self.classes.User
        Address = self.classes.Address

        s = Session()

        for q, mname in (
            (s.query(User).limit(2), r"limit\(\)"),
            (s.query(User).offset(2), r"offset\(\)"),
            (s.query(User).limit(2).offset(2), r"limit\(\)"),
            (s.query(User).order_by(User.id), r"order_by\(\)"),
            (s.query(User).group_by(User.id), r"group_by\(\)"),
            (s.query(User).distinct(), r"distinct\(\)"),
            (s.query(User).join(User.addresses),
                r"join\(\), outerjoin\(\), select_from\(\), or from_self\(\)"),
            (s.query(User).outerjoin(User.addresses),
                r"join\(\), outerjoin\(\), select_from\(\), or from_self\(\)"),
            (s.query(User).select_from(Address),
                r"join\(\), outerjoin\(\), select_from\(\), or from_self\(\)"),
            (s.query(User).from_self(),
                r"join\(\), outerjoin\(\), select_from\(\), or from_self\(\)"),
        ):
            assert_raises_message(
                exc.InvalidRequestError,
                r"Can't call Query.update\(\) or Query.delete\(\) when "
                "%s has been called" % mname,
                q.update,
                {'name': 'ed'})
            assert_raises_message(
                exc.InvalidRequestError,
                r"Can't call Query.update\(\) or Query.delete\(\) when "
                "%s has been called" % mname,
                q.delete)
예제 #3
0
 def test_set_illegal(self):
     f1 = Foo()
     assert_raises_message(
         ValueError,
         "Attribute 'data' does not accept objects",
         setattr, f1, 'data', 'foo'
     )
예제 #4
0
    def test_no_table_needs_pl(self):
        Subset = self.classes.Subset

        selectable = select([column("x"), column("y"), column("z")]).alias()
        assert_raises_message(
            sa.exc.ArgumentError, "could not assemble any primary key columns", mapper, Subset, selectable
        )
예제 #5
0
 def test_with_transaction(self):
     conn = self.engine.connect()
     trans = conn.begin()
     eq_(conn.execute(select([1])).scalar(), 1)
     assert not conn.closed
     self.engine.test_shutdown()
     _assert_invalidated(conn.execute, select([1]))
     assert not conn.closed
     assert conn.invalidated
     assert trans.is_active
     assert_raises_message(
         tsa.exc.StatementError,
         "Can't reconnect until invalid transaction is rolled back",
         conn.execute, select([1]))
     assert trans.is_active
     assert_raises_message(
         tsa.exc.InvalidRequestError,
         "Can't reconnect until invalid transaction is rolled back",
         trans.commit
     )
     assert trans.is_active
     trans.rollback()
     assert not trans.is_active
     assert conn.invalidated
     eq_(conn.execute(select([1])).scalar(), 1)
     assert not conn.invalidated
예제 #6
0
 def _assert_raises_no_join(self, fn, relname, secondary_arg,
                 *arg, **kw):
     if secondary_arg is not None:
         assert_raises_message(
             exc.NoForeignKeysError,
             "Could not determine join condition between "
             "parent/child tables on relationship %s - "
             "there are no foreign keys linking these tables "
             "via secondary table '%s'.  "
             "Ensure that referencing columns are associated "
             "with a ForeignKey "
             "or ForeignKeyConstraint, or specify 'primaryjoin' and "
             "'secondaryjoin' expressions"
             % (relname, secondary_arg),
             fn, *arg, **kw)
     else:
         assert_raises_message(
             exc.NoForeignKeysError,
             "Could not determine join condition between "
             "parent/child tables on relationship %s - "
             "there are no foreign keys linking these tables.  "
             "Ensure that referencing columns are associated "
             "with a ForeignKey "
             "or ForeignKeyConstraint, or specify a 'primaryjoin' "
             "expression."
             % (relname,),
             fn, *arg, **kw)
예제 #7
0
 def test_bitwise_required_for_empty(self):
     assert_raises_message(
         exc.ArgumentError,
         "Can't use the blank value '' in a SET without setting "
         "retrieve_as_bitwise=True",
         mysql.SET, "a", "b", ''
     )
예제 #8
0
 def test_unconsumed_names_kwargs(self):
     t = table("t", column("x"), column("y"))
     assert_raises_message(
         exc.CompileError,
         "Unconsumed column names: z",
         t.insert().values(x=5, z=5).compile,
     )
예제 #9
0
    def test_auto_detach_on_gc_session(self):
        users, User = self.tables.users, self.classes.User

        mapper(User, users)

        sess = Session()

        u1 = User(name='u1')
        sess.add(u1)
        sess.commit()

        # can't add u1 to Session,
        # already belongs to u2
        s2 = Session()
        assert_raises_message(
            sa.exc.InvalidRequestError,
            r".*is already attached to session",
            s2.add, u1
        )

        # garbage collect sess
        del sess
        gc_collect()

        # s2 lets it in now despite u1 having
        # session_key
        s2.add(u1)
        assert u1 in s2
예제 #10
0
    def test_varchar_raise(self):
        for type_ in (
            String,
            VARCHAR,
            String(),
            VARCHAR(),
            NVARCHAR(),
            Unicode,
            Unicode(),
        ):
            type_ = sqltypes.to_instance(type_)
            assert_raises_message(
                exc.CompileError,
                "VARCHAR requires a length on dialect mysql",
                type_.compile,
                dialect=mysql.dialect()
            )

            t1 = Table('sometable', MetaData(),
                Column('somecolumn', type_)
            )
            assert_raises_message(
                exc.CompileError,
                r"\(in table 'sometable', column 'somecolumn'\)\: "
                r"(?:N)?VARCHAR requires a length on dialect mysql",
                schema.CreateTable(t1).compile,
                dialect=mysql.dialect()
            )
예제 #11
0
 def test_unknown_legacy_lock_mode(self):
     User = self.classes.User
     sess = Session()
     assert_raises_message(
         exc.ArgumentError, "Unknown with_lockmode argument: 'unknown_mode'",
         sess.query(User.id).with_lockmode, 'unknown_mode'
     )
예제 #12
0
    def test_concurrent_mod_err_noexpire_on_commit(self):
        sess = self._fixture(expire_on_commit=False)

        f1 = self.classes.Foo(value='f1')
        sess.add(f1)
        sess.commit()

        # here, we're not expired overall, so no load occurs and we
        # stay without a version id, unless we've emitted
        # a SELECT for it within the flush.
        f1.value

        s2 = Session(expire_on_commit=False)
        f2 = s2.query(self.classes.Foo).first()
        f2.value = 'f2'
        s2.commit()

        f1.value = 'f3'

        assert_raises_message(
            orm.exc.StaleDataError,
            r"UPDATE statement on table 'version_table' expected to "
            r"update 1 row\(s\); 0 were matched.",
            sess.commit
        )
예제 #13
0
    def test_lobs_without_convert_many_rows(self):
        engine = testing_engine(
            options=dict(auto_convert_lobs=False, arraysize=1))
        result = engine.execute(
            "select id, data, bindata from z_test order by id")
        results = result.fetchall()

        def go():
            eq_(
                [
                    dict(
                        id=row["id"],
                        data=row["data"].read(),
                        bindata=row["bindata"].read()
                    ) for row in results
                ],
                self.data)
        # this comes from cx_Oracle because these are raw
        # cx_Oracle.Variable objects
        if testing.requires.oracle5x.enabled:
            assert_raises_message(
                testing.db.dialect.dbapi.ProgrammingError,
                "LOB variable no longer valid after subsequent fetch",
                go
            )
        else:
            go()
예제 #14
0
    def test_versioncheck(self):
        """query.with_lockmode performs a 'version check' on an already loaded instance"""

        Foo = self.classes.Foo


        s1 = self._fixture()
        f1s1 = Foo(value='f1 value')
        s1.add(f1s1)
        s1.commit()

        s2 = create_session(autocommit=False)
        f1s2 = s2.query(Foo).get(f1s1.id)
        f1s2.value='f1 new value'
        s2.commit()

        # load, version is wrong
        assert_raises_message(
                sa.orm.exc.StaleDataError,
                r"Instance .* has version id '\d+' which does not "
                r"match database-loaded version id '\d+'",
                s1.query(Foo).with_lockmode('read').get, f1s1.id
            )

        # reload it - this expires the old version first
        s1.refresh(f1s1, lockmode='read')

        # now assert version OK
        s1.query(Foo).with_lockmode('read').get(f1s1.id)

        # assert brand new load is OK too
        s1.close()
        s1.query(Foo).with_lockmode('read').get(f1s1.id)
예제 #15
0
    def test_child_row_switch_two(self):
        P = self.classes.P

        Session = sessionmaker()

        # TODO: not sure this test is
        # testing exactly what its looking for

        sess1 = Session()
        sess1.add(P(id='P1', data='P version 1'))
        sess1.commit()
        sess1.close()

        p1 = sess1.query(P).first()

        sess2 = Session()
        p2 = sess2.query(P).first()

        sess1.delete(p1)
        sess1.commit()

        # this can be removed and it still passes
        sess1.add(P(id='P1', data='P version 2'))
        sess1.commit()

        p2.data = 'P overwritten by concurrent tx'
        if testing.db.dialect.supports_sane_rowcount:
            assert_raises_message(
                orm.exc.StaleDataError,
                r"UPDATE statement on table 'p' expected to update "
                r"1 row\(s\); 0 were matched.",
                sess2.commit
            )
        else:
            sess2.commit
예제 #16
0
    def test_report_primary_error_when_rollback_fails(self):
        User, users = self.classes.User, self.tables.users

        mapper(User, users)

        session = Session(testing.db)

        with expect_warnings(".*during handling of a previous exception.*"):
            session.begin_nested()
            savepoint = session.\
                connection()._Connection__transaction._savepoint

            # force the savepoint to disappear
            session.connection().dialect.do_release_savepoint(
                session.connection(), savepoint
            )

            # now do a broken flush
            session.add_all([User(id=1), User(id=1)])

            assert_raises_message(
                sa_exc.DBAPIError,
                "ROLLBACK TO SAVEPOINT ",
                session.flush
            )
예제 #17
0
    def test_validator_multi_warning(self):
        users = self.tables.users

        class Foo(object):
            @validates("name")
            def validate_one(self, key, value):
                pass

            @validates("name")
            def validate_two(self, key, value):
                pass

        assert_raises_message(
            exc.InvalidRequestError,
            "A validation function for mapped attribute "
            "'name' on mapper Mapper|Foo|users already exists",
            mapper, Foo, users
        )

        class Bar(object):
            @validates("id")
            def validate_three(self, key, value):
                return value + 10

            @validates("id", "name")
            def validate_four(self, key, value):
                return value + "foo"

        assert_raises_message(
            exc.InvalidRequestError,
            "A validation function for mapped attribute "
            "'name' on mapper Mapper|Bar|users already exists",
            mapper, Bar, users
        )
예제 #18
0
 def test_cant_parse_datetime_message(self):
     for (typ, disp) in [(Time, "time"), (DateTime, "datetime"), (Date, "date")]:
         assert_raises_message(
             ValueError,
             "Couldn't parse %s string." % disp,
             lambda: testing.db.execute(text("select 'ASDF' as value", typemap={"value": typ})).scalar(),
         )
예제 #19
0
    def test_no_prepare_wo_twophase(self):
        sess = create_session(bind=testing.db, autocommit=False)

        assert_raises_message(sa_exc.InvalidRequestError,
                              "'twophase' mode not enabled, or not root "
                              "transaction; can't prepare.",
                              sess.prepare)
예제 #20
0
    def test_identity_conflict(self):
        users, User = self.tables.users, self.classes.User

        mapper(User, users)
        for s in (
            create_session(),
            create_session(weak_identity_map=False),
        ):
            users.delete().execute()
            u1 = User(name="ed")
            s.add(u1)
            s.flush()
            s.expunge(u1)
            u2 = s.query(User).first()
            s.expunge(u2)
            s.identity_map.add(sa.orm.attributes.instance_state(u1))

            assert_raises_message(
                sa.exc.InvalidRequestError,
                "Can't attach instance <User.*?>; another instance "
                "with key .*? is already "
                "present in this session.",
                s.identity_map.add,
                sa.orm.attributes.instance_state(u2)
            )
예제 #21
0
    def test_invalidate_trans(self):
        conn = db.connect()
        trans = conn.begin()
        dbapi.shutdown()
        try:
            conn.execute(select([1]))
            assert False
        except tsa.exc.DBAPIError:
            pass

        # assert was invalidated

        gc_collect()
        assert len(dbapi.connections) == 0
        assert not conn.closed
        assert conn.invalidated
        assert trans.is_active
        assert_raises_message(
            tsa.exc.StatementError,
            "Can't reconnect until invalid transaction is rolled back",
            conn.execute, select([1])
        )
        assert trans.is_active
        try:
            trans.commit()
            assert False
        except tsa.exc.InvalidRequestError, e:
            assert str(e) \
                == "Can't reconnect until invalid transaction is "\
                "rolled back"
예제 #22
0
    def test_single_no_table_args(self):

        class Person(Base, fixtures.ComparableEntity):

            __tablename__ = 'people'
            id = Column('id', Integer, primary_key=True)
            name = Column('name', String(50))
            discriminator = Column('type', String(50))
            __mapper_args__ = {'polymorphic_on': discriminator}

        def go():

            class Engineer(Person):

                __mapper_args__ = {'polymorphic_identity': 'engineer'}
                primary_language = Column('primary_language',
                        String(50))

                # this should be on the Person class, as this is single
                # table inheritance, which is why we test that this
                # throws an exception!

                __table_args__ = {'mysql_engine': 'InnoDB'}

        assert_raises_message(sa.exc.ArgumentError,
                              'place __table_args__', go)
예제 #23
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,
            )
예제 #24
0
 def _assert_unorderable_types(self, callable_):
     if util.py3k:
         assert_raises_message(
             TypeError, 'unorderable types', callable_)
     else:
         assert_raises_message(
             TypeError, 'cannot compare sets using cmp()', callable_)
예제 #25
0
 def test_missing_bind_posn(self):
     assert_raises_message(
         exc.ArgumentError,
         "This text\(\) construct doesn't define a bound parameter named 'bar'",
         text(":foo").bindparams,
         bindparam('foo', value=5), bindparam('bar', value=7)
     )
예제 #26
0
    def test_overlapping_attribute_error(self):
        place, Transition, place_input, Place, transition = (
            self.tables.place,
            self.classes.Transition,
            self.tables.place_input,
            self.classes.Place,
            self.tables.transition,
        )

        mapper(
            Place,
            place,
            properties={
                "transitions": relationship(
                    Transition, secondary=place_input, backref="places"
                )
            },
        )
        mapper(
            Transition,
            transition,
            properties={
                "places": relationship(
                    Place, secondary=place_input, backref="transitions"
                )
            },
        )
        assert_raises_message(
            sa.exc.ArgumentError,
            "property of that name exists",
            sa.orm.configure_mappers,
        )
예제 #27
0
 def test_with_transaction(self):
     conn = engine.connect()
     trans = conn.begin()
     eq_(conn.execute(select([1])).scalar(), 1)
     assert not conn.closed
     engine.test_shutdown()
     try:
         conn.execute(select([1]))
         assert False
     except tsa.exc.DBAPIError as e:
         if not e.connection_invalidated:
             raise
     assert not conn.closed
     assert conn.invalidated
     assert trans.is_active
     assert_raises_message(
         tsa.exc.StatementError,
         "Can't reconnect until invalid transaction is "\
             "rolled back",
         conn.execute, select([1])
     )
     assert trans.is_active
     try:
         trans.commit()
         assert False
     except tsa.exc.InvalidRequestError as e:
         assert str(e) \
             == "Can't reconnect until invalid transaction is "\
             "rolled back"
     assert trans.is_active
     trans.rollback()
     assert not trans.is_active
     assert conn.invalidated
     eq_(conn.execute(select([1])).scalar(), 1)
     assert not conn.invalidated
예제 #28
0
 def test_missing_bind_kw(self):
     assert_raises_message(
         exc.ArgumentError,
         "This text\(\) construct doesn't define a bound parameter named 'bar'",
         text(":foo").bindparams,
         foo=5, bar=7
     )
예제 #29
0
 def _assert_raises_ambig_join(
     self, fn, relname, secondary_arg, *arg, **kw
 ):
     if secondary_arg is not None:
         assert_raises_message(
             exc.AmbiguousForeignKeysError,
             "Could not determine join condition between "
             "parent/child tables on relationship %s - "
             "there are multiple foreign key paths linking the "
             "tables via secondary table '%s'.  "
             "Specify the 'foreign_keys' argument, providing a list "
             "of those columns which should be counted as "
             "containing a foreign key reference from the "
             "secondary table to each of the parent and child tables."
             % (relname, secondary_arg),
             fn,
             *arg,
             **kw
         )
     else:
         assert_raises_message(
             exc.AmbiguousForeignKeysError,
             "Could not determine join condition between "
             "parent/child tables on relationship %s - "
             "there are no foreign keys linking these tables.  "
             % (relname,),
             fn,
             *arg,
             **kw
         )
예제 #30
0
    def test_limit_offset_for_update(self):
        metadata = self.metadata
        # 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()

        t.insert().execute(
            {"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.
        eq_(
            t.select().with_for_update().limit(2).execute().fetchall(),
            [(1, 1), (2, 7)],
        )

        # here, its impossible.  But we'd prefer it to raise ORA-02014
        # instead of issuing a syntax error.
        assert_raises_message(
            exc.DatabaseError,
            "ORA-02014",
            t.select().with_for_update().limit(2).offset(3).execute,
        )
예제 #31
0
    def test_conflicting_backref_one(self):
        """test that conflicting backrefs raises an exception"""

        metadata = MetaData(testing.db)

        order = Table(
            "orders",
            metadata,
            Column("id", Integer, primary_key=True),
            Column("type", Unicode(16)),
        )

        product = Table("products", metadata,
                        Column("id", Integer, primary_key=True))

        orderproduct = Table(
            "orderproducts",
            metadata,
            Column("id", Integer, primary_key=True),
            Column("order_id",
                   Integer,
                   ForeignKey("orders.id"),
                   nullable=False),
            Column(
                "product_id",
                Integer,
                ForeignKey("products.id"),
                nullable=False,
            ),
        )

        class Order(object):
            pass

        class Product(object):
            pass

        class OrderProduct(object):
            pass

        order_join = order.select().alias("pjoin")

        order_mapper = mapper(
            Order,
            order,
            with_polymorphic=("*", order_join),
            polymorphic_on=order_join.c.type,
            polymorphic_identity="order",
            properties={
                "orderproducts":
                relationship(OrderProduct, lazy="select", backref="product")
            },
        )

        mapper(
            Product,
            product,
            properties={
                "orderproducts":
                relationship(OrderProduct, lazy="select", backref="product")
            },
        )

        mapper(OrderProduct, orderproduct)

        assert_raises_message(sa_exc.ArgumentError, "Error creating backref",
                              configure_mappers)
예제 #32
0
 def _assert_unorderable_types(self, callable_):
     if util.py3k:
         assert_raises_message(TypeError, 'unorderable types', callable_)
     else:
         assert_raises_message(TypeError, 'cannot compare sets using cmp()',
                               callable_)
예제 #33
0
 def test_result_processor_invalid(self):
     mssql_date_type = _MSDate()
     result_processor = mssql_date_type.result_processor(None, None)
     assert_raises_message(ValueError,
                           "could not parse 'abc' as a date value",
                           result_processor, 'abc')
예제 #34
0
 def test_missing_bind_posn(self):
     assert_raises_message(
         exc.ArgumentError,
         "This text\(\) construct doesn't define a bound parameter named 'bar'",
         text(":foo").bindparams, bindparam('foo', value=5),
         bindparam('bar', value=7))
예제 #35
0
 def test_nondeletable(self):
     A = self._fixture(False)
     a1 = A(_value=5)
     assert_raises_message(AttributeError, "can't delete attribute",
                           delattr, a1, "value")
예제 #36
0
 def test_nonassignable(self):
     A = self._fixture(False)
     a1 = A(_value=5)
     assert_raises_message(AttributeError, "can't set attribute", setattr,
                           a1, "value", 10)
예제 #37
0
    def test_insert_executemany_insdefault_passed(self, connection):
        t1 = self.tables.t1
        result = connection.execute(
            t1.insert().return_defaults(),
            [
                {
                    "data": "d1",
                    "insdef": 11
                },
                {
                    "data": "d2",
                    "insdef": 12
                },
                {
                    "data": "d3",
                    "insdef": 13
                },
                {
                    "data": "d4",
                    "insdef": 14
                },
                {
                    "data": "d5",
                    "insdef": 15
                },
                {
                    "data": "d6",
                    "insdef": 16
                },
            ],
        )

        eq_(
            [row._mapping for row in result.returned_defaults_rows],
            [
                {
                    "id": 1,
                    "upddef": None
                },
                {
                    "id": 2,
                    "upddef": None
                },
                {
                    "id": 3,
                    "upddef": None
                },
                {
                    "id": 4,
                    "upddef": None
                },
                {
                    "id": 5,
                    "upddef": None
                },
                {
                    "id": 6,
                    "upddef": None
                },
            ],
        )

        eq_(
            result.inserted_primary_key_rows,
            [(1, ), (2, ), (3, ), (4, ), (5, ), (6, )],
        )
        assert_raises_message(
            sa_exc.InvalidRequestError,
            "This statement was an executemany call; "
            "if return defaults is supported",
            lambda: result.returned_defaults,
        )
        assert_raises_message(
            sa_exc.InvalidRequestError,
            "This statement was an executemany call; "
            "if primary key returning is supported",
            lambda: result.inserted_primary_key,
        )
예제 #38
0
 def test_bitwise_required_for_empty(self):
     assert_raises_message(
         exc.ArgumentError,
         "Can't use the blank value '' in a SET without setting "
         "retrieve_as_bitwise=True", mysql.SET, "a", "b", '')
예제 #39
0
    def _assert_data_noautoincrement(self, table):
        self.engine = \
            engines.testing_engine(options={'implicit_returning': False})
        metadata.bind = self.engine
        table.insert().execute({'id': 30, 'data': 'd1'})
        if self.engine.driver == 'pg8000':
            exception_cls = exc.ProgrammingError
        elif self.engine.driver == 'pypostgresql':
            exception_cls = Exception
        else:
            exception_cls = exc.IntegrityError
        assert_raises_message(exception_cls,
                              'violates not-null constraint',
                              table.insert().execute, {'data': 'd2'})
        assert_raises_message(exception_cls,
                              'violates not-null constraint',
                              table.insert().execute, {'data': 'd2'},
                              {'data': 'd3'})
        assert_raises_message(exception_cls,
                              'violates not-null constraint',
                              table.insert().execute, {'data': 'd2'})
        assert_raises_message(exception_cls,
                              'violates not-null constraint',
                              table.insert().execute, {'data': 'd2'},
                              {'data': 'd3'})
        table.insert().execute({'id': 31, 'data': 'd2'}, {'id': 32,
                                                          'data': 'd3'})
        table.insert(inline=True).execute({'id': 33, 'data': 'd4'})
        assert table.select().execute().fetchall() == [
            (30, 'd1'),
            (31, 'd2'),
            (32, 'd3'),
            (33, 'd4')]
        table.delete().execute()

        # test the same series of events using a reflected version of
        # the table

        m2 = MetaData(self.engine)
        table = Table(table.name, m2, autoload=True)
        table.insert().execute({'id': 30, 'data': 'd1'})
        assert_raises_message(exception_cls,
                              'violates not-null constraint',
                              table.insert().execute, {'data': 'd2'})
        assert_raises_message(exception_cls,
                              'violates not-null constraint',
                              table.insert().execute, {'data': 'd2'},
                              {'data': 'd3'})
        table.insert().execute({'id': 31, 'data': 'd2'}, {'id': 32,
                                                          'data': 'd3'})
        table.insert(inline=True).execute({'id': 33, 'data': 'd4'})
        assert table.select().execute().fetchall() == [
            (30, 'd1'),
            (31, 'd2'),
            (32, 'd3'),
            (33, 'd4')]
예제 #40
0
    def test_with_transaction(self):
        conn = self.engine.connect()
        trans = conn.begin()
        assert trans.is_valid
        eq_(conn.execute(select(1)).scalar(), 1)
        assert not conn.closed
        self.engine.test_shutdown()
        _assert_invalidated(conn.execute, select(1))
        assert not conn.closed
        assert conn.invalidated
        assert trans.is_active
        assert not trans.is_valid

        assert_raises_message(
            tsa.exc.PendingRollbackError,
            "Can't reconnect until invalid transaction is rolled back",
            conn.execute,
            select(1),
        )
        assert trans.is_active
        assert not trans.is_valid

        assert_raises_message(
            tsa.exc.PendingRollbackError,
            "Can't reconnect until invalid transaction is rolled back",
            trans.commit,
        )

        # becomes inactive
        assert not trans.is_active
        assert not trans.is_valid

        # still asks us to rollback
        assert_raises_message(
            tsa.exc.PendingRollbackError,
            "Can't reconnect until invalid transaction is rolled back",
            conn.execute,
            select(1),
        )

        # still asks us..
        assert_raises_message(
            tsa.exc.PendingRollbackError,
            "Can't reconnect until invalid transaction is rolled back",
            trans.commit,
        )

        # still...it's being consistent in what it is asking.
        assert_raises_message(
            tsa.exc.PendingRollbackError,
            "Can't reconnect until invalid transaction is rolled back",
            conn.execute,
            select(1),
        )

        #  OK!
        trans.rollback()
        assert not trans.is_active
        assert not trans.is_valid

        # conn still invalid but we can reconnect
        assert conn.invalidated
        eq_(conn.execute(select(1)).scalar(), 1)
        assert not conn.invalidated
예제 #41
0
 trans = conn.begin()
 eq_(conn.execute(select([1])).scalar(), 1)
 assert not conn.closed
 engine.test_shutdown()
 try:
     conn.execute(select([1]))
     assert False
 except tsa.exc.DBAPIError, e:
     if not e.connection_invalidated:
         raise
 assert not conn.closed
 assert conn.invalidated
 assert trans.is_active
 assert_raises_message(
     tsa.exc.StatementError,
     "Can't reconnect until invalid transaction is "\
         "rolled back",
     conn.execute, select([1])
 )
 assert trans.is_active
 try:
     trans.commit()
     assert False
 except tsa.exc.InvalidRequestError, e:
     assert str(e) \
         == "Can't reconnect until invalid transaction is "\
         "rolled back"
 assert trans.is_active
 trans.rollback()
 assert not trans.is_active
 assert conn.invalidated
 eq_(conn.execute(select([1])).scalar(), 1)
예제 #42
0
 def test_coerce_raise(self):
     assert_raises_message(
         ValueError,
         "Attribute 'data' does not accept objects of type",
         Foo, data=set([1, 2, 3])
     )
예제 #43
0
    def test_cycle_unnamed_fks(self):
        metadata = MetaData()

        Table(
            "a",
            metadata,
            Column("id", Integer, primary_key=True),
            Column("bid", Integer, ForeignKey("b.id")),
        )

        Table(
            "b",
            metadata,
            Column("id", Integer, primary_key=True),
            Column("aid", Integer, ForeignKey("a.id")),
        )

        assertions = [
            AllOf(
                CompiledSQL("CREATE TABLE b ("
                            "id INTEGER NOT NULL, "
                            "aid INTEGER, "
                            "PRIMARY KEY (id)"
                            ")"),
                CompiledSQL("CREATE TABLE a ("
                            "id INTEGER NOT NULL, "
                            "bid INTEGER, "
                            "PRIMARY KEY (id)"
                            ")"),
            ),
            AllOf(
                CompiledSQL("ALTER TABLE b ADD "
                            "FOREIGN KEY(aid) REFERENCES a (id)"),
                CompiledSQL("ALTER TABLE a ADD "
                            "FOREIGN KEY(bid) REFERENCES b (id)"),
            ),
        ]
        with self.sql_execution_asserter() as asserter:
            metadata.create_all(testing.db, checkfirst=False)

        if testing.db.dialect.supports_alter:
            asserter.assert_(*assertions)

            assert_raises_message(
                exc.CircularDependencyError,
                "Can't sort tables for DROP; an unresolvable foreign key "
                "dependency exists between tables: a, b.  "
                "Please ensure that the "
                "ForeignKey and ForeignKeyConstraint objects involved in the "
                "cycle have names so that they can be dropped using "
                "DROP CONSTRAINT.",
                metadata.drop_all,
                testing.db,
                checkfirst=False,
            )
        else:
            with expect_warnings(
                    "Can't sort tables for DROP; an unresolvable "
                    "foreign key dependency exists between tables"):
                with self.sql_execution_asserter() as asserter:
                    metadata.drop_all(testing.db, checkfirst=False)

            asserter.assert_(
                AllOf(CompiledSQL("DROP TABLE b"),
                      CompiledSQL("DROP TABLE a")))
예제 #44
0
 def test_update_one_elem_varg(self):
     a1 = self.A()
     assert_raises_message(
         ValueError, "dictionary update sequence requires "
         "2-element tuples", a1.elements.update, (("B", 3), 'elem2'))
예제 #45
0
 def test_extra_dirty_state_post_flush_warning(self):
     s, a1, a2 = self._test_extra_dirty_state()
     assert_raises_message(
         sa.exc.SAWarning,
         "Attribute history events accumulated on 1 previously "
         "clean instances", s.commit)
예제 #46
0
 def _raises(self, expr):
     assert_raises_message(TypeError,
                           "Boolean value of this clause is not defined",
                           bool, expr)
예제 #47
0
 def test_update_multi_elem_varg(self):
     a1 = self.A()
     assert_raises_message(TypeError,
                           "update expected at most 1 arguments, got 2",
                           a1.elements.update, (("B", 3), 'elem2'),
                           (("C", 4), "elem3"))
예제 #48
0
    def test_only_str_set(self, argname):
        u1 = url.URL.create("somedriver")

        assert_raises_message(TypeError, "%s must be a string" % argname,
                              u1.set, **{argname: 35.8})
예제 #49
0
 def test_set_illegal(self):
     f1 = Foo()
     assert_raises_message(ValueError,
                           "Attribute 'data' does not accept objects",
                           setattr, f1, 'data', 'foo')
예제 #50
0
    def _roundtrip(
        self,
        Employee,
        Manager,
        Engineer,
        Boss,
        polymorphic=True,
        explicit_type=False,
    ):
        Base.metadata.create_all(testing.db)
        sess = fixture_session()
        e1 = Engineer(name="dilbert", primary_language="java")
        e2 = Engineer(name="wally", primary_language="c++")
        m1 = Manager(name="dogbert", golf_swing="fore!")
        e3 = Engineer(name="vlad", primary_language="cobol")
        b1 = Boss(name="pointy haired")

        if polymorphic:
            for obj in [e1, e2, m1, e3, b1]:
                if explicit_type:
                    eq_(obj.type, obj.__mapper__.polymorphic_identity)
                else:
                    assert_raises_message(
                        AttributeError,
                        "does not implement attribute .?'type' "
                        "at the instance level.",
                        getattr,
                        obj,
                        "type",
                    )
        else:
            assert "type" not in Engineer.__dict__
            assert "type" not in Manager.__dict__
            assert "type" not in Boss.__dict__

        sess.add_all([e1, e2, m1, e3, b1])
        sess.flush()
        sess.expunge_all()
        if polymorphic:
            eq_(
                sess.query(Employee).order_by(Employee.name).all(),
                [
                    Engineer(name="dilbert"),
                    Manager(name="dogbert"),
                    Boss(name="pointy haired"),
                    Engineer(name="vlad"),
                    Engineer(name="wally"),
                ],
            )
        else:
            eq_(
                sess.query(Engineer).order_by(Engineer.name).all(),
                [
                    Engineer(name="dilbert"),
                    Engineer(name="vlad"),
                    Engineer(name="wally"),
                ],
            )
            eq_(sess.query(Manager).all(), [Manager(name="dogbert")])
            eq_(sess.query(Boss).all(), [Boss(name="pointy haired")])

        e1 = sess.query(Engineer).order_by(Engineer.name).first()
        sess.expire(e1)
        eq_(e1.name, "dilbert")
예제 #51
0
 def test_unary_no_ops(self):
     assert_raises_message(exc.CompileError,
                           "Unary expression has no operator or modifier",
                           UnaryExpression(literal("x")).compile)
예제 #52
0
    def test_multi_level_no_base(self):
        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {
                "engineer": engineers_table,
                "hacker": hackers_table
            },
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        tom = Manager("Tom", "knows how to manage things")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            tom,
            "type",
            "sometype",
        )

        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            hacker,
            "type",
            "sometype",
        )

        session.add_all((tom, jerry, hacker))
        session.flush()

        # ensure "readonly" on save logic didn't pollute the
        # expired_attributes collection

        assert ("nickname"
                not in attributes.instance_state(jerry).expired_attributes)
        assert ("name"
                not in attributes.instance_state(jerry).expired_attributes)
        assert ("name"
                not in attributes.instance_state(hacker).expired_attributes)
        assert ("nickname"
                not in attributes.instance_state(hacker).expired_attributes)

        def go():
            eq_(jerry.name, "Jerry")
            eq_(hacker.nickname, "Badass")

        self.assert_sql_count(testing.db, go, 0)
        session.expunge_all()
        assert (repr(
            session.query(Employee).filter(Employee.name == "Tom").one()) ==
                "Manager Tom knows how to manage things")
        assert (repr(
            session.query(Manager).filter(Manager.name == "Tom").one()) ==
                "Manager Tom knows how to manage things")
        assert set([repr(x) for x in session.query(Employee).all()]) == set([
            "Engineer Jerry knows how to program",
            "Manager Tom knows how to manage things",
            "Hacker Kurt 'Badass' knows how to hack",
        ])
        assert set([repr(x) for x in session.query(Manager).all()
                    ]) == set(["Manager Tom knows how to manage things"])
        assert set([repr(x) for x in session.query(Engineer).all()]) == set([
            "Engineer Jerry knows how to program",
            "Hacker Kurt 'Badass' knows how to hack",
        ])
        assert set([repr(x) for x in session.query(Hacker).all()
                    ]) == set(["Hacker Kurt 'Badass' knows how to hack"])
예제 #53
0
 def test_only_str_constructor(self, argname):
     assert_raises_message(TypeError, "%s must be a string" % argname,
                           url.URL.create, "somedriver", **{argname: 35.8})
예제 #54
0
 def test_only_str_drivername_no_none(self, value):
     assert_raises_message(TypeError, "drivername must be a string",
                           url.URL.create, value)
예제 #55
0
    def test_multi_level_no_base(self):
        pjoin = polymorphic_union(
            {
                'manager': managers_table,
                'engineer': engineers_table,
                'hacker': hackers_table
            }, 'type', 'pjoin')
        pjoin2 = polymorphic_union(
            {
                'engineer': engineers_table,
                'hacker': hackers_table
            }, 'type', 'pjoin2')
        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        manager_mapper = mapper(Manager,
                                managers_table,
                                inherits=employee_mapper,
                                concrete=True,
                                polymorphic_identity='manager')
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            with_polymorphic=('*', pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity='engineer',
        )
        hacker_mapper = mapper(Hacker,
                               hackers_table,
                               inherits=engineer_mapper,
                               concrete=True,
                               polymorphic_identity='hacker')
        session = create_session()
        tom = Manager('Tom', 'knows how to manage things')

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr, tom, "type", "sometype")

        jerry = Engineer('Jerry', 'knows how to program')
        hacker = Hacker('Kurt', 'Badass', 'knows how to hack')

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr, hacker, "type", "sometype")

        session.add_all((tom, jerry, hacker))
        session.flush()

        # ensure "readonly" on save logic didn't pollute the
        # expired_attributes collection

        assert 'nickname' \
            not in attributes.instance_state(jerry).expired_attributes
        assert 'name' \
            not in attributes.instance_state(jerry).expired_attributes
        assert 'name' \
            not in attributes.instance_state(hacker).expired_attributes
        assert 'nickname' \
            not in attributes.instance_state(hacker).expired_attributes

        def go():
            eq_(jerry.name, 'Jerry')
            eq_(hacker.nickname, 'Badass')

        self.assert_sql_count(testing.db, go, 0)
        session.expunge_all()
        assert repr(session.query(Employee).filter(Employee.name
                    == 'Tom').one()) \
            == 'Manager Tom knows how to manage things'
        assert repr(
            session.query(Manager).filter(Manager.name == 'Tom').one()
        ) == 'Manager Tom knows how to manage things'
        assert set([repr(x) for x in session.query(Employee).all()]) \
            == set(['Engineer Jerry knows how to program',
                   'Manager Tom knows how to manage things',
                   "Hacker Kurt 'Badass' knows how to hack"])
        assert set([repr(x) for x in session.query(Manager).all()]) \
            == set(['Manager Tom knows how to manage things'])
        assert set([repr(x) for x in session.query(Engineer).all()]) \
            == set(['Engineer Jerry knows how to program',
                   "Hacker Kurt 'Badass' knows how to hack"])
        assert set([repr(x) for x in session.query(Hacker).all()]) \
            == set(["Hacker Kurt 'Badass' knows how to hack"])
예제 #56
0
 def _assert_non_simple_warning(self, fn):
     assert_raises_message(
         exc.SAWarning, "Non-simple column elements in "
         "primary join condition for property "
         r"None - consider using remote\(\) "
         "annotations to mark the remote side.", fn)
예제 #57
0
 def test_only_str_drivername_no_none_legacy(self, value):
     with expect_deprecated(r"Calling URL\(\) directly"):
         assert_raises_message(TypeError, "drivername must be a string",
                               url.URL, value)
예제 #58
0
    def test_not_supported(self):
        dialect, connection = self._fixture(None)

        with expect_warnings("Could not fetch transaction isolation level"):
            assert_raises_message(NotImplementedError, "Can't fetch isolation",
                                  dialect.get_isolation_level, connection)
예제 #59
0
 def test_cursor_shutdown_in_initialize(self):
     db = self._fixture(True, True)
     assert_raises_message(exc.SAWarning, "Exception attempting to detect",
                           db.connect)
     eq_(db.pool.logger.error.mock_calls,
         [call('Error closing cursor', exc_info=True)])