Skip to content

Instantly share code, notes, and snippets.

@ods
Created April 29, 2013 12:54
Show Gist options
  • Save ods/5481419 to your computer and use it in GitHub Desktop.
Save ods/5481419 to your computer and use it in GitHub Desktop.
Test case for implicit merge in SQLAlchemy when PK is set in transient object
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, ForeignKey, create_engine
from sqlalchemy.orm import sessionmaker, relationship
Base = declarative_base()
class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, primary_key=True)
#children = relationship('Child', cascade='all') # doesn't merge
children = relationship('Child', cascade='all,delete-orphan')
def __repr__(self):
return 'Parent(id=%r, children=%r)' % (self.id, self.children)
class Child(Base):
__tablename__ = 'children'
id = Column(Integer, primary_key=True)
parent_id = Column(ForeignKey(Parent.id), nullable=False)
parent = relationship(Parent)
data1 = Column(Integer, server_default='1', default=2)
data2 = Column(Integer, server_default='1', default=2)
def __repr__(self):
return 'Child(id=%r, data1=%r, data2=%r)' % (
self.id, self.data1, self.data2)
engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)
db = sessionmaker(bind=engine)()
p = Parent(children=[Child(data1=3, data2=3)])
db.add(p)
db.commit()
print p
p_id = p.id
c_id = p.children[0].id
db.expunge_all()
p = db.query(Parent).get(p_id)
#print p # Access to children might affect behavior
p.children = [Child(id=c_id, data1=None)]
db.commit()
db.expunge_all()
p = db.query(Parent).get(p_id)
print p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment