如何将自动过滤器添加到与 SQLAlchemy 的关系中?
Posted
技术标签:
【中文标题】如何将自动过滤器添加到与 SQLAlchemy 的关系中?【英文标题】:How to add an automatic filter to a relation with SQLAlchemy? 【发布时间】:2010-09-21 00:54:59 【问题描述】:我正在使用 SQLAlchemy 0.5rc,我想为关系添加一个自动过滤器,以便每次尝试获取该关系的记录时,如果它们被标记,它就会忽略“远程”记录作为“logically_deleted”(子表的布尔字段)
例如,如果对象“父”具有“子”关系,该关系具有
3 条记录,但其中一条在逻辑上已被删除,当我查询“父级”时,我希望 SQLA 能够
获取只有两个孩子的父对象..
我该怎么做?通过向primaryjoin添加“and”条件
关系的参数? (例如“Children.parent_id == Parent.id and Children.logically_deleted == False
”,但是这样写“and”是否正确?)
编辑: 我设法以这种方式做到了
children = relation("Children", primaryjoin=and_(id == Children.parent_id, Children.logically_deleted==False))
但是有没有办法将字符串用作primaryjoin?
【问题讨论】:
【参考方案1】:我目前只是在重新开发 0.4.something,但这是我的建议:
db.query(Object).filter(Object.first==value).filter(Object.second==False).all()
我认为这就是你想要做的,对吧?
(注意:用网络浏览器编写,不是真正的代码!)
【讨论】:
不,我正在寻找自动的东西。我会澄清这个问题 :) 谢谢! 不用担心。我想我了解您要做什么,但主要是阅读您提供的代码!【参考方案2】:and_() 函数是在 SQLAlchemy 中与 & 运算符一起进行逻辑连接的正确方法,但要小心后者,因为它具有令人惊讶的优先级规则,即比比较运算符具有更高的优先级。
您也可以将字符串用作 text() 构造函数的主要连接,但这会使您的代码因急切加载和连接附带的任何表别名而中断。
对于逻辑删除,最好将整个类映射到忽略已删除值的选择上:
mapper(Something, select([sometable], sometable.c.deleted == False))
【讨论】:
这可以翻译成使用 mapper_args 吗?我的意思是我使用的是声明性的。 我尝试在 mapper_args 中使用它,但我收到一条错误消息,提示“mapper() 为关键字参数 'local_table' 获取了多个值”。所以恐怕没用。【参考方案3】:但是有没有办法使用字符串作为 primaryjoin 代替?
您可以使用以下内容:
children = relationship("Children", primaryjoin="and_(Parent.id==Children.parent_id, Children.logically_deleted==False)"
这对我有用!
【讨论】:
以上是关于如何将自动过滤器添加到与 SQLAlchemy 的关系中?的主要内容,如果未能解决你的问题,请参考以下文章
您如何设置 sqlalchemy 关系ihp,以便子查询负载将根据属性过滤我们的结果