SQLAlchemy:如何在多态继承中将ForeignKeyConstraint用于父表?

时间:2016-10-09 20:11:37

标签: python sqlalchemy

我有一个模型,其中Edge是连接Node的关联对象,并且正在进行子类化以创建不同类型的Edge。我的最终目标是在Edge类本身(或稍后使用mixin)动态创建子类的所有字段。
Edge有一个复合主键,由Node表的两个外键和一个edge_type字段组成,它还充当子类的鉴别符。
为此,我需要将子类与ForeignKeyConstraint连接到Edge类的复合主键。现在,要动态创建此ForeignKeyConstraint,我使用@declared_attr定义它,但不能引用应该从edge_type表继承到子类的Edge列,但是我我得到以下例外情况:

File "/data/foo/venv/lib/python3.5/site-packages/sqlalchemy/util/_collections.py", line 194, in __getitem__
return self._data[key]
KeyError: 'edge_type'

During handling of the above exception, another exception occurred:

<snip>

sqlalchemy.exc.ArgumentError: Can't create ForeignKeyConstraint on table 'hierarchy': no column named 'edge_type' is present.

我的模型看起来像这样:

class Edge(HasTablename, Base):

    from_node_id = Column(Integer, ForeignKey(Node.id), primary_key=True)
    to_node_id = Column(Integer, ForeignKey(Node.id), primary_key=True)
    from_node = relationship(Node, foreign_keys=from_node_id,
                             backref=backref('from_edges')
    to_node = relationship(Node, foreign_keys=to_node_id,
                           backref=backref('to_edges')

    edge_type = Column(String, primary_key=True)

    @declared_attr
    def __mapper_args__(cls):
        if has_inherited_table(cls):
            return {'polymorphic_identity': cls.__name__.lower()}
        else:
            return {'polymorphic_identity': cls.__name__.lower(),
                    'polymorphic_on': cls.edge_type}

    @declared_attr
    def __table_args__(cls):
        if has_inherited_table(cls):
            return (ForeignKeyConstraint(
                       ['from_node_id', 'to_node_id', 'edge_type'],
                       [cls.__base__().__table__.c.from_node_id,
                        cls.__base__().__table__.c.to_node_id,
                        cls.__base__().__table__.c.edge_type]), )


class Hierarchy(Edge):

    from_node_id = Column(Integer, primary_key=True)
    to_node_id = Column(Integer, primary_key=True)


class History(Edge):

    from_node_id = Column(Integer, primary_key=True)
    to_node_id = Column(Integer, primary_key=True)

如果我在子类中显式定义edge_type = Column(String, primary_key=True),这可以正常工作,但我不知道它为什么不被继承,或者无法从@declared_attr中的ForeignKeyConstraint访问?

0 个答案:

没有答案