python - sqlalchemy:使用声明和反射多次连接到同一个表

标签 python sqlalchemy

这是我的问题的精简版:

假设我有两个表:“过程”和“角色”。

角色有字段:(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/

相关文章:

python - 聚合数据框列

Python - 在列表中搜索多个值并执行多个操作

python - 在 Python 中解析 JSON

python - Pandas - 转置一列

python - 与 SQLAlchemy-Continuum 的多对多关系插入具有重复 transaction_id 的记录

sqlalchemy - 如何使用 SqlAlchemy 和 pymssql 为 MS SQL 设置查询超时?

python - 如何防止特定类在 SQLAlchemy 中被更新/删除?

python - sqlalchemy 如何与 automap_base 生成(多对多)关系

python - 在 SQLAlchemy Core 中使用 `with` 上下文管理器我如何知道事务是否回滚?

python - "for loop"有两个变量?