3

要在 Google App Engine 的 NDB 中检索实体,我需要fetch()afterquery()吗?例如:

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()如果我想在查询后检索 所有实体,是否需要使用?
4

3 回答 3

6

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

于 2013-03-14T13:47:10.340 回答
4
member_query = Member.query(Member.account==account)

member_query now contains a Query instance.

From there, you have a few options, but it seems that you would want to only grab ONE entity from this query. To do that, you'd say.

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

Now, member is either None if the account doesn't exist, or will contain a Member model instance.

If you use .fetch(), you can specify the number of entities you want to retrieve as the first argument, or use None (or no arguments) to grab all. If there are a lot of entities that match this condition, this could be time consuming.

Another paradigm would be to iterate over the query and break or return on the first entity that matches your conditions. This paradigm would allow you to do on-the-fly conditionals not covered by your query parameters. For example...

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

# No account
return None

Querying over this sort of membership model is less than ideal, however, because it will require a query to run every time. Of course, if you want a 'user' to have access to multiple 'profiles' (like Facebook User <-> Facebook Pages, as an example), you need something like this.

It's far more efficient to structure the list of "Profiles" that an account has access to, like so:

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):
    # ...

As you can see, this also let's you quickly determine if a user has access to a given profile.

于 2013-11-15T02:00:08.470 回答
2

member = Member.query(Member.account==account).get()意味着获得一个实例。

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

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

于 2014-04-06T12:46:59.100 回答