2013-03-14 6 views
3

Чтобы получить объекты в NDB приложения Google App Engine, нужно ли мне fetch() после query()? Например:Google App Engine NDB: нужно выбрать() после запроса?

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(), если я хочу получить все объектов по запросу?
+0

В качестве примечания стороны, самый быстрый способ, которым я знаю для достижения этого условия (если вам не нужен объект), является 'if Member.query (...).get (keys_only = True): ' – Josh

ответ

6

Если fetch() не используется, то member = Member.query(..) назначает экземпляр класса Query в member. Итак, ваше условие if истинно.

+0

Спасибо, Питер, у вас есть ответ на вопрос 2? –

+0

Да, вам нужно использовать .fetch() для извлечения всех объектов. Просто используйте запрос без каких-либо фильтров. –

+0

Фактически 'fetch()' выполняет запрос и возвращает результаты. Он не возвращает _all_ сущности, только те, которые определены в параметрах запроса. –

4
member_query = Member.query(Member.account==account) 

member_query теперь содержит экземпляр запроса.

Оттуда у вас есть несколько вариантов, но вам кажется, что вы хотите получить только один объект из этого запроса. Для этого вы бы сказали.

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

Теперь член либо отсутствует, если учетная запись не существует, либо будет содержать экземпляр модели участника.

Если вы используете .fetch(), вы можете указать количество объектов, которые хотите получить в качестве первого аргумента, или использовать None (или без аргументов), чтобы захватить все. Если есть много объектов, которые соответствуют этому условию, это может занять много времени.

Еще одна парадигма заключалась бы в повторении запроса и обрыве или возврате первого объекта, соответствующего вашим условиям. Эта парадигма позволит вам выполнять условия «на лету», не охватываемые вашими параметрами запроса. Например ...

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

# No account 
return None 

Запрос над такого рода модели членства меньше, чем идеал, однако, поскольку это потребует запроса для запуска каждый раз. Конечно, если вы хотите, чтобы «пользователь» имел доступ к нескольким «профилям» (например, Facebook User < -> Страницы в 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): 
    # ... 

Как вы можете видеть, это также давайте быстро определить, если пользователь имеет доступ к данный профиль.

2

member = Member.query(Member.account==account).get() означает получить один экземпляр.

members = Member.query(Member.account==account).fetch() возвращает результат в списке.

memberQuery = Member.query(Member.account==account) возвращает класс запроса, который может быть отфильтрован снова.

Смежные вопросы