您如何设置 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 的关系中?

如何根据SqlAlchemy关系设置模型默认值?

如何将sqlalchemy中列的默认值设置为关系中列的值?

如何在sqlalchemy before_insert事件中添加模型的关系实例?

如何在 SQLAlchemy 中设置 M2M 混合计数属性?

Sqlalchemy:过滤关系中应该有多少个实例