Создайте GQL с запросом IN для ReferenceProperty - PullRequest
3 голосов
/ 03 августа 2009

Сообщение класса (db.Model):

user = db.ReferenceProperty(User, required=True, collection_name='Message_set')  
text = db.TextProperty(required=True)

Я пробовал это, но я получаю BadValueError в операторе gql.

пользователи = []

users.append (ПользовательА)

users.append (UserB)

users.append (userC)

messages = Message.gql ('Где пользователь In: users', users = users) .fetch (100)

Ответы [ 4 ]

2 голосов
/ 03 августа 2009

Трудно сказать без полной трассировки стека (пожалуйста?), Но я думаю, что IN не любит, когда передаются сущности, а не ключи. Попробуйте это:

users = [userA.key(), userB.key(), userC.key()]
messages = Message.gql("WHERE user in :users", users=users).fetch(100
2 голосов
/ 03 августа 2009

Оператор IN в GQL фактически синтезируется кодом Python уровня приложения как цикл, выполняющий серию = выборок и их конкатенацию - на самом деле он не является частью возможностей основного хранилища и поэтому, к сожалению, подвержен некоторые ограничения (и его производительность никогда не бывает особенно хорошей). Я не уверен, что это было отличное дизайнерское решение - включить его в API-интерфейс Python (я полагаю, что оно не дублировалось в API Java), но вы здесь. (Кстати, у оператора != тоже есть похожие проблемы).

Я не уверен, почему, в частности, это должно мешать вашему предполагаемому использованию, но я подозреваю, что это связано с тем, что объект «запрос» является экземпляром datastore.MultiQuery, а не просто datastore.Query - что произойдет, если вы это сделаете в вашем собственном коде Python уровня приложения, что обычно делает код Python уровня приложения, предоставляемый GAE? Смотрите в вашем исходном файле SDK google / appengine / api / datastore.py, в частности, класс MultiQuery - в конце концов, он сводится к выполнению всех отдельных запросов и объединению их результатов (в порядке сортировки, если требуется, но это не так). похоже, дело именно в этом).

1 голос
/ 13 января 2010

с этими моделями:

class MyUsuario(db.Model):
    nombre=db.StringProperty(required=True)

class Message(db.Model):
    MyUsuario = db.ReferenceProperty(MyUsuario, required=True, collection_name='Message_set')  
    text = db.StringProperty(required=True)

Этот код работает:

from modelos import MyUsuario, Message
from google.appengine.ext import db

usuarios=MyUsuario.all()

userA=usuarios[0]
userB=usuarios[1]
userC=usuarios[2]

usuarios= []

usuarios.append(userA.key())
usuarios.append(userB.key())
usuarios.append(userC.key())

messages = db.GqlQuery('select * from Message Where MyUsuario In :usuari', usuari=usuarios)

for message in messages:
    print message.text

Я видел awnser в этом сообщении групп Google

0 голосов
/ 03 августа 2009

Я думаю, что вы хотите список ключей пользователей? попробуйте users.append (userA.key ()). Значение user referenceproperty является ключом для пользовательского объекта.

...