class Sample(Base):
__metaclass__ = VersionedMeta
__tablename__ = 'sample'
__table_args__ = {'schema':'test'}
id = Column(Integer, primary_key=True)
token = Column(String(64))
box_id = Column(Integer, ForeignKey('
test.box.id', onupdate='cascade', ondelete='cascade'), nullable=False)
def __init__(self, token, box):
self.token = token
self.box = box
class Container(Base):
__metaclass__ = VersionedMeta
__tablename__ = 'container'
__table_args__ = {'schema':'test'}
id = Column(Integer, primary_key=True)
discriminator = Column('type', String(64))
token = Column(String(128), nullable=False)
description = Column(String)
__mapper_args__ = {'polymorphic_on': discriminator, 'polymorphic_identity':'container'}
def __init__(self, token, description=''):
self.token = token
self.description = description
class Box(Container):
__tablename__ = 'box'
__table_args__ = {'schema':'test'}
__mapper_args__ = {'polymorphic_identity': 'box'}
id = Column(Integer, ForeignKey('
test.container.id', onupdate="cascade", ondelete="cascade"), primary_key=True)
barcode = Column(String(64))
samples = relationship('Sample', backref='box')
def __init__(self, token, description='', barcode=''):
super(Box, self).__init__(token, description)
self.barcode = barcode
Base.metadata.drop_all()
Base.metadata.create_all()
Session = scoped_session(sessionmaker(extension=VersionedListener()))
sess = Session()
b = Box('Big box', 'sample1')
sess.add(b)
s = Sample('New sample', b)
sess.add(s)
sess.commit()
sess.delete(b)
sess.commit()
This fails because of the "nullable=False" clause on the Sample foreign key as SQLA seems to try to update the sample to set box_id to null...
2011-09-20 11:41:51,021 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2011-09-20 11:41:51,022 INFO sqlalchemy.engine.base.Engine SELECT test.container.type AS test_container_type,
test.box.id AS test_box_id,
test.container.id AS test_container_id, test.container.token AS test_container_token, test.container.description AS test_container_description, test.container.version AS test_container_version, test.box.barcode AS test_box_barcode
2011-09-20 11:41:51,023 INFO sqlalchemy.engine.base.Engine {'param_1': 1}
2011-09-20 11:41:51,025 INFO sqlalchemy.engine.base.Engine SELECT
test.sample.id AS test_sample_id, test.sample.token AS test_sample_token, test.sample.box_id AS test_sample_box_id, test.sample.version AS test_sample_version
FROM test.sample
WHERE %(param_1)s = test.sample.box_id
2011-09-20 11:41:51,025 INFO sqlalchemy.engine.base.Engine {'param_1': 1}
2011-09-20 11:41:51,028 INFO sqlalchemy.engine.base.Engine INSERT INTO test.container_history (id, type, token, description, version) VALUES (%(id)s, %(type)s, %(token)s, %(description)s, %(version)s)
2011-09-20 11:41:51,028 INFO sqlalchemy.engine.base.Engine {'token': u'Big box', 'version': 1, 'type': u'box', 'id': 1, 'description': u'sample1'}
2011-09-20 11:41:51,029 INFO sqlalchemy.engine.base.Engine INSERT INTO test.box_history (id, barcode, version) VALUES (%(id)s, %(barcode)s, %(version)s)
2011-09-20 11:41:51,029 INFO sqlalchemy.engine.base.Engine {'barcode': u'', 'id': 1, 'version': 1}
2011-09-20 11:41:51,031 INFO sqlalchemy.engine.base.Engine UPDATE test.sample SET box_id=%(box_id)s WHERE
test.sample.id = %(test_sample_id)s
2011-09-20 11:41:51,031 INFO sqlalchemy.engine.base.Engine {'box_id': None, 'test_sample_id': 1}
2011-09-20 11:41:51,032 INFO sqlalchemy.engine.base.Engine ROLLBACK
So it does indeed seem to visit the sample, but I must be doing something wrong in my declaration because SQLA should be attempting to delete the sample not update it !