Python sqlalchemy.orm.attributes.get_history() Examples

The following are 18 code examples of sqlalchemy.orm.attributes.get_history(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module sqlalchemy.orm.attributes , or try the search function .
Example #1
Source File: sqlalchemy.py    From depot with MIT License 6 votes vote down vote up
def _session_flush(cls, session, flush_context, instances):
        for obj in session.deleted:
            class_ = obj.__class__
            tracked_columns = cls.mapped_entities.get(class_, tuple())
            for col in tracked_columns:
                value = getattr(obj, col)
                if value is not None:
                    session._depot_old = getattr(session, '_depot_old', set())
                    session._depot_old.update(value.files)

        for obj in session.new.union(session.dirty):
            class_ = obj.__class__
            tracked_columns = cls.mapped_entities.get(class_, tuple())
            for col in tracked_columns:
                history = get_history(obj, col)
                added_files = itertools.chain(*(f.files for f in history.added
                                               if f is not None))
                deleted_files = itertools.chain(*(f.files for f in history.deleted
                                                 if f is not None))

                session._depot_new = getattr(session, '_depot_new', set())
                session._depot_new.update(added_files)
                session._depot_old = getattr(session, '_depot_old', set())
                session._depot_old.update(deleted_files) 
Example #2
Source File: db.py    From maple-blog with GNU General Public License v3.0 6 votes vote down vote up
def bucket_update_listen(mapper, connection, target):
    oldname = target.name
    newname = target.name
    history = get_history(target, "name")
    if history.added and history.deleted:
        oldname = history.deleted[0]
        newname = history.added[0]

    oldpath = os.path.join(
        config.UPLOAD_FOLDER,
        oldname,
    )
    newpath = os.path.join(
        config.UPLOAD_FOLDER,
        newname,
    )
    if oldpath != newpath and os.path.exists(oldpath):
        os.rename(oldpath, newpath) 
Example #3
Source File: db.py    From maple-blog with GNU General Public License v3.0 6 votes vote down vote up
def filepath_update_listen(mapper, connection, target):
    change = {
        "name": (target.name, target.name),
        "bucket": (target.bucket, target.bucket)
    }
    history = get_history(target, "bucket")
    if history.added and history.deleted:
        change["bucket"] = (history.deleted[0], history.added[0])

    history = get_history(target, "name")
    if history.added and history.deleted:
        change["name"] = (history.deleted[0], history.added[0])

    oldpath = os.path.join(
        change["bucket"][0].abspath,
        change["name"][0],
    )
    newpath = os.path.join(
        change["bucket"][1].abspath,
        change["name"][1],
    )
    if oldpath != newpath and os.path.exists(oldpath):
        os.rename(oldpath, newpath) 
Example #4
Source File: test_mapper.py    From sqlalchemy with MIT License 6 votes vote down vote up
def test_unmapped_subclass_error_premap(self):
        users = self.tables.users

        class Base(object):
            pass

        mapper(Base, users)

        class Sub(Base):
            pass

        sa.orm.configure_mappers()

        # we can create new instances, set attributes.
        s = Sub()
        s.name = "foo"
        eq_(s.name, "foo")
        eq_(attributes.get_history(s, "name"), (["foo"], (), ()))

        # using it with an ORM operation, raises
        assert_raises(
            sa.orm.exc.UnmappedClassError, create_session().add, Sub()
        ) 
Example #5
Source File: test_attributes.py    From sqlalchemy with MIT License 6 votes vote down vote up
def test_lazy_history_collection(self):
        Post, Blog, lazy_posts = self._fixture()

        p1, p2, p3 = Post("post 1"), Post("post 2"), Post("post 3")
        lazy_posts.return_value = [p1, p2, p3]

        b = Blog("blog 1")
        p = Post("post 4")
        p.blog = b

        p4 = Post("post 5")
        p4.blog = b

        eq_(lazy_posts.call_count, 1)

        eq_(
            attributes.instance_state(b).get_history(
                "posts", attributes.PASSIVE_OFF
            ),
            ([p, p4], [p1, p2, p3], []),
        )
        eq_(lazy_posts.call_count, 1) 
Example #6
Source File: test_mapper.py    From sqlalchemy with MIT License 6 votes vote down vote up
def test_unmapped_subclass_error_postmap(self):
        users = self.tables.users

        class Base(object):
            pass

        class Sub(Base):
            pass

        mapper(Base, users)
        sa.orm.configure_mappers()

        # we can create new instances, set attributes.
        s = Sub()
        s.name = "foo"
        eq_(s.name, "foo")
        eq_(attributes.get_history(s, "name"), (["foo"], (), ()))

        # using it with an ORM operation, raises
        assert_raises(
            sa.orm.exc.UnmappedClassError, create_session().add, Sub()
        ) 
Example #7
Source File: test_dynamic.py    From sqlalchemy with MIT License 6 votes vote down vote up
def _assert_history(self, obj, compare, compare_passive=None):
        if isinstance(obj, self.classes.User):
            attrname = "addresses"
        elif isinstance(obj, self.classes.Order):
            attrname = "items"

        sess = inspect(obj).session

        if sess:
            sess.autoflush = False
        try:
            eq_(attributes.get_history(obj, attrname), compare)

            if compare_passive is None:
                compare_passive = compare

            eq_(
                attributes.get_history(
                    obj, attrname, attributes.LOAD_AGAINST_COMMITTED
                ),
                compare_passive,
            )
        finally:
            if sess:
                sess.autoflush = True 
Example #8
Source File: test_attributes.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_passive_history_collection_no_value(self):
        Post, Blog, lazy_posts = self._fixture()

        lazy_posts.return_value = attributes.PASSIVE_NO_RESULT

        b = Blog("blog 1")
        p = Post("post 1")

        state, dict_ = (
            attributes.instance_state(b),
            attributes.instance_dict(b),
        )

        # this sets up NO_VALUE on b.posts
        p.blog = b

        eq_(state.committed_state, {"posts": attributes.NO_VALUE})
        assert "posts" not in dict_

        # then suppose the object was made transient again,
        # the lazy loader would return this
        lazy_posts.return_value = attributes.ATTR_EMPTY

        p2 = Post("asdf")
        p2.blog = b

        eq_(state.committed_state, {"posts": attributes.NO_VALUE})
        eq_(dict_["posts"], [p2])

        # then this would fail.
        eq_(
            Blog.posts.impl.get_history(
                state, dict_, passive=attributes.PASSIVE_NO_INITIALIZE
            ),
            ([p2], (), ()),
        )

        eq_(
            Blog.posts.impl.get_all_pending(state, dict_),
            [(attributes.instance_state(p2), p2)],
        ) 
Example #9
Source File: test_relationships.py    From sqlalchemy with MIT License 5 votes vote down vote up
def _test_attribute(self, obj, attrname, newvalue):
        sess = Session()
        sess.add(obj)
        oldvalue = getattr(obj, attrname)
        sess.commit()

        # expired
        assert attrname not in obj.__dict__

        setattr(obj, attrname, newvalue)
        eq_(
            attributes.get_history(obj, attrname), ([newvalue], (), [oldvalue])
        ) 
Example #10
Source File: test_merge.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_many_to_one_cascade(self):
        Address, addresses, users, User = (
            self.classes.Address,
            self.tables.addresses,
            self.tables.users,
            self.classes.User,
        )

        mapper(Address, addresses, properties={"user": relationship(User)})
        mapper(User, users)

        u1 = User(id=1, name="u1")
        a1 = Address(id=1, email_address="a1", user=u1)
        u2 = User(id=2, name="u2")

        sess = create_session()
        sess.add_all([a1, u2])
        sess.flush()

        a1.user = u2

        sess2 = create_session()
        a2 = sess2.merge(a1)
        eq_(attributes.get_history(a2, "user"), ([u2], (), ()))
        assert a2 in sess2.dirty

        sess.refresh(a1)

        sess2 = create_session()
        a2 = sess2.merge(a1, load=False)
        eq_(attributes.get_history(a2, "user"), ((), [u1], ()))
        assert a2 not in sess2.dirty 
Example #11
Source File: test_events.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_changes_reset(self):
        """test the contract of load/refresh such that history is reset.

        This has never been an official contract but we are testing it
        here to ensure it is maintained given the loading performance
        enhancements.

        """
        User = self.classes.User

        @event.listens_for(User, "load")
        def canary1(obj, context):
            obj.name = "new name!"

        @event.listens_for(User, "refresh")
        def canary2(obj, context, props):
            obj.name = "refreshed name!"

        sess = Session()
        u1 = User(name="u1")
        sess.add(u1)
        sess.commit()
        sess.close()

        u1 = sess.query(User).first()
        eq_(attributes.get_history(u1, "name"), ((), ["new name!"], ()))
        assert "name" not in attributes.instance_state(u1).committed_state
        assert u1 not in sess.dirty

        sess.expire(u1)
        u1.id
        eq_(attributes.get_history(u1, "name"), ((), ["refreshed name!"], ()))
        assert "name" not in attributes.instance_state(u1).committed_state
        assert u1 in sess.dirty 
Example #12
Source File: test_dynamic.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_merge(self):
        addresses = self.tables.addresses
        User, Address = self._user_address_fixture(
            addresses_args={"order_by": addresses.c.email_address}
        )
        sess = create_session()
        u1 = User(name="jack")
        a1 = Address(email_address="a1")
        a2 = Address(email_address="a2")
        a3 = Address(email_address="a3")

        u1.addresses.append(a2)
        u1.addresses.append(a3)

        sess.add_all([u1, a1])
        sess.flush()

        u1 = User(id=u1.id, name="jack")
        u1.addresses.append(a1)
        u1.addresses.append(a3)
        u1 = sess.merge(u1)
        eq_(attributes.get_history(u1, "addresses"), ([a1], [a3], [a2]))

        sess.flush()

        eq_(list(u1.addresses), [a1, a3]) 
Example #13
Source File: utils.py    From ReadableWebProxy with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def changeset(obj):
    """
    Return a humanized changeset for given SQLAlchemy declarative object. With
    this function you can easily check the changeset of given object in current
    transaction.

    ::


        from sqlalchemy_continuum_vendored import changeset


        article = Article(name=u'Some article')
        changeset(article)
        # {'name': [u'Some article', None]}

    :param obj: SQLAlchemy declarative model object
    """
    data = {}
    session = sa.orm.object_session(obj)
    if session and obj in session.deleted:
        columns = [c for c in sa.inspect(obj.__class__).columns.values()
                   if is_table_column(c)]

        for column in columns:
            if not column.primary_key:
                value = getattr(obj, column.key)
                if value is not None:
                    data[column.key] = [None, getattr(obj, column.key)]
    else:
        for prop in obj.__mapper__.iterate_properties:
            history = get_history(obj, prop.key)
            if history.has_changes():
                old_value = history.deleted[0] if history.deleted else None
                new_value = history.added[0] if history.added else None

                if new_value:
                    data[prop.key] = [new_value, old_value]
    return data 
Example #14
Source File: test_attributes.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_helpers(self):
        class Foo(object):
            pass

        class Bar(object):
            pass

        instrumentation.register_class(Foo)
        instrumentation.register_class(Bar)
        attributes.register_attribute(
            Foo, "coll", uselist=True, useobject=True
        )

        f1 = Foo()
        b1 = Bar()
        b2 = Bar()
        coll = attributes.init_collection(f1, "coll")
        assert coll.data is f1.coll
        assert attributes.get_attribute(f1, "coll") is f1.coll
        attributes.set_attribute(f1, "coll", [b1])
        assert f1.coll == [b1]
        eq_(attributes.get_history(f1, "coll"), ([b1], [], []))
        attributes.set_committed_value(f1, "coll", [b2])
        eq_(attributes.get_history(f1, "coll"), ((), [b2], ()))

        attributes.del_attribute(f1, "coll")
        assert "coll" not in f1.__dict__ 
Example #15
Source File: test_composites.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_get_history(self):
        Edge = self.classes.Edge
        Point = self.classes.Point
        from sqlalchemy.orm.attributes import get_history

        e1 = Edge()
        e1.start = Point(1, 2)
        eq_(
            get_history(e1, "start"),
            ([Point(x=1, y=2)], (), [Point(x=None, y=None)]),
        )

        eq_(get_history(e1, "end"), ((), [Point(x=None, y=None)], ())) 
Example #16
Source File: versioned_map.py    From sqlalchemy with MIT License 5 votes vote down vote up
def new_version(self, session):
        # convert to an INSERT
        make_transient(self)
        self.id = None

        # history of the 'elements' collection.
        # this is a tuple of groups: (added, unchanged, deleted)
        hist = attributes.get_history(self, "elements")

        # rewrite the 'elements' collection
        # from scratch, removing all history
        attributes.set_committed_value(self, "elements", {})

        # new elements in the "added" group
        # are moved to our new collection.
        for elem in hist.added:
            self.elements[elem.name] = elem

        # copy elements in the 'unchanged' group.
        # the new ones associate with the new ConfigData,
        # the old ones stay associated with the old ConfigData
        for elem in hist.unchanged:
            self.elements[elem.name] = ConfigValueAssociation(
                elem.config_value
            )

        # we also need to expire changes on each ConfigValueAssociation
        # that is to remain associated with the old ConfigData.
        # Here, each one takes care of that in its new_version()
        # method, though we could do that here as well. 
Example #17
Source File: db.py    From maple-blog with GNU General Public License v3.0 5 votes vote down vote up
def file_update_listen(mapper, connection, target):
    change = {
        "name": (target.name, target.name),
        "path": (target.path, target.path),
        "hash": (target.hash, target.hash),
    }
    history = get_history(target, "hash")
    if history.added and history.deleted:
        change["hash"] = (history.deleted[0], history.added[0])

    history = get_history(target, "name")
    if history.added and history.deleted:
        change["name"] = (history.deleted[0], history.added[0])

    history = get_history(target, "path")
    if history.added and history.deleted:
        change["path"] = (history.deleted[0], history.added[0])

    oldpath = os.path.join(
        change["path"][0].abspath,
        change["name"][0],
    )
    newpath = os.path.join(
        change["path"][1].abspath,
        change["name"][1],
    )
    file_change = change["hash"][0] != change["hash"][1]
    filepath_change = oldpath != newpath and os.path.exists(oldpath)

    if file_change and filepath_change:
        os.remove(oldpath)

    if not file_change and filepath_change:
        dirname = os.path.dirname(newpath)
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        os.rename(oldpath, newpath)

    dirname = os.path.dirname(oldpath)
    if not os.listdir(dirname):
        os.rmdir(dirname) 
Example #18
Source File: flask_cache.py    From ECache with MIT License 5 votes vote down vote up
def _flush_all(self, obj):
        for column in self._columns():
            added, unchanged, deleted = get_history(obj, column)
            for value in list(deleted) + list(added):
                self.flush(self._cache_key(**{column: value}))
        self.flush(self._cache_key())
        self.flush(self._cache_key(getattr(obj, self.pk)))