On 02/21/2017 03:56 PM, Shane Carey wrote:
I understand from the docs and several questions both here and on
bitbucket that cascading polymorphism is not supported. This
is what it says on the docs:
Warning
Currently, *only one discriminator column may be set*, typically on the
base-most class in the hierarchy. “Cascading” polymorphic columns are
not yet supported.
However, the following experiment works for me
it's possible that because you've named the column "type" on every
subclass, the value is shared as these are mapped to the same attribute
name by default (though I thought it emits a warning when this happens
implicitly).
The feature in general is not supported for the normal case when the
columns are differently named. A recipe to make this work is at
https://bitbucket.org/zzzeek/sqlalchemy/issues/2555/cascading-polymorphic-ons.
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
import json
Base = declarative_base()
class Top(Base):
__tablename__ = 'top'
id = Column(Integer, primary_key=True)
type = Column(String(8), nullable=False)
__mapper_args__ = {
'polymorphic_on': type,
'with_polymorphic': '*'
}
def dict(self):
return {
'id': self.id
}
class Primary(Top):
__tablename__ = 'primary'
id = Column(None, ForeignKey(Top.id), primary_key=True)
type = Column(String(8), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'primary',
'polymorphic_on': type,
'with_polymorphic': '*'
}
def dict(self):
return {
'type': self.type,
**super().dict()
}
class One(Primary):
__tablename__ = 'one'
id = Column(None, ForeignKey(Primary.id), primary_key=True)
one = Column(String(32), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'one'
}
def dict(self):
return {
'one': self.one,
**super().dict()
}
class Two(Primary):
__tablename__ = 'two'
id = Column(None, ForeignKey(Primary.id), primary_key=True)
two = Column(String(32), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'two'
}
def dict(self):
return {
'two': self.two,
**super().dict()
}
class Secondary(Top):
__tablename__ = 'secondary'
id = Column(None, ForeignKey(Top.id), primary_key=True)
type = Column(String(8), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'secondary',
'polymorphic_on': type,
'with_polymorphic': '*'
}
def dict(self):
return {
'type': self.type,
**super().dict()
}
class Three(Secondary):
__tablename__ = 'three'
id = Column(None, ForeignKey(Secondary.id), primary_key=True)
three = Column(String(32), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'three'
}
def dict(self):
return {
'three': self.three,
**super().dict()
}
class Four(Secondary):
__tablename__ = 'four'
id = Column(None, ForeignKey(Secondary.id), primary_key=True)
four = Column(String(32), nullable=False)
__mapper_args__ = {
'polymorphic_identity': 'four'
}
def dict(self):
return {
'four': self.four,
**super().dict()
}
if __name__ == '__main__':
e = create_engine('sqlite:///poly_casc.db', echo=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)
s = create_session(e)
s.begin()
s.add_all([One(one='one'), Two(two='two'), Three(three='three'),
Four(four='four')])
s.commit()
for m in s.query(Top).all():
print(json.dumps(m.dict(), indent=4))
print(type(m))
s.expunge_all()
for m in s.query(Primary).all():
print(json.dumps(m.dict(), indent=4))
print(type(m))
s.expunge_all()
for m in s.query(One).all():
print(json.dumps(m.dict(), indent=4))
print(type(m))
so I am wondering if the docs needed to be updated, or I am missing
something regarding the functionality.
Thanks
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and
Verifiable Example. See http://stackoverflow.com/help/mcve for a full
description.
---
You received this message because you are subscribed to the Google
Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to sqlalchemy+unsubscr...@googlegroups.com
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.