我正在测试设置 SQLAlchemy 以映射现有数据库。该数据库是很久以前由我们不再使用的以前的第 3 方应用程序自动建立的,因此未定义一些预期的东西,例如外键约束。该软件将管理所有这些关系。
它是一种节点式的生产跟踪数据库结构,具有父子关系。特定于节点类型的数据存在于它们自己的表中,并且有一个用于常见列(如 type、uid、parentUid、...)的主关系表
结构是这样的...
- 基本上包含每个节点条目的层次结构表,具有主键“uid”、“type”枚举和用于引用父节点的“parentUid”。
- NodeA / NodeB / ...表有一个与层次表一一匹配的“uid”
我从 SQLAlchemy 文档中收集到的是我应该尝试做“加入”表。这是我到目前为止所拥有的:
# has a column called 'parentUid'
hierarchy = Table('hierarchy', METADATA, autoload=True)
hier_fk = lambda: Column('uid',
Integer,
ForeignKey('hierarchy.uid'),
primary_key=True)
nodeTypeA = Table('nodetype_a', METADATA, nodehier_fk(), autoload=True)
nodeTypeB = Table('nodetype_b', METADATA, nodehier_fk(), autoload=True)
Base = declarative_base()
class NodeA(Base):
__table__ = join(hierarchy, nodeTypeA)
id = column_property(hierarchy.c.uid, nodeTypeA.c.uid)
uid = nodeTypeA.c.uid
class NodeB(Base):
__table__ = join(hierarchy, nodeTypeB)
id = column_property(hierarchy.c.uid, nodeTypeB.c.uid)
uid = nodeTypeB.c.uid
# cannot figure this one out
parent = relationship("NodeA", primaryjoin="NodeB.parentUid==NodeA.id")
relationship
显然是错误的并且崩溃了。我已经尝试了一堆定义foreign_keys
属性的组合,并使用混合hierarchy.c.uid
样式方法。但我只是无法掌握如何与另一张桌子建立关系。
没有这relationship
条线,查询效果很好。我得到了加入层次表的每个节点的完整表示。我什至可以通过执行以下操作手动获取 NodeB 的 NodeA 父级:
node_a = session.query(NodeA).filter_by(uid=node_b.parentUid).first()
“加入”方法是否适合我的目标?我怎样才能让这种关系发挥作用?
更新
到目前为止,我已经设法通过以下方式建立了一种单向关系:
children = relationship("NodeB",
primaryjoin="NodeB.parentUid==NodeA.id",
foreign_keys=[hierarchy.c.parentUid],
# backref="parent"
)
但是如果我取消注释backref
让它把它放在相反的位置上NodeB
,我会得到这个:
ArgumentError: NodeA.children 和反向引用 NodeB.parent 都是相同的方向。您的意思是在多对一上设置 remote_side 吗?