这是我的问题的精简版:
假设我有两个表:“过程”和“角色”。
角色有字段:(role_uid, role_name)
过程有字段:(procedure_uid, procedure_name, inform_role_uid, consult_role_uid)
所以 'role' 与 'procedure' 有两个一对多的关系。
部分代码:
class Role(Base):
__tablename__ = "role"
__table_args__ = ({'autoload':True, 'useexisting': True})
class Procedure(Base):
__tablename__ = "procedure"
__table_args__ = (sqlalchemy.ForeignKeyConstraint(['consult_role_uid','inform_role_uid'],['role.role_uid', 'role.role_uid']),
{'autoload':True, 'useexisting': True})
Procedure.consult_role = sqlalchemy.orm.relationship(Role,
primaryjoin="Procedure.consult_role_uid==Role.role_uid", foreign_keys=Role.role_uid)
Procedure.inform_role = sqlalchemy.orm.relationship(Role,
primaryjoin="Procedure.inform_role_uid==Role.role_uid", foreign_keys=Role.role_uid)
consult_role = sqlalchemy.orm.aliased(Role, name="consult_role")
inform_role = sqlalchemy.orm.aliased(Role, name="inform_role")
query = session.query(
Procedure.procedure_name,
consult_role.role_name.label("consult_role_name"),
inform_role.role_name.label("inform_role_name")).join(consult_role, inform_role)
这会产生以下 SQL:
SELECT
`procedure`.procedure_name AS procedure_procedure_name,
consult_role.role_name AS consult_role_name,
inform_role.role_name AS inform_role_name
FROM
`procedure`
INNER JOIN role AS consult_role
ON consult_role.role_uid = `procedure`.consult_role_uid
AND consult_role.role_uid = `procedure`.inform_role_uid
INNER JOIN role AS inform_role
ON inform_role.role_uid = `procedure`.consult_role_uid
AND inform_role.role_uid = `procedure`.inform_role_uid
如您所见,我无意让每个内部联接都加入两个字段。 为什么它似乎忽略了我的“primaryjoin”参数?
最佳答案
因此,为了完整起见,这里是上述问题的固定代码。我添加了两个 ForeignKeyContstaints,我还必须指定要在连接中使用的关系。
class Role(Base):
__tablename__ = "role"
__table_args__ = ({'autoload':True, 'useexisting': True})
class Procedure(Base):
__tablename__ = "procedure"
__table_args__ = (
sqlalchemy.ForeignKeyConstraint(['consult_role_uid'], ['role.role_uid']),
sqlalchemy.ForeignKeyConstraint(['inform_role_uid'], ['role.role_uid']),
{'autoload':True, 'useexisting': True})
Procedure.consult_role = sqlalchemy.orm.relationship(Role,
primaryjoin="Procedure.consult_role_uid==Role.role_uid", foreign_keys=Role.role_uid)
Procedure.inform_role = sqlalchemy.orm.relationship(Role,
primaryjoin="Procedure.inform_role_uid==Role.role_uid", foreign_keys=Role.role_uid)
consult_role = sqlalchemy.orm.aliased(Role, name="consult_role")
inform_role = sqlalchemy.orm.aliased(Role, name="inform_role")
query = session.query(
Procedure.procedure_name,
consult_role.role_name.label("consult_role_name"),
inform_role.role_name.label("inform_role_name")).join((consult_role, Procedure.consult_role), (inform_role, Procedure.inform_role))
这产生了以下正确的 SQL:
SELECT
`procedure`.procedure_name AS procedure_procedure_name,
consult_role.role_name AS consult_role_name,
inform_role.role_name AS inform_role_name
FROM
`procedure`
INNER JOIN role AS consult_role ON `procedure`.consult_role_uid = consult_role.role_uid
INNER JOIN role AS inform_role ON `procedure`.inform_role_uid = inform_role.role_uid
关于python - sqlalchemy:使用声明和反射多次连接到同一个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6819268/