Last active
December 7, 2021 21:45
-
-
Save nicoddemus/26de7bbcdfa9ed4b14fcfdde72b1d63f to your computer and use it in GitHub Desktop.
Replicate the example from https://docs.sqlalchemy.org/en/14/_modules/examples/inheritance/joined.html using classic mappings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pathlib import Path | |
import attr | |
from sqlalchemy import Column | |
from sqlalchemy import create_engine | |
from sqlalchemy import ForeignKey | |
from sqlalchemy import Integer | |
from sqlalchemy import MetaData | |
from sqlalchemy import String | |
from sqlalchemy import Table | |
from sqlalchemy.orm import registry | |
from sqlalchemy.orm import relationship | |
from sqlalchemy.orm import sessionmaker | |
class Person: | |
pass | |
@attr.s(auto_attribs=True) | |
class Manager(Person): | |
name: str | |
data: str | |
@attr.s(auto_attribs=True) | |
class Engineer(Person): | |
name: str | |
info: int | |
@attr.s(auto_attribs=True) | |
class Company: | |
people: list[Person] | |
metadata = MetaData() | |
mapper_registry = registry() | |
persons_table = Table( | |
"person", | |
metadata, | |
Column("id", Integer, primary_key=True, autoincrement=True), | |
Column("type", String(50)), | |
) | |
managers_table = Table( | |
"manager", | |
metadata, | |
Column('id', ForeignKey("person.id"), primary_key=True), | |
Column("name", String(50)), | |
Column("data", String(50)), | |
) | |
engineers_table = Table( | |
"engineer", | |
metadata, | |
Column('id', ForeignKey("person.id"), primary_key=True), | |
Column("name", String(50)), | |
Column("info", Integer), | |
) | |
company_table = Table( | |
"company", | |
metadata, | |
Column("id", Integer, primary_key=True), | |
) | |
company_2_people_table = Table( | |
"company_2_people", | |
metadata, | |
Column("id", Integer, primary_key=True, autoincrement=True), | |
Column("company_id", ForeignKey("company.id")), | |
Column("person_id", ForeignKey("person.id")), | |
) | |
person_mapper = mapper_registry.map_imperatively( | |
Person, | |
persons_table, | |
polymorphic_identity="person", | |
polymorphic_on=persons_table.c.type, | |
) | |
manager_mapper = mapper_registry.map_imperatively( | |
Manager, | |
managers_table, | |
inherits=person_mapper, | |
polymorphic_identity="manager", | |
) | |
engineer_mapper = mapper_registry.map_imperatively( | |
Engineer, | |
engineers_table, | |
inherits=person_mapper, | |
polymorphic_identity="engineer", | |
) | |
company_mapper = mapper_registry.map_imperatively( | |
Company, | |
company_table, | |
properties={ | |
"people": relationship( | |
person_mapper, | |
secondary=company_2_people_table, | |
collection_class=list, | |
), | |
}, | |
) | |
fn = Path(__file__).with_suffix(".db") | |
fn.unlink(missing_ok=True) | |
engine = create_engine(f"sqlite:///{fn}", echo=False) | |
metadata.create_all(engine) | |
Session = sessionmaker(bind=engine) | |
with Session() as session: | |
m1 = Manager(name="Manager 1", data="Manager Data") | |
m2 = Manager(name="Manager 2", data="Manager Data") | |
e1 = Engineer(name="Eng 1", info=10) | |
e2 = Engineer(name="Eng 2", info=30) | |
company = Company([e2, m1, e1, m2]) | |
session.add(company) | |
session.commit() | |
with Session() as session: | |
print(session.query(Company).get(1)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Asked for help on Stack Overflow: https://stackoverflow.com/questions/66921914/using-polymorphic-classes-in-classic-mappings-styleFound the solution, the code above now works as expected. 👍