如何设置sqlalchemy relationsihp,以便subqueryload将根据属性

时间:2017-03-31 21:54:03

标签: python flask sqlalchemy

我有以下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可能是默认的,我只需要调整主连接。但它似乎没有做任何事情。

以下是正在生成的查询:

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

1 个答案:

答案 0 :(得分:0)

我明白了。

  1. 我需要使用secondaryjoin关键字而不是primaryjoin
  2. 我必须弄清楚填充手动连接的正确方法,即使用模型的型号名称和辅助表名称。
  3. self.db.relationship("tableB", secondary='and_(TableBModel.id==tableA_tableB.c.tableB, TableBModel.deleted.isnot(True))', secondary=tableA_tableB)