<p dir="auto"><strong>Migrated issue, originally created by Michael Bayer (<a href="https://github.com/zzzeek">@zzzeek</a>)</strong></p>
<p dir="auto">i.e.:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="    def get_history(self, state, passive=PASSIVE_OFF):
        return History.from_attribute(
            self, state, state.dict.get(self.key, NO_VALUE))"><pre class="notranslate"><code class="notranslate">    def get_history(self, state, passive=PASSIVE_OFF):
        return History.from_attribute(
            self, state, state.dict.get(self.key, NO_VALUE))
</code></pre></div>
<p dir="auto">should be more like:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="    def get_history(self, state, passive=PASSIVE_OFF):
        if self.key in state.dict:
            return History.from_attribute(self, state, state.dict[self.key](self.key))
        else:
            current = self.get(state, passive=passive)
            if current is PASSIVE_NORESULT:
                return HISTORY_BLANK
            else:
                return History.from_attribute(self, state, current)"><pre class="notranslate"><code class="notranslate">    def get_history(self, state, passive=PASSIVE_OFF):
        if self.key in state.dict:
            return History.from_attribute(self, state, state.dict[self.key](self.key))
        else:
            current = self.get(state, passive=passive)
            if current is PASSIVE_NORESULT:
                return HISTORY_BLANK
            else:
                return History.from_attribute(self, state, current)
</code></pre></div>
<p dir="auto">this to support extensions which need to get attribute history regardless of an object being expired or having deferred columns.  workaround is to force a load using getattr().  but the passive flag shouldn't be silently ignored.</p>
<p dir="auto">however, SA's ORM doesn't need this itself, and the fact that it's ignored right now might be fulfilling part of the current behavioral contract, i.e. don't load the old value unnecessarily.  So ensure that get_history() is always called with PASSIVE_OFF for scalars right now and that honoring the flag doesn't result in unnecessary loads.</p>
<p dir="auto"><strong>Migrated issue, originally created by Anonymous</strong></p>
<p dir="auto">We are doing some stuff with history and have a little problem.</p>
<p dir="auto">After commit, history has been reseted to empty state: there no value in <code class="notranslate">unchanged</code> and after attribute is changed there is no value in <code class="notranslate">deleted</code>.</p>
<p dir="auto">Probably, it is a bug. If it is correct behaviour, how is it expained?</p>
<p dir="auto">Both on 0.8.2 and dev versions. Here is a test case.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class HistoryTest(_fixtures.FixtureTest):
    run_inserts = None

    def test_commit_history(self):
        from sqlalchemy.orm.attributes import get_history, History

        User, users = self.classes.User, self.tables.users

        m2 = sa.MetaData()
        users_unbound = users.tometadata(m2)
        mapper(User, users_unbound)

        sess = Session(binds={User: self.metadata.bind})
        u = User(id=1, name='daniel')
        sess.add(u)
        print get_history(u, 'name')
        assert get_history(u, 'name') ==\
                         History(['daniel']('daniel'), (), ())

        sess.commit()
        print get_history(u, 'name')
        assert get_history(u, 'name') == \
                         History((), ['daniel']('daniel'), ())
                         # fails: History((), (), ())

        u.name = 'peter'
        print get_history(u, 'name')
        assert get_history(u, 'name') == \
                         History(['peter']('peter'), (), ['daniel']('daniel'))
                         # fails: History(['peter']('peter'), (), ())"><pre class="notranslate"><code class="notranslate">class HistoryTest(_fixtures.FixtureTest):
    run_inserts = None

    def test_commit_history(self):
        from sqlalchemy.orm.attributes import get_history, History

        User, users = self.classes.User, self.tables.users

        m2 = sa.MetaData()
        users_unbound = users.tometadata(m2)
        mapper(User, users_unbound)

        sess = Session(binds={User: self.metadata.bind})
        u = User(id=1, name='daniel')
        sess.add(u)
        print get_history(u, 'name')
        assert get_history(u, 'name') ==\
                         History(['daniel']('daniel'), (), ())

        sess.commit()
        print get_history(u, 'name')
        assert get_history(u, 'name') == \
                         History((), ['daniel']('daniel'), ())
                         # fails: History((), (), ())

        u.name = 'peter'
        print get_history(u, 'name')
        assert get_history(u, 'name') == \
                         History(['peter']('peter'), (), ['daniel']('daniel'))
                         # fails: History(['peter']('peter'), (), ())
</code></pre></div>
<hr>
<p dir="auto">Attachments: <a href="../wiki/imported_issue_attachments/2787/2787.patch">2787.patch</a></p>