簡體   English   中英

SQLAlchemy:單表繼承,子項中的相同列

[英]SQLAlchemy: Single Table Inheritance, same column in childs

我目前使用單表繼承策略映射類層次結構(我不可能使用join)。 此層次結構可能如下所示:

class Parent(Base):
    __tablename__ = 'mytable'
    __mapper_args__ = {
        'polymorphic_on' : type,
        'polymorphic_identity' : 'parent'
    }

    id = Column(Integer, primary_key = True)
    type = Column(String(32), nullable = False)

class Child1(Parent):
    __mapper_args__ = { 'polymorphic_identity' : 'child1' }

    property1 = Column(Integer)

class Child2(Parent):
    __mapper_args__ = { 'polymorphic_identity' : 'child2' }

    property1 = Column(Integer)

class Child3(Parent):
    __mapper_args__ = { 'polymorphic_identity' : 'child3' }

    other_property = Column(Integer)

那么問題是,我想有一個property1兩個Child1Child2但不是在Child3 上面的當前代碼導致錯誤:

sqlalchemy.exc.ArgumentError: Column 'property1' on class <class
'__main__.Child2'>  conflicts with existing column 'mytable.property1'

我當然可以添加其他層的繼承層次其中Child1Child2從派生,並包含property1列,但Child1Child2幾乎不彼此相關,但我想重用這兩個類相同的數據庫列。

我已經嘗試將property1 = Child1.property1添加到Child2但是沒有用(實例值沒有存儲在Child2的數據庫中)

任何人都可以指出如何重用已經由另一個子類定義的列?

直接從解決列沖突中的文檔進行調整:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'mytable'

    id = Column(Integer, primary_key = True)
    type = Column(String(32), nullable = False)
    __mapper_args__ = {
        'polymorphic_on' : type,
        'polymorphic_identity' : 'parent'
    }

class Child1(Parent):
    __mapper_args__ = { 'polymorphic_identity' : 'child1' }

    @declared_attr
    def property1(cls):
        return Parent.__table__.c.get('property1', Column(Integer))

class Child2(Parent):
    __mapper_args__ = { 'polymorphic_identity' : 'child2' }

    @declared_attr
    def property1(cls):
        return Parent.__table__.c.get('property1', Column(Integer))

class Child3(Parent):
    __mapper_args__ = { 'polymorphic_identity' : 'child3' }

    other_property = Column(Integer)

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

s = Session(e)
s.add_all([Child1(property1=1), Child2(property1=2), Child3(other_property=3)])
s.commit()

for p in s.query(Parent):
    if isinstance(p, (Child1, Child2)):
        print p.property1
    elif isinstance(p, Child3):
        print p.other_property

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM