mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-15 05:07:16 -04:00
fb81f9c8d9
Also replace http://pypi.python.org/pypi with https://pypi.org/project Change-Id: I84b5005c39969a82140706472989f2a30b0c7685
174 lines
4.3 KiB
Python
174 lines
4.3 KiB
Python
"""Single-table (table-per-hierarchy) inheritance example."""
|
|
|
|
from sqlalchemy import Column
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy import ForeignKey
|
|
from sqlalchemy import inspect
|
|
from sqlalchemy import Integer
|
|
from sqlalchemy import or_
|
|
from sqlalchemy import String
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
from sqlalchemy.ext.declarative import declared_attr
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy.orm import with_polymorphic
|
|
|
|
|
|
Base = declarative_base()
|
|
|
|
|
|
class Company(Base):
|
|
__tablename__ = "company"
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(String(50))
|
|
|
|
employees = relationship(
|
|
"Person", back_populates="company", cascade="all, delete-orphan"
|
|
)
|
|
|
|
def __repr__(self):
|
|
return "Company %s" % self.name
|
|
|
|
|
|
class Person(Base):
|
|
__tablename__ = "person"
|
|
id = Column(Integer, primary_key=True)
|
|
company_id = Column(ForeignKey("company.id"))
|
|
name = Column(String(50))
|
|
type = Column(String(50))
|
|
|
|
company = relationship("Company", back_populates="employees")
|
|
|
|
__mapper_args__ = {
|
|
"polymorphic_identity": "person",
|
|
"polymorphic_on": type,
|
|
}
|
|
|
|
def __repr__(self):
|
|
return "Ordinary person %s" % self.name
|
|
|
|
|
|
class Engineer(Person):
|
|
|
|
engineer_name = Column(String(30))
|
|
primary_language = Column(String(30))
|
|
|
|
# illustrate a single-inh "conflicting" column declaration;
|
|
# see https://docs.sqlalchemy.org/en/latest/orm/extensions/
|
|
# declarative/inheritance.html#resolving-column-conflicts
|
|
@declared_attr
|
|
def status(cls):
|
|
return Person.__table__.c.get("status", Column(String(30)))
|
|
|
|
__mapper_args__ = {"polymorphic_identity": "engineer"}
|
|
|
|
def __repr__(self):
|
|
return (
|
|
"Engineer %s, status %s, engineer_name %s, "
|
|
"primary_language %s"
|
|
% (
|
|
self.name,
|
|
self.status,
|
|
self.engineer_name,
|
|
self.primary_language,
|
|
)
|
|
)
|
|
|
|
|
|
class Manager(Person):
|
|
manager_name = Column(String(30))
|
|
|
|
@declared_attr
|
|
def status(cls):
|
|
return Person.__table__.c.get("status", Column(String(30)))
|
|
|
|
__mapper_args__ = {"polymorphic_identity": "manager"}
|
|
|
|
def __repr__(self):
|
|
return "Manager %s, status %s, manager_name %s" % (
|
|
self.name,
|
|
self.status,
|
|
self.manager_name,
|
|
)
|
|
|
|
|
|
engine = create_engine("sqlite://", echo=True)
|
|
Base.metadata.create_all(engine)
|
|
|
|
session = Session(engine)
|
|
|
|
c = Company(
|
|
name="company1",
|
|
employees=[
|
|
Manager(
|
|
name="pointy haired boss", status="AAB", manager_name="manager1"
|
|
),
|
|
Engineer(
|
|
name="dilbert",
|
|
status="BBA",
|
|
engineer_name="engineer1",
|
|
primary_language="java",
|
|
),
|
|
Person(name="joesmith"),
|
|
Engineer(
|
|
name="wally",
|
|
status="CGG",
|
|
engineer_name="engineer2",
|
|
primary_language="python",
|
|
),
|
|
Manager(name="jsmith", status="ABA", manager_name="manager2"),
|
|
],
|
|
)
|
|
session.add(c)
|
|
|
|
session.commit()
|
|
|
|
c = session.query(Company).get(1)
|
|
for e in c.employees:
|
|
print(e, inspect(e).key, e.company)
|
|
assert set([e.name for e in c.employees]) == set(
|
|
["pointy haired boss", "dilbert", "joesmith", "wally", "jsmith"]
|
|
)
|
|
print("\n")
|
|
|
|
dilbert = session.query(Person).filter_by(name="dilbert").one()
|
|
dilbert2 = session.query(Engineer).filter_by(name="dilbert").one()
|
|
assert dilbert is dilbert2
|
|
|
|
dilbert.engineer_name = "hes dilbert!"
|
|
|
|
session.commit()
|
|
|
|
c = session.query(Company).get(1)
|
|
for e in c.employees:
|
|
print(e)
|
|
|
|
# query using with_polymorphic.
|
|
eng_manager = with_polymorphic(Person, [Engineer, Manager])
|
|
print(
|
|
session.query(eng_manager)
|
|
.filter(
|
|
or_(
|
|
eng_manager.Engineer.engineer_name == "engineer1",
|
|
eng_manager.Manager.manager_name == "manager2",
|
|
)
|
|
)
|
|
.all()
|
|
)
|
|
|
|
# illustrate join from Company,
|
|
eng_manager = with_polymorphic(Person, [Engineer, Manager])
|
|
print(
|
|
session.query(Company)
|
|
.join(Company.employees.of_type(eng_manager))
|
|
.filter(
|
|
or_(
|
|
eng_manager.Engineer.engineer_name == "engineer1",
|
|
eng_manager.Manager.manager_name == "manager2",
|
|
)
|
|
)
|
|
.all()
|
|
)
|
|
|
|
session.commit()
|