possible post_update regression in 0.6

Issue #1807 resolved
Mike Bayer repo owner created an issue
from sqlalchemy import Table, Column, Integer, String, MetaData,create_engine, ForeignKey, ForeignKeyConstraint
from sqlalchemy.orm import relation, sessionmaker, scoped_session,synonym, object_session, mapper, backref

engine = create_engine('sqlite:///', echo=False)

Session = scoped_session(sessionmaker(autoflush=True,autocommit=False, bind=engine))
metadata = MetaData()

contacts = Table('contacts', metadata,
             Column('id', Integer, primary_key=True),
             Column('name', String(35)),
             Column('account_id', Integer),
             ForeignKeyConstraint(['account_id']('account_id'), ['accounts.id']('accounts.id')))

accounts = Table('accounts', metadata,
                Column('id', Integer, primary_key=True),
                Column('name', String(35)),
                Column('created_by_id', Integer),
                ForeignKeyConstraint(['created_by_id']('created_by_id'),['contacts.id']('contacts.id'), name='fk1', use_alter=True))

class Contact(object): pass
class Account(object): pass

mapper(Contact, contacts, properties={
   'account': relation(Account,

primaryjoin=contacts.c.account_id==accounts.c.id,
                       post_update=True,
                       #backref=backref('contacts', post_update=True)
                       backref='contacts'
                       )
})
mapper(Account, accounts, properties={
   'created_by': relation(Contact,primaryjoin=accounts.c.created_by_id==contacts.c.id),
   #'contacts': relation(Contact,primaryjoin=accounts.c.id==contacts.c.account_id)
})

metadata.create_all(bind=engine)

# create basic data
frank = Contact()
frank.name = "Frank"
Session.add(frank)

finc = Account()
finc.name = "Frank Inc."
frank.account = finc
Session.add(finc)

Session.commit()
Session.expunge_all()

# reproduce the problem
bob = Contact()
bob.name = 'Bob'
Session.add(bob)

frank = Session.query(Contact).filter_by(name='Frank').first()
finc = frank.account

bob.account = finc

assert bob.account == finc
Session.commit()
assert bob.account == finc

If either backref on the 'account' relation of Contact is set then the UPDATE fails to issue. If the 'contacts' relation is defined directly on Account or the backref isn't defined at all then everything works as expected. This is tested on SQLAlchemy 0.6.0 with Python 2.6. I verified this as working under 0.5.8.

Comments (3)

  1. Log in to comment