On 11/16/2016 10:18 AM, Michael Williamson wrote:
When using AbstractConcreteBase to implement inheritance with a
separate table per type (and no common table), it seems like properties
that are present on all of the subtypes are lifted up onto the super
type. Is there a way to get the same behaviour when using joined table
inheritance? For instance, at the moment, the below fails since
Employee.name doesn't exist. Is there a way to get Employee.name to be
automatically generated from the subtypes?


Joined table inheritance assumes column names are unique for a given inheritance hierarchy unless special steps are taken to resolve how the duplicate names will be handled. This is because multiple tables are queried to produce a single row. This is not analogous to concrete inheritance where each row is the product of only one table at a time.

In this case, to have engineer.name as well as employee.name, you'd need to use a different attribute name to distinguish them, but also there's no automatic movement of columns from the subclass to the superclass. That would occur if Manager / Engineer were *single* table inheritance, but not for joined.





    from __future__ import unicode_literals

    from sqlalchemy import create_engine, Column, Integer, String,
    ForeignKey from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import Session


    Base = declarative_base()


    class Employee(Base):
        __tablename__ = "employee"
        __mapper_args__ = {
            "polymorphic_on": "discriminator",
        }
        id = Column(Integer, primary_key=True)
        discriminator = Column(String)


    class Manager(Employee):
        __tablename__ = "manager"
        __mapper_args__ = {
            "polymorphic_identity": "manager",
        }

        id = Column(Integer, ForeignKey(Employee.id), primary_key=True)
        name = Column(String)


    class Engineer(Employee):
        __tablename__ = "engineer"
        __mapper_args__ = {
            "polymorphic_identity": "employee",
        }

        id = Column(Integer, ForeignKey(Employee.id), primary_key=True)
        name = Column(String)

    engine = create_engine("sqlite:///:memory:", echo=True)

    Base.metadata.create_all(engine)
    session = Session(engine)

    session.add(Engineer(name="Jim"))
    session.add(Manager(name="Jules"))
    session.commit()

    print(session.query(Employee.name).all())


For comparison, when using AbstractConcreteBase, it's possible to
reference Employee.name:

    from __future__ import unicode_literals

    from sqlalchemy import create_engine, Column, Integer, String
    from sqlalchemy.ext.declarative import declarative_base,
    AbstractConcreteBase from sqlalchemy.orm import Session


    Base = declarative_base()


    class Employee(AbstractConcreteBase, Base):
        pass


    class Manager(Employee):
        __tablename__ = "manager"
        __mapper_args__ = {
            "polymorphic_identity": "manager",
            "concrete": True
        }

        id = Column(Integer, primary_key=True)
        name = Column(String)


    class Engineer(Employee):
        __tablename__ = "engineer"
        __mapper_args__ = {
            "polymorphic_identity": "employee",
            "concrete": True,
        }

        id = Column(Integer, primary_key=True)
        name = Column(String)

    engine = create_engine("sqlite:///:memory:", echo=True)

    Base.metadata.create_all(engine)
    session = Session(engine)

    session.add(Engineer(name="Jim"))
    session.add(Manager(name="Jules"))
    session.commit()

    print(session.query(Employee.name).all())


Thanks (both in advance for this question, and for putting up with my
other questions!)

Michael


--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to