Versioning and multi-level inheritance

40 views
Skip to first unread message

JPLaverdure

unread,
Jun 16, 2011, 11:20:33 AM6/16/11
to sqlalchemy
Hello,

I'm trying to use the versioning recipe describe on the website along
with a multi-level inheritance model (Joined-Table inheritance)

Here are my declarative statements:

[code]
class Sample(Base):
__metaclass__ = VersionedMeta
__tablename__ = 'sample'
__table_args__ = {'schema': 'test'}

id = Column(Integer, primary_key=True)
discriminator = Column('type', String(50))
token = Column(String(128), nullable=False)
source_sample_id = Column(Integer, ForeignKey('test.sample.id'))

children = relationship("Sample", backref=backref('source_sample',
remote_side=id), single_parent=True)

__mapper_args__ = {'polymorphic_on': discriminator,
'polymorphic_identity':'sample'}

def __init__(self, token, source_sample_id=None):
self.token = token
self.source_sample_id = source_sample_id

class Tissue(Sample):
__metaclass__ = VersionedMeta
__tablename__ = 'tissue'
__mapper_args__ = {'polymorphic_identity': 'tissue'}
__table_args__ = {'schema': 'test'}

id = Column(Integer, ForeignKey('test.sample.id'),
primary_key=True)
concentration = Column(String(32))

def __init__(self, token, concentration, source_sample_id=None):
super(Sample, self).__init__(token, source_sample_id)
self.concentration = concentration

class LeukemicTissue(Tissue):
__metaclass__ = VersionedMeta
__tablename__ = 'leukemic_tissue'
__mapper_args__ = {'polymorphic_identity': 'leukemic_tissue'}
__table_args__ = {'schema': 'test'}

id = Column(Integer, ForeignKey('test.tissue.id'),
primary_key=True)
leukemia = Column(String)

def __init__(self, token, concentration, leukemia,
source_sample_id=None):
super(Tissue, self).__init__(token, concentration,
source_sample_id)
self.leukemia = leukemia
[/code]


Whenever I try to "create_all()" I get the following error:
sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
between 'tissue_history' and 'leucegene_tissue_history'.

Single level-inheritance works beautifully (ie if I stop at "Tissue"
and don't declare the "LeukemicTissue") but I really need a multi-
level inheritance scheme to work..

Can anyone give me any pointers ?

Thanks !!

Michael Bayer

unread,
Jun 16, 2011, 12:05:41 PM6/16/11
to sqlal...@googlegroups.com
apply this patch to history_meta.py

diff -r 7c65c0cdd3c8 examples/versioning/history_meta.py
--- a/examples/versioning/history_meta.py Tue Jun 14 19:57:21 2011 -0400
+++ b/examples/versioning/history_meta.py Thu Jun 16 12:04:43 2011 -0400
@@ -35,7 +35,7 @@
col.unique = False

if super_mapper and col_references_table(column, super_mapper.local_table):
- super_fks.append((col.key, list(super_history_mapper.base_mapper.local_table.primary_key)[0]))
+ super_fks.append((col.key, list(super_history_mapper.local_table.primary_key)[0]))

cols.append(col)

as you can see, the foreign key generation is pulling from the "base" mapper which isn't the case in a multilevel situation, it needs to pull the FKs from the immediate super-mapper.

> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To post to this group, send email to sqlal...@googlegroups.com.
> To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
>

JPLaverdure

unread,
Jun 16, 2011, 1:24:41 PM6/16/11
to sqlalchemy
Fantastic ! And so quick to answer !

Thank you very much for your help, works like a charm now.
Has this patch been applied in the 0.7 release of sqlalchemy ? (I was
working with 0.6.7)

JP

gary clark

unread,
Jun 16, 2011, 4:57:01 PM6/16/11
to sqlal...@googlegroups.com
Hello,

I am trying to connect to another machine to access the mysql database. I have a firewall on one machine which restricts alot of the accesses from outside.

I am doing something like:

create_engine('mysql://root:p...@192.168.1.10/database',poolClass=NullPool)

Could someone be so kind and tell me what needs to be open on the other machine to connect and what the default port is?

Thanks,
Gary C

Michael Bayer

unread,
Jun 16, 2011, 5:00:09 PM6/16/11
to sqlal...@googlegroups.com
i committed it to 0.7.

technically the logic there should search up the chain of mappers for an FK in a parent table, its still making a bit of an assumption.

JPLaverdure

unread,
Aug 31, 2011, 10:28:05 AM8/31/11
to sqlal...@googlegroups.com
I just realised the following issue:

When I create the following relationship:

class Container(Base):
    __metaclass__ = VersionedMeta
    __tablename__ = 'container'
    __table_args__ = {'schema':'storage'}

    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'}

class Box(Container):
    __metaclass__ = VersionedMeta
    __tablename__ = 'box'
    __table_args__ = {'schema':'storage'}
    __mapper_args__ = {'polymorphic_identity': 'box'}
    
    id = Column(Integer, ForeignKey('storage.container.id', onupdate="cascade", ondelete="cascade"), primary_key=True)
    barcode = Column(String(64))

Even though box_history gets created, no "version" column is added to the box table and any modification to a Box entity does not log the change in the _history table.
Could anyone please point out what I'm doing wrong ?

I tried removing the metaclass declaration from the Box entity since it would basically inherit it from Container but that didn't help in solving my issue.

Thank you !!

Michael Bayer

unread,
Aug 31, 2011, 12:23:16 PM8/31/11
to sqlal...@googlegroups.com
"version" is only on your Container table since it will always have a row corresponding to each Box row, so "box.version" is not necessary.  You can change this by changing:

    if not super_history_mapper:
        cls.version = Column('version', Integer, default=1, nullable=False)

to:

        cls.version = Column('version', Integer, default=1, nullable=False)

then ensuring that Box.version is also written on update.





--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sqlalchemy/-/PK3kVAsuh5QJ.

JPLaverdure

unread,
Aug 31, 2011, 2:56:25 PM8/31/11
to sqlal...@googlegroups.com
Hi Michael,

Thank you for your reply.
Unfortunately, the mistake was all mine... 
At some point (and for an obscure reason...), I had stopped using the VersionedListener so changes were no longer registering in the DB :-/

So sorry !

JP

Jean-Philippe Laverdure

unread,
Aug 31, 2011, 2:55:09 PM8/31/11
to sqlal...@googlegroups.com
JP
--
Je-Pe

Reply all
Reply to author
Forward
0 new messages