我有一个sqlalchemy声明模型,看起来像:
expr = or_(Post.owner == current_user, # current_user is ORM User1
Post.public == True,
Post.shared.contains(another_user))
posts = session.query(Post).filter(expr).all()
在我的测试数据库中,我有一个帖子Post1的用户User1。 Post1没有任何与之关联的共享用户。我尝试了一个查询:
posts
但是session.query(Post).filter(Post.owner == current_user).all() # returns Post1
session.query(Post).filter(Post.public == True).all() # returns Post1
session.query(Post).filter(Post.shared.contains(another_user)).all() # empty list as expected
是一个空列表。以下是各个查询:
or_
如果确认三个单独查询中有两个有效,原始Post.shared.contains(another_user)
的工作原理是什么?
编辑#1:
用Post.shared.any(User.id == another_user_id)
替换or_
可修复<?php
$custom_fields = get_option( 'wp_estate_custom_fields', true);
if(isset($custom_fields[0])){
for($i = 0; $i < count($custom_fields); ++$i) {
if($custom_fields[$i][0] != 'MYNAMEHERE') continue;
$name = $custom_fields[$i][0];
$label = $custom_fields[$i][1];
$type = $custom_fields[$i][2];
$order = $custom_fields[$i][3];
$dropdown_values = $custom_fields[$i][4];
$slug = str_replace(' ','_',$name);
$slug = wpestate_limit45(sanitize_title( $name ));
$slug = sanitize_key($slug);
$post_id = $post->ID;
$show = 1;
if (function_exists('icl_translate') ){
$label = icl_translate('wpestate','wp_estate_property_custom_front_'.$label, $label ) ;
}
if($i%2!=0){
print '<p class="half_form half_form_last">';
}else{
print '<p class="half_form">';
}
$value=$custom_fields_array[$slug];
wpestate_show_custom_field($show,$slug,$name,$label,$type,$order,$dropdown_values,$post_id,$value);
break;
}
}
?>
查询问题。但是现在我想知道为什么一个有效,另一个没有。
答案 0 :(得分:1)
您没有包含辅助表定义,但我认为它是这样的:
shared_post = Table(
'shared_post', Base.metadata,
Column('user_id', Integer,
ForeignKey('user.id', ondelete='cascade'), nullable=False),
Column('post_id', Integer,
ForeignKey('post.id', ondelete='cascade'), nullable=False)
)
调试SQLAlchemy查询的一个良好开端是尝试打印部分表达式甚至完整查询:
print(expr) # where expr is the original or_(...)
产量
:param_1 = post.owner_id OR post.public = 1 OR post.id = shared_post_1.post_id AND :param_2 = shared_post_1.user_id
我们看到.contains()
方法产生了一个隐式连接和一个没有括号的2个表达式的AND:连接谓词
post.id = shared_post_1.post_id
,第二个表达式是给定用户的实际检查
:param_2 = shared_post_1.user_id
因此,您的谓词现在由OR组成,后跟一个永远不会满足的AND。
完整查询
SELECT post.id AS post_id, post.owner_id AS post_owner_id, post.name AS post_name, post.public AS post_public
FROM post, shared_post AS shared_post_1
WHERE ? = post.owner_id OR post.public = 1 OR post.id = shared_post_1.post_id AND ? = shared_post_1.user_id