<p dir="auto"><strong>Migrated issue, originally created by Adrian (<a href="https://github.com/thiefmaster">@thiefmaster</a>)</strong></p>
<p dir="auto">I have the following code: <a href="https://gist.github.com/ThiefMaster/9cea43683142912e5ffb0fa3b5d8d0a9">https://gist.github.com/ThiefMaster/9cea43683142912e5ffb0fa3b5d8d0a9</a></p>
<p dir="auto">It fails with a circular dependency error even though there is only a change to <code class="notranslate">p</code> (however, both <code class="notranslate">p</code> and <code class="notranslate">gal</code> show up in<br>
<code class="notranslate">sess.dirty</code> when I print it right before the commit, but <code class="notranslate">is_modified</code> only returns True for <code class="notranslate">p</code>).</p>
<p dir="auto">It also works fine if I uncomment the expire call - but of course that's an awful workaround. <code class="notranslate">post_update=True</code> on the <code class="notranslate">gallery</code><br>
relationship also does the job but it seems like an SQLAlchemy bug to me since there's only one object with changes which can be flushed/committed just fine if I do<br>
a manual expire...</p>
<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. when doing "whos-dependent-on-who", if both instances are already persistent, there should be no dependency between them and post_update should not be needed.  ex:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="from sqlalchemy import *
from sqlalchemy.orm import *

meta = MetaData(create_engine('sqlite://'))

contacts = Table('contacts', meta,
   Column('id', Integer, primary_key=True),
   Column('name', String(50)),
   Column('created_by', Integer),
   Column('updated_by', Integer),
   ForeignKeyConstraint(['created_by']('created_by'), ['contacts.id']('contacts.id')),
   ForeignKeyConstraint(['updated_by']('updated_by'), ['contacts.id']('contacts.id'))
)

meta.create_all()

class Contact(object):
    def __init__(self, name, created_by=None):
        self.name = name
        self.created_by = created_by

    def __eq__(self, other):
        return other.name == self.name
        
    def __repr__(self):
        return &quot;Contact(created_by=%r, updated_by=%r)&quot; % (self.created_by, self.updated_by)


mapper(Contact, contacts, properties={
   '_created_by': contacts.c.created_by,
   '_updated_by': contacts.c.updated_by,
   'created_by': relation(Contact, primaryjoin=contacts.c.created_by==contacts.c.id,
           remote_side=[contacts.c.id](contacts.c.id)),
   'updated_by': relation(Contact,primaryjoin=contacts.c.updated_by==contacts.c.id,
            remote_side=[contacts.c.id](contacts.c.id),
           backref=backref('updated_by_me', primaryjoin=contacts.c.updated_by==contacts.c.id),
    )
})

sess = create_session()

c1 = Contact('c1')

c2 = Contact('c2', created_by=c1)
c3 = Contact('c3', created_by=c1)
c3.updated_by = c2

sess.save(c1)
sess.save(c2)
sess.save(c3)
sess.flush()

c2.updated_by = c1
c3.updated_by = c1
sess.flush()

c2.updated_by=c3
c3.updated_by = c2
sess.flush()  # &lt;--- fails.  no INSERTs are happening here so UPDATEs should handle it fine"><pre class="notranslate"><code class="notranslate">from sqlalchemy import *
from sqlalchemy.orm import *

meta = MetaData(create_engine('sqlite://'))

contacts = Table('contacts', meta,
   Column('id', Integer, primary_key=True),
   Column('name', String(50)),
   Column('created_by', Integer),
   Column('updated_by', Integer),
   ForeignKeyConstraint(['created_by']('created_by'), ['contacts.id']('contacts.id')),
   ForeignKeyConstraint(['updated_by']('updated_by'), ['contacts.id']('contacts.id'))
)

meta.create_all()

class Contact(object):
    def __init__(self, name, created_by=None):
        self.name = name
        self.created_by = created_by

    def __eq__(self, other):
        return other.name == self.name
        
    def __repr__(self):
        return "Contact(created_by=%r, updated_by=%r)" % (self.created_by, self.updated_by)


mapper(Contact, contacts, properties={
   '_created_by': contacts.c.created_by,
   '_updated_by': contacts.c.updated_by,
   'created_by': relation(Contact, primaryjoin=contacts.c.created_by==contacts.c.id,
           remote_side=[contacts.c.id](contacts.c.id)),
   'updated_by': relation(Contact,primaryjoin=contacts.c.updated_by==contacts.c.id,
            remote_side=[contacts.c.id](contacts.c.id),
           backref=backref('updated_by_me', primaryjoin=contacts.c.updated_by==contacts.c.id),
    )
})

sess = create_session()

c1 = Contact('c1')

c2 = Contact('c2', created_by=c1)
c3 = Contact('c3', created_by=c1)
c3.updated_by = c2

sess.save(c1)
sess.save(c2)
sess.save(c3)
sess.flush()

c2.updated_by = c1
c3.updated_by = c1
sess.flush()

c2.updated_by=c3
c3.updated_by = c2
sess.flush()  # &lt;--- fails.  no INSERTs are happening here so UPDATEs should handle it fine
</code></pre></div>