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.

Reply via email to