如何在SQLAlchemy中为关系添加自动过滤器?

10 投票
3 回答
2717 浏览
提问于 2025-04-11 09:35

我正在使用 SQLAlchemy 0.5rc,想给一个关系添加自动过滤功能。这样每次它尝试获取这个关系的记录时,如果有记录被标记为“逻辑删除”(这是子表中的一个布尔字段),就会忽略这些记录。

举个例子,如果一个“父”对象有一个“孩子”关系,里面有3条记录,但其中一条被逻辑删除了,当我查询“父”对象时,我希望 SQLA 只获取这个父对象的两个孩子。
我该怎么做呢?是通过在关系的 primaryjoin 参数中添加一个“和”条件吗?(比如说 "Children.parent_id == Parent.id and Children.logically_deleted == False",这样写“和”对吗?)

编辑:
我已经这样做成功了

children = relation("Children", primaryjoin=and_(id == Children.parent_id, Children.logically_deleted==False))

但是有没有办法用字符串作为 primaryjoin 呢?

3 个回答

0

我现在只是在开发0.4.x版本的东西,不过我建议你可以这样做:

db.query(Object).filter(Object.first==value).filter(Object.second==False).all()

我觉得这就是你想要做的,对吧?

(注意:这是在网页浏览器里写的,不是真正的代码!)

11

但是有没有办法用字符串作为主连接呢?

你可以使用下面的代码:

children = relationship("Children", primaryjoin="and_(Parent.id==Children.parent_id, Children.logically_deleted==False)"

这个方法对我有效!

4

and_() 函数是 SQLAlchemy 中进行逻辑与运算的正确方法,另外你也可以使用 & 运算符,但要小心,因为它的优先级规则有点让人意外,也就是说,它的优先级比比较运算符还要高。

你也可以用字符串作为主要的连接方式,使用 text() 构造函数,但这样做会导致你的代码在使用表别名和急加载时出错。

对于逻辑删除,最好是将整个类映射到一个忽略已删除值的选择上:

mapper(Something, select([sometable], sometable.c.deleted == False))

撰写回答