您如何设置 sqlalchemy 关系ihp,以便子查询负载将根据属性过滤我们的结果
Posted
技术标签:
【中文标题】您如何设置 sqlalchemy 关系ihp,以便子查询负载将根据属性过滤我们的结果【英文标题】:how do you set up a sqlalchemy relationsihp, such that the subqueryload will filter our results based on an attribute 【发布时间】:2017-03-31 21:54:03 【问题描述】:我有以下 sqlalchemy 模型/表:
Table('tableA',
MetaData(bind=None),
Column('id', BigInteger()),
Column('deleted', Boolean())
schema=None)
Table('tableA_tableB',
MetaData(bind=None),
Column('tableB', BigInteger(), ForeignKey('tableB.id'), table=<tableA_tableB>),
Column('tableA', BigInteger(), ForeignKey('tableA.id'), table=<tableA_tableB>),
schema=None)
Table('tableB',
MetaData(bind=None),
Column('id', BigInteger()),
Column('deleted', Boolean())
schema=None)
以下代码创建了one-to-many
关系:
self.db.relationship("tableB", secondary=tableA_tableB)
这在运行子查询加载时按预期工作,它返回所有连接的结果。但是,现在我需要设置关系,以便它只返回已删除不为 True 的子项。
我尝试在关系函数中使用 primaryjoin
关键字,但我几乎没有取得任何进展。
self.db.relationship("tableB",
primaryjoin='and_(tableB.id==tableA_tableB.tableB,
tableB.deleted.isnot(True))',
secondary=tableA_tableB)
我的想法是因为我使用的是辅助表,所以secondaryjoin可能是默认的,我只需要调整primaryjoin。但它似乎没有做任何事情。
这是正在生成的查询:
SELECT tableB.deleted AS tableB_deleted,
anon_1.tableA_id AS anon_1_tableA_id
FROM
(SELECT tableA.id AS tableA_id
FROM tableA
WHERE tableA.deleted IS NOT TRUE
GROUP BY tableA.id LIMIT %(param_1)s) AS anon_1
JOIN tableA_tableB AS tableA_tableB_1 ON anon_1.tableA_id = tableA_tableB_1.tableA
JOIN tableB ON tableB.id = tableA_tableB_1.tableB
ORDER BY anon_1.tableA_id
这是我需要它生成的查询:
SELECT tableB.deleted AS tableB_deleted,
anon_1.tableA_id AS anon_1_tableA_id
FROM
(SELECT tableA.id AS tableA_id
FROM tableA
WHERE tableA.deleted IS NOT TRUE
GROUP BY tableA.id LIMIT %(param_1)s) AS anon_1
JOIN tableA_tableB AS tableA_tableB_1 ON anon_1.tableA_id = tableA_tableB_1.tableA
JOIN tableB ON tableB.id = tableA_tableB_1.tableB
WHERE tableb.deleted IS NOT TRUE
ORDER BY anon_1.tableA_id
【问题讨论】:
在这种情况下,tableB 不是您的孩子吗?换句话说,您不应该使用secondaryjoin=...
。您应该考虑提供一个最小、完整且可验证的示例。虽然可以从您包含的内容中推断出映射的类和查询,但如果不必这样做,它会使回答变得容易得多。
工作代码的公平点。
【参考方案1】:
我想通了。
-
我需要使用secondaryjoin 关键字而不是primaryjoin
我必须找出填充手动联接的正确方法,即使用模型的模型名称和辅助表名称。
self.db.relationship("tableB",
secondary='and_(TableBModel.id==tableA_tableB.c.tableB,
TableBModel.deleted.isnot(True))',
secondary=tableA_tableB)
【讨论】:
以上是关于您如何设置 sqlalchemy 关系ihp,以便子查询负载将根据属性过滤我们的结果的主要内容,如果未能解决你的问题,请参考以下文章
如何在sqlalchemy before_insert事件中添加模型的关系实例?