【问题标题】:Google App Engine NDB: need to fetch() after query?Google App Engine NDB:查询后需要 fetch() 吗?
【发布时间】:2013-03-14 13:27:29
【问题描述】:

要在 Google App Engine 的 NDB 中检索实体,是否需要在 query() 之后输入 fetch()?例如:

account = self.request.get('account')
member = Member.query(Member.account==account).fetch()
if member:   
    # Account exists
else:        
    # Account does not exist

我有两个问题:

  1. 如果使用.fetch(),代码运行正确。然而,如果 .fetch() 没用,测试总是正确的,这意味着一些 检索实体。有什么问题?
  2. 一般情况下,如果要检索,是否需要使用.fetch() 查询后的所有实体?

【问题讨论】:

  • 附带说明,我所知道的实现此条件的最快方法(如果您不需要实体)是if Member.query(...).get(keys_only=True):

标签: google-app-engine app-engine-ndb


【解决方案1】:

如果不使用 fetch(),则 member = Member.query(..) 将 Query 类实例分配给 member。所以你的 if 条件为真。

【讨论】:

  • 谢谢彼得,你有问题 2 的答案吗?
  • 是的,您需要使用 .fetch() 来检索所有实体。只需使用不带任何过滤器的查询。
  • 其实fetch()执行查询并返回结果。它不返回所有实体,只返回查询参数中定义的实体。
  • 我的意思是:我需要使用fetch() 来检索满足查询的实体吗?也就是members = Member.query(Member.age>20)还是members = Member.query(Member.age>20).fetch()?因为sometimes前者提供的结果适合后面的处理,但sometimes不适合。它们有什么区别?
  • @Tang 您所描述的是使用Member.query() 作为迭代器之间的区别(for ent in query 将分批检索结果并顺利迭代,或for ent in query.fetch() 将检索所有结果'up front' 并遍历实体列表。)
【解决方案2】:
member_query = Member.query(Member.account==account)

member_query 现在包含一个 Query 实例。

从那里,您有几个选项,但您似乎只想从此查询中获取一个实体。要做到这一点,你会说。

member = Member.query(Member.account==account).get()

现在,如果帐户不存在,则 member 为 None,或者将包含 Member 模型实例。

如果使用 .fetch(),则可以指定要检索的实体数量作为第一个参数,或使用 None(或无参数)获取所有实体。如果有很多实体符合此条件,这可能会很耗时。

另一种范例是遍历查询并中断或返回与您的条件匹配的第一个实体。此范例将允许您执行查询参数未涵盖的即时条件。比如……

for member in member_query:
    if member.active:
        return member

# No account
return None

但是,对这种成员资格模型进行查询并不理想,因为它每次都需要运行一个查询。当然,如果您希望“用户”能够访问多个“个人资料”(例如 Facebook 用户 Facebook 页面),您需要这样的东西。

构建帐户有权访问的“个人资料”列表的效率要高得多,如下所示:

class UserAccount(ndb.Model):
    """User Account"""

    """List of keys which reference profiles this user can access"""
    profiles = ndb.KeyProperty(repeated=True)

    def fetch_profiles(self):
        """Returns a list of profile entities this user can access"""
        return ndb.get_multi(profiles)

    def can_user_access_profile(self, profile):
        """Returns True if user can access 'profile' (either a ndb.Model or ndb.Key)"""
        if isinstance(profile, ndb.Model):
            profile = profile.key()  # Convert Model instances to a key

        return profile in self.profiles

class Profile(ndb.Model):
    # ...

如您所见,这还可以让您快速确定用户是否有权访问给定的个人资料。

【讨论】:

    【解决方案3】:

    member = Member.query(Member.account==account).get() 表示获取一个实例。

    members = Member.query(Member.account==account).fetch() 在列表中返回结果。

    memberQuery = Member.query(Member.account==account) 返回一个查询类,可以再次过滤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多