我有一个模型,其中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访问?