Pregunta

Estoy en una situación en la que necesito abarcar las relaciones de entidad de Google App Engine en una consulta como en el modelo de base de datos Django . Estoy usando ListProperty s para relaciones de uno a muchos, así:

class Foo(db.Model): bars = db.ListProperty(db.Key)
class Bar(db.Model): eggs = db.ListProperty(db.Key)

Y me gustaría realizar una consulta que haga lo siguiente:

# Foo.filter('bars.eggs =', target_egg)
[foo
for egg in eggs if egg == target_egg
for eggs in bar.eggs
for bar in foo.bars
for foo in Foo.all()]

La comprensión parece radicalmente ineficiente. Realmente me gustaría realizar una consulta como en la parte comentada, pero no se parece a la sintaxis de GQL permite realizar consultas contra los atributos de los atributos:

   SELECT * FROM <kind>
    [WHERE <condition> [AND <condition> ...]]
    [ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]]
    [LIMIT [<offset>,]<count>]
    [OFFSET <offset>]

  <condition> := <property> {< | <= | > | >= | = | != } <value>
  <condition> := <property> IN <list>
  <condition> := ANCESTOR IS <entity or key>
¿Fue útil?

Solución

Tienes razón, el almacén de datos de App Engine no permite este tipo de consulta. Y tiene razón en que la comprensión de la lista es ineficiente. Sin embargo, considere que eso es exactamente lo que hace una base de datos relacional cuando ejecuta una consulta con uniones como la suya: la base de datos tiene que realizar el mismo trabajo O (n ^ 3) que está haciendo aquí, la única diferencia es que lo estás haciendo en Python y con tiempo adicional de ida y vuelta. Dado que App Engine está diseñado para escalar, en realidad no está hecho para este tipo de consultas.

Por lo general, sin embargo, hay una manera de desnormalizar un poco su modelo para facilitar esto, moviendo algunas de las propiedades que necesita para acceder al modelo Foo, o si está haciendo agregados, moviendo el total al Foo modelo. Sin embargo, es difícil dar soluciones concretas sin tener más idea de qué problema está tratando de resolver.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top