Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在SQLAlchemy中筛选时访问关系上的backref_Python_Python 3.x_Sqlalchemy - Fatal编程技术网

Python 在SQLAlchemy中筛选时访问关系上的backref

Python 在SQLAlchemy中筛选时访问关系上的backref,python,python-3.x,sqlalchemy,Python,Python 3.x,Sqlalchemy,我有一个名为ExtendedUser的表,它与User表有一对一的关系,在User表上有一个名为extended\u User的backref。User表与UserPosts表有一对多关系,在User表上有一个名为posts的backref 类用户(基本): __tablename_=“用户” id=列(整数,主键=True) 类UserPost(基): __tablename=“user\u posts” id=列(整数,主键=True) user\u id=列(整数,ForeignKey(“

我有一个名为
ExtendedUser
的表,它与
User
表有一对一的关系,在
User
表上有一个名为
extended\u User
的backref。
User
表与
UserPosts
表有一对多关系,在
User
表上有一个名为
posts
的backref

类用户(基本):
__tablename_=“用户”
id=列(整数,主键=True)
类UserPost(基):
__tablename=“user\u posts”
id=列(整数,主键=True)
user\u id=列(整数,ForeignKey(“users.id”))
用户=关系(“用户”,backref=“posts”)
类延伸器(基本):
__tablename=“扩展用户”
user\u id=Column(整数,ForeignKey(“users.id”),primary\u key=True)
用户=关系(“用户”,backref=“扩展用户”,uselist=False,lazy=“已加入”)
extendeducer
开始,我想选择
extendeducer
s中
User
s没有post的所有
extendeducer
s。 所以我尝试做的失败是

sess.query(ExtendedUser.filter)(而不是(ExtendedUser.user.posts.any())
但这不起作用,我得到一个错误:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with ExtendedUser.user has an attribute 'posts'

如何对查询进行建模,以便仅返回其
User
具有
UserPost
s的
ExtendedUser
s?

发生错误的原因是
.User
属性是不同的,这取决于您是从类还是从类的实例访问它。例如,这会引发您正在获得的异常:

ExtendedUser.user.posts
这是因为访问类
扩展程序
上的
.user
会返回一个
InstrumentedAttribute
对象,并且
InstrumentedAttribute
的实例没有名为
posts
的属性

这项工作:

inst=ExtendedUser()
仪器用户职位
上述方法之所以有效,是因为我们访问了
.user
的一个
ExtendedUser
实例,该实例返回一个名为
posts
user
实例

类和实例属性访问之间的这种不同行为由Python的

实现目标的一种方法是使用子查询在
user\u posts
表中查询唯一的
user\u id
s,并测试
extender
user\u id
不在结果中:

q = sess.query(ExtendedUser).\
    filter(
        not_(
            ExtendedUser.user_id.in_(
                sess.query(UserPost.user_id).distinct()
            )
        )
    )
下面是一个工作示例,但首先我必须稍微更改
ExtendedUser.user
的定义:

类扩展控制器(基本):
...
用户=关系(
“用户”,backref=backref(“扩展用户”,uselist=False),lazy=“已加入”)
注意使用了
backref
功能,该功能允许我在
User.extended\u User
上设置
uselist=False
。您的示例在
ExtendedUser.user
上有
uselist=False
,但不需要它,因为外键是在
ExtendedUser
上定义的,因此
ExtendedUser.user
只能指向一个用户,sqlalchemy将自动知道集合不应该是列表。如果没有这个更改,我将得到一个
TypeError:compatible collection type:ExtendedUser不是类似列表的
异常

好的,下面是一个例子:

sess = Session()
user_1 = User(extended_user=ExtendedUser())
user_2 = User(extended_user=ExtendedUser())
user_3 = User(extended_user=ExtendedUser())
user_1.posts = [UserPost()]
sess.add_all([user_1, user_2, user_3])
sess.commit()
q = sess.query(ExtendedUser).\
    filter(
        not_(
            ExtendedUser.user_id.in_(
                sess.query(UserPost.user_id).distinct()
            )
        )
    )

print(q.all())  # [ExtendedUser(user_id=2), ExtendedUser(user_id=3)]

谢谢,这是一个很好的解决方案。我使用的方法来自我的实体框架背景,在那里类似的表达式可以无缝工作。我现在意识到SQLAlchemy可能更接近纯SQL(较低级别),这意味着它没有那么神奇,但生成的查询可能更简单。我不能给你投票,因为我的代表率低,如果可以的话,我会给你投票。对不起,不用担心,很乐意帮忙。很可能还有其他的解决方案,我觉得这只是一个直截了当的解决方案。祝你一切顺利。