Skip to content

Instantly share code, notes, and snippets.

@ods
Last active December 24, 2015 12:09
Show Gist options
  • Save ods/6796065 to your computer and use it in GitHub Desktop.
Save ods/6796065 to your computer and use it in GitHub Desktop.
This schema fails as well as relationship definitions on both side with back_populates. Relationship definitions on both side without back_populates work fine. Exception is: sqlalchemy.orm.exc.FlushError: New instance <B at 0x2135e90> with identity key (<class '__main__.B'>, (1,)) conflicts with persistent instance <B at 0x212d850> Commenting th…
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, ForeignKey, create_engine
from sqlalchemy.orm import sessionmaker, Session, relationship
Base = declarative_base()
class AB(Base):
__tablename__ = 'AB'
a_id = Column(ForeignKey('A.id'), primary_key=True)
b_id = Column(ForeignKey('B.id'), primary_key=True)
class A(Base):
__tablename__ = 'A'
id = Column(Integer, primary_key=True)
b = relationship('B', secondary=AB.__table__, backref='a')
class B(Base):
__tablename__ = 'B'
id = Column(Integer, primary_key=True)
engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
b = B(id=1, a=[A(id=1)])
session.add(b)
session.commit()
b.a[0].b # <- Commenting this line changes exception to IntegrityError
b = B(id=1, a=[session.query(A).get(1)])
b = session.merge(b) # <- Fails
session.commit()
@zzzeek
Copy link

zzzeek commented Oct 2, 2013

its not merge.

session = sessionmaker(bind=engine)()

b = B(id=1, a=[A(id=1)])
session.add(b)
session.commit()

b.a[0].b # <- Commenting this line changes exception to IntegrityError

# you just cascaded a brand new B(id=1) into the Session via backref
b = B(id=1, a=[session.query(A).get(1)])

# boom
session.flush()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment