如何在SQLAlchemy中定义反向多态?

时间:2017-07-26 09:27:48

标签: python python-3.x sqlalchemy

父母

id  | child_type | child_id
--- | ---------- |--------
1   | Student    | 5
7   | Student    | 8
9   | Employee   | 3
15  | Employee   | 8
29  | Employee   | 12

id  | name
--- | ----------
1   | Jerry
..  | ...
5   | Alex
8   | Tom

员工

id  | name
--- | ----------
3   | John
..  | ...
8   | Mike
12  | Susan

文件

models.py

from sqlalchemy.ext.declarative import declarative_base, AbstractConcreteBase
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.sql.sqltypes import Integer, String

Base = declarative_base()


class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, pirmary_key=True)
    child_type = Column(String)
    child_id = Column(Integer)
    child = relationship('Child', uselist=False)


class Child(AbstractConcreteBase, Base):
    name = Column(String)


class Student(Child):
    __tablename__ = 'students'
    __mapper_args__ = {
        'polymorphic_identity': 'Student',
        'concrete': True
    }
    id = Column(Integer, ForeignKey(Parent.child_id), primary_key=True)


class Employee(Child):
    __tablename__ = 'employees'
    __mapper_args__ = {
        'polymorphic_identity': 'Employee',
        'concrete': True
    }
    id = Column(Integer, ForeignKey(Parent.child_id), primary_key=True)

main.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Parent

if __name__ == '__main__':
    engine = create_engine('mysql~~', encoding='utf-8')
    session = sessionmaker(bind=engine)()

    parent_success_1 = session.query(Parent).get(1)  # <Parent(id=1, child_type='Student', child_id=5)>
    assert parent_success_1.child.name == 'Alex'     # success

    parent_success_2 = session.query(Parent).get(15) # <Parent(id=15, child_type='Employee', child_id=8)>
    assert parent_success_2.child.name == 'Mike'     # success

    parent_failure = session.query(Parent).get(7)    # <Parent(id=7, child_type='Student', child_id=8)>
    assert parent_failure.child.name == 'Tom'        # failed
    # sqlalchemy.orm.exc.MultipleResultsFound: Multiple rows were found for one()

父有子指针via(child_type,child_id)。 所以我想通过set child_type,child_id。

来通过多态来访问子

但是当我使用rails的belongs_to多态样式列时,我无法从父级加载多态实例。

如果在父模型中设置uselist=True (default),请执行以下操作:

child = relationship('Child')

parent_failure.child返回:

[<Student(id=8, name='Tom')>, <Employee(id=8, name='Mike')>]

如何将polymorphic_on设置为父级的child_type列以供使用?

0 个答案:

没有答案