【问题标题】:SQLAlchemy: Single Table Inheritance, same column in childsSQLAlchemy:单表继承,子表中的同一列
【发布时间】:2013-06-14 15:00:19
【问题描述】:

我目前使用单表继承策略映射一个类层次结构(我不可能使用joined)。此层次结构可能如下所示:

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)

问题是我想在Child1Child2 上都有一个property1,而不是在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 的实例值未存储在数据库中)

谁能指出如何重用已经由另一个子类定义的列?

【问题讨论】:

    标签: python orm sqlalchemy single-table-inheritance


    【解决方案1】:

    直接改编自 Resolving Column Conflicts 的文档:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-04
      • 1970-01-01
      • 2011-10-10
      • 2023-03-30
      • 1970-01-01
      • 2020-12-07
      相关资源
      最近更新 更多