def test_no_orphan(self):
        """test that a lazily loaded child object is not marked as an orphan"""

        users, Address, addresses, User = (
            self.tables.users,
            self.classes.Address,
            self.tables.addresses,
            self.classes.User,
        )

        mapper(
            User,
            users,
            properties={
                "addresses":
                relationship(Address,
                             cascade="all,delete-orphan",
                             lazy="select")
            },
        )
        mapper(Address, addresses)

        sess = create_session()
        user = sess.query(User).get(7)
        assert getattr(User, "addresses").hasparent(attributes.instance_state(
            user.addresses[0]),
                                                    optimistic=True)
        assert not sa.orm.class_mapper(Address)._is_orphan(
            attributes.instance_state(user.addresses[0]))
Пример #2
0
    def test_pending_combines_with_flushed(self):
        """test the combination of unflushed pending + lazy loaded from DB."""

        Item, Keyword = (self.classes.Item, self.classes.Keyword)

        session = Session(testing.db, autoflush=False)

        k1 = Keyword(name="k1")
        k2 = Keyword(name="k2")
        i1 = Item(description="i1", keywords=[k1])
        session.add(i1)
        session.add(k2)
        session.commit()

        k2.items.append(i1)
        # the pending
        # list is still here.
        eq_(
            set(
                attributes.instance_state(
                    i1)._pending_mutations["keywords"].added_items),
            set([k2]),
        )
        # because autoflush is off, k2 is still
        # coming in from pending
        eq_(i1.keywords, [k1, k2])

        # prove it didn't flush
        eq_(session.scalar("select count(*) from item_keywords"), 1)

        # the pending collection was removed
        assert ("keywords"
                not in attributes.instance_state(i1)._pending_mutations)
