Construir uma GQL com "consulta IN' para ReferenceProperty
-
10-07-2019 - |
Pergunta
classe Message (db.Model):
user = db.ReferenceProperty(User, required=True, collection_name='Message_set')
text = db.TextProperty(required=True)
Eu tentei isso, mas eu estou ficando BadValueError na declaração GQL.
users = []
users.append (userA)
users.append (userB)
users.append (UserC)
mensagens = Message.gql ( 'Onde usuário In: usuários', os usuários = usuários) .fetch (100)
Solução
É difícil dizer sem a stacktrace completo (por favor?), Mas eu acho que IN não gosta de ser entidades passaram em vez de chaves. Tente isto:
users = [userA.key(), userB.key(), userC.key()]
messages = Message.gql("WHERE user in :users", users=users).fetch(100
Outras dicas
O operador IN
em GQL é realmente sintetizado por em nível de aplicativo de código Python como um loop fazendo uma série de buscas =
e concatenando-los - não é realmente parte das capacidades do armazenamento subjacente e assim é, infelizmente, sujeito a algumas limitações (e seu desempenho não é particularmente bom). Eu não estou certo de que foi um grande decisão de projeto para incluí-lo na API do Python (eu acredito que não foi duplicado na API Java), mas, aí está você. (Btw, o operador !=
tem problemas semelhantes, também).
Eu não sei por que, em especial, esta deve interferir com o seu uso pretendido, mas eu suspeito que é devido ao objeto "consulta" ser uma instância de datastore.MultiQuery em vez de datastore.Query simples - o que acontece se você fizer em seu próprio código Python em nível de aplicativo que o nível de código Python aplicativo GAE fornecido normalmente faz? Veja em seu arquivo fontes SDK do Google / appengine / api / datastore.py, especificamente a classe MultiQuery - no final tudo se resume a fazer todas as consultas separadas e fundindo seus resultados (em ordem de classificação, se necessário, mas que doesn' t parece ser o caso aqui).
com este modelos:
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)
Esse código funciona:
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
Eu vi o awnser neste Grupos do Google publicar
Eu acho que você pode querer uma lista de chaves dos usuários? tente users.append (userA.key ()). O valor da ReferenceProperty usuário é a chave para uma entidade de usuário.