App Engine ndb. 基于引用属性查询模型

0 投票
1 回答
840 浏览
提问于 2025-04-17 19:47

我在使用AppEngine框架中的ndb查询一个对象时遇到了一些问题。我对ndb还很陌生,感觉自己可能误解了一些重要的概念。

这是我目前的代码:

我有一个叫做Teacher的模型:

from webapp2_extras.appengine.auth.models import User

class Teacher(ndb.Model):
    user = ndb.StructuredProperty(User)
    ranking = ndb.FloatProperty(required=True)

正如你所看到的,用户模型是来自webapp2框架的。然后我尝试查询与某个用户相关联的教师。我是这样做的:

def _findTeacher(self, user):
    t = Teacher.query(Teacher.user == user).fetch(1)
    if t:
        return t[0]
    else:
        return None

这个作为参数传入的用户是这样获取的:

user_session = self.auth.get_user_by_session()
user = self.auth.store.user_model.get_by_auth_token(user_session['user_id'], user_session['token'])[0]

但是,我得到了以下错误:

BadFilterError: invalid filter: Cannot query for non-empty repeated property auth_ids.

我真的很想知道我哪里出错了,如果能有一个使用ndb和webapp2认证系统的应用示例,那就太好了。

谢谢大家

1 个回答

1

来自 NDB 属性 的内容:

虽然一个结构化属性(StructuredProperty)可以重复使用,并且一个结构化属性可以包含另一个结构化属性,但要注意:如果一个结构化属性里面包含另一个结构化属性,那么只能有一个是可以重复的。

这个错误发生的原因是因为 Teacher.User 是一个结构化属性,它里面包含了 Teacher.User.auth_ids,而后者是一个可以重复的结构化属性。

编辑(解决方案):

我建议这样做:

class Teacher(ndb.Model):
    user = ndb.KeyProperty(User)
    ranking = ndb.FloatProperty(required=True)

存储一个用户的引用。对于你上面的例子,这样做是可行的。不过,这也意味着你不能查询用户的任何属性,比如 Teacher.User.name == 'bob'

你可以这样查询:

t = Teacher.query(Teacher.user == user.key).fetch(1)

希望这对你有帮助。

撰写回答