Пример #3
0
 def _fixture(self):
     A, B = self.classes.A, self.classes.B
     session = create_session()
     uowcommit = self._get_test_uow(session)
     a_mapper = class_mapper(A)
     b_mapper = class_mapper(B)
     self.a1 = a1 = A()
     self.b1 = b1 = B()
     uowcommit = self._get_test_uow(session)
     return (
         uowcommit,
         attributes.instance_state(a1),
         attributes.instance_state(b1),
         a_mapper,
         b_mapper,
     )
 def test_history_populated_passive_return_never_set(self):
     User, Address, sess, a1 = self._u_ad_fixture(True)
     eq_(
         Address.user.impl.get_history(
             attributes.instance_state(a1),
             attributes.instance_dict(a1),
             passive=attributes.PASSIVE_RETURN_NEVER_SET,
         ),
         ((), [User(name="ed")], ()),
     )
 def test_history_empty_passive_return_never_set(self):
     User, Address, sess, a1 = self._u_ad_fixture(False)
     eq_(
         Address.user.impl.get_history(
             attributes.instance_state(a1),
             attributes.instance_dict(a1),
             passive=attributes.PASSIVE_RETURN_NEVER_SET,
         ),
         ((), (), ()),
     )
     assert "user_id" not in a1.__dict__
     assert "user" not in a1.__dict__
 def test_get_empty_passive_no_initialize(self):
     User, Address, sess, a1 = self._u_ad_fixture(False)
     eq_(
         Address.user.impl.get(
             attributes.instance_state(a1),
             attributes.instance_dict(a1),
             passive=attributes.PASSIVE_NO_INITIALIZE,
         ),
         attributes.PASSIVE_NO_RESULT,
     )
     assert "user_id" not in a1.__dict__
     assert "user" not in a1.__dict__
 def test_history_populated_passive_no_initialize(self):
     User, Address, sess, a1 = self._u_ad_fixture(True)
     eq_(
         Address.user.impl.get_history(
             attributes.instance_state(a1),
             attributes.instance_dict(a1),
             passive=attributes.PASSIVE_NO_INITIALIZE,
         ),
         attributes.HISTORY_BLANK,
     )
     assert "user_id" not in a1.__dict__
     assert "user" not in a1.__dict__
    def test_basic(self):
        for base in (object, MyBaseClass, MyClass):

            class User(base):
                pass

            register_class(User)
            attributes.register_attribute(User,
                                          "user_id",
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(User,
                                          "user_name",
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(User,
                                          "email_address",
                                          uselist=False,
                                          useobject=False)

            u = User()
            u.user_id = 7
            u.user_name = "john"
            u.email_address = "*****@*****.**"

            eq_(u.user_id, 7)
            eq_(u.user_name, "john")
            eq_(u.email_address, "*****@*****.**")
            attributes.instance_state(u)._commit_all(
                attributes.instance_dict(u))
            eq_(u.user_id, 7)
            eq_(u.user_name, "john")
            eq_(u.email_address, "*****@*****.**")

            u.user_name = "heythere"
            u.email_address = "*****@*****.**"
            eq_(u.user_id, 7)
            eq_(u.user_name, "heythere")
            eq_(u.email_address, "*****@*****.**")
Пример #9
0
    def test_exceptions(self):
        class Foo(object):
            pass

        users = self.tables.users
        mapper(User, users)

        for sa_exc in (
            orm_exc.UnmappedInstanceError(Foo()),
            orm_exc.UnmappedClassError(Foo),
            orm_exc.ObjectDeletedError(attributes.instance_state(User())),
        ):
            for loads, dumps in picklers():
                repickled = loads(dumps(sa_exc))
                eq_(repickled.args[0], sa_exc.args[0])
Пример #10
0
    def test_rebuild_state(self):
        """not much of a 'test', but illustrate how to
        remove instance-level state before pickling.

        """

        users = self.tables.users

        mapper(User, users)

        u1 = User()
        attributes.manager_of_class(User).teardown_instance(u1)
        assert not u1.__dict__
        u2 = pickle.loads(pickle.dumps(u1))
        attributes.manager_of_class(User).setup_instance(u2)
        assert attributes.instance_state(u2)
    def test_alternate_finders(self):
        """Ensure the generic finder front-end deals with edge cases."""
        class Unknown(object):
            pass

        class Known(MyBaseClass):
            pass

        register_class(Known)
        k, u = Known(), Unknown()

        assert instrumentation.manager_of_class(Unknown) is None
        assert instrumentation.manager_of_class(Known) is not None
        assert instrumentation.manager_of_class(None) is None

        assert attributes.instance_state(k) is not None
        assert_raises((AttributeError, KeyError), attributes.instance_state, u)
        assert_raises((AttributeError, KeyError), attributes.instance_state,
                      None)
    def test_stale_state_positive_pk_change(self):
        """Illustrate that we can't easily link a
        stale state to a fresh one if the fresh one has
        a PK change  (unless we a. tracked all the previous PKs,
        wasteful, or b. recycled states - time consuming,
        breaks lots of edge cases, destabilizes the code)

        """

        User = self.classes.User
        s, u1, a1 = self._fixture()

        s._expunge_states([attributes.instance_state(u1)])

        del u1
        gc_collect()

        u1 = s.query(User).first()

        # primary key change.  now we
        # can't rely on state.key as the
        # identifier.
        new_id = u1.id + 10
        u1.id = new_id
        a1.user_id = new_id
        s.flush()

        assert_raises_message(
            orm_exc.StaleDataError,
            "can't be sure this is the most recent parent.",
            u1.addresses.remove,
            a1,
        )

        # u1.addresses wasn't actually impacted, because the event was
        # caught before collection mutation
        eq_(u1.addresses, [a1])

        # expire all and we can continue
        s.expire_all()
        u1.addresses.remove(a1)

        self._assert_not_hasparent(a1)
    def test_stale_state_negative(self):
        User = self.classes.User
        s, u1, a1 = self._fixture()

        u2 = User(addresses=[a1])
        s.add(u2)
        s.flush()
        s._expunge_states([attributes.instance_state(u2)])
        del u2
        gc_collect()

        assert_raises_message(
            orm_exc.StaleDataError,
            "can't be sure this is the most recent parent.",
            u1.addresses.remove,
            a1,
        )

        s.flush()
        self._assert_hasparent(a1)
Пример #14
0
 def test_instance_state(self):
     User = self.classes.User
     u1 = User()
     insp = inspect(u1)
     is_(insp, instance_state(u1))
Пример #15
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"])
    def test_deferred(self):
        for base in (object, MyBaseClass, MyClass):

            class Foo(base):
                pass

            data = {"a": "this is a", "b": 12}

            def loader(state, keys):
                for k in keys:
                    state.dict[k] = data[k]
                return attributes.ATTR_WAS_SET

            manager = register_class(Foo)
            manager.deferred_scalar_loader = loader
            attributes.register_attribute(Foo,
                                          "a",
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(Foo,
                                          "b",
                                          uselist=False,
                                          useobject=False)

            if base is object:
                assert Foo not in (
                    instrumentation._instrumentation_factory._state_finders)
            else:
                assert Foo in (
                    instrumentation._instrumentation_factory._state_finders)

            f = Foo()
            attributes.instance_state(f)._expire(attributes.instance_dict(f),
                                                 set())
            eq_(f.a, "this is a")
            eq_(f.b, 12)

            f.a = "this is some new a"
            attributes.instance_state(f)._expire(attributes.instance_dict(f),
                                                 set())
            eq_(f.a, "this is a")
            eq_(f.b, 12)

            attributes.instance_state(f)._expire(attributes.instance_dict(f),
                                                 set())
            f.a = "this is another new a"
            eq_(f.a, "this is another new a")
            eq_(f.b, 12)

            attributes.instance_state(f)._expire(attributes.instance_dict(f),
                                                 set())
            eq_(f.a, "this is a")
            eq_(f.b, 12)

            del f.a
            eq_(f.a, None)
            eq_(f.b, 12)

            attributes.instance_state(f)._commit_all(
                attributes.instance_dict(f))
            eq_(f.a, None)
            eq_(f.b, 12)
    def test_history(self):
        for base in (object, MyBaseClass, MyClass):

            class Foo(base):
                pass

            class Bar(base):
                pass

            register_class(Foo)
            register_class(Bar)
            attributes.register_attribute(Foo,
                                          "name",
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(Foo,
                                          "bars",
                                          uselist=True,
                                          trackparent=True,
                                          useobject=True)
            attributes.register_attribute(Bar,
                                          "name",
                                          uselist=False,
                                          useobject=False)

            f1 = Foo()
            f1.name = "f1"

            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "name"),
                (["f1"], (), ()),
            )

            b1 = Bar()
            b1.name = "b1"
            f1.bars.append(b1)
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ([b1], [], []),
            )

            attributes.instance_state(f1)._commit_all(
                attributes.instance_dict(f1))
            attributes.instance_state(b1)._commit_all(
                attributes.instance_dict(b1))

            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "name"),
                ((), ["f1"], ()),
            )
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ((), [b1], ()),
            )

            f1.name = "f1mod"
            b2 = Bar()
            b2.name = "b2"
            f1.bars.append(b2)
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "name"),
                (["f1mod"], (), ["f1"]),
            )
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ([b2], [b1], []),
            )
            f1.bars.remove(b1)
            eq_(
                attributes.get_state_history(attributes.instance_state(f1),
                                             "bars"),
                ([b2], [], [b1]),
            )