A classe de consulta

Nota: os programadores que criam novas aplicações são fortemente aconselhados a usar a biblioteca de cliente NDB, que tem várias vantagens em comparação com esta biblioteca de cliente, como o armazenamento em cache automático de entidades através da API Memcache. Se estiver a usar atualmente a biblioteca cliente DB mais antiga, leia o guia de migração de DB para NDB

A classe Query representa uma consulta para obter entidades do App Engine Datastore. (Consulte também a classe relacionada GqlQuery, que define consultas através de GQL, uma linguagem de consulta semelhante a SQL.)

Query está definido no módulo google.appengine.ext.db.

Nota: o mecanismo de consulta baseado em índice suporta uma vasta gama de consultas e é adequado para a maioria das aplicações. No entanto, não suporta alguns tipos de consultas comuns noutras tecnologias de bases de dados. Em particular, as junções e as consultas agregadas não são suportadas no motor de consultas do Datastore. Consulte a página Consultas do Datastore para ver as limitações das consultas do Datastore.

Introdução

Uma aplicação cria um objeto de consulta para um determinado tipo de entidade chamando o construtor Query diretamente

class Song(db.Model):
  title = db.StringProperty()
  composer = db.StringProperty()
  date = db.DateTimeProperty()

q = db.Query(Song)

ou o método da classe all() da classe do modelo do tipo:

q = Song.all()

Sem mais modificações, a instância resultante da classe Query vai obter todas as entidades existentes do tipo especificado. As chamadas de métodos no objeto podem ser usadas para personalizar a consulta com critérios de filtro adicionais, condições de ascendentes e ordens de ordenação:

q.filter('title =', 'Imagine')
q.ancestor(ancestor_key)
q.order('-date')

Para maior conveniência, todos estes métodos devolvem o próprio objeto de consulta para que possam ser em cascata numa única declaração:

q.filter('title =', 'Imagine').ancestor(key).order('-date')

Em seguida, a aplicação pode executar a consulta e aceder aos resultados de qualquer uma das seguintes formas:

  • Trate o objeto de consulta como um objeto iterável para processar as entidades correspondentes uma de cada vez:

    for song in q:
      print song.title

    Isto chama implicitamente o método run() da consulta para gerar as entidades correspondentes. Assim, é equivalente a

    for song in q.run():
      print song.title

    Pode definir um limite para o número de resultados a processar com o argumento de palavra-chave limit:

    for song in q.run(limit=5):
      print song.title

    A interface do iterador não armazena em cache os resultados, pelo que a criação de um novo iterador a partir do objeto de consulta reitera a mesma consulta desde o início.

  • Chame o método get() da consulta para obter a primeira entidade correspondente única encontrada no Datastore:

    song = q.get()
    print song.title
  • Chame o método fetch() da consulta para obter uma lista de todas as entidades correspondentes até um número especificado de resultados:

    results = q.fetch(limit=5)
    for song in results:
      print song.title

    Tal como acontece com run(), o objeto de consulta não armazena em cache os resultados, pelo que chamar fetch() uma segunda vez volta a emitir a mesma consulta.

    Nota: raramente deve usar este método. Quase sempre é melhor usar run() em alternativa.

Construtor

O construtor da classe Query é definido da seguinte forma:

class Query (model_class=None, keys_only=False, cursor=None, namespace=None, projection=None, distinct=False)

Cria uma instância da classe Query para obter entidades a partir do App Engine Datastore.

Sem modificações adicionais, o objeto de consulta resultante vai obter todas as entidades existentes do tipo especificado por model_class. Os métodos de instância filter(), ancestor(), e order() podem ser usados para personalizar a consulta com critérios de filtro adicionais, condições de antepassados e ordens de ordenação.

Argumentos

model_class
Classe de modelo (ou expansão) que representa o tipo de entidade ao qual a consulta se aplica.
keys_only
Se true, devolve apenas chaves em vez de entidades completas. As consultas apenas com chaves são mais rápidas e baratas do que as que devolvem entidades completas.
cursor
Posição do cursor na qual retomar a consulta.
namespace
Espaço de nomes a usar para a consulta.
projeção
Lista ou tuplo de nomes de propriedades a devolver. Apenas são devolvidas as entidades que possuem as propriedades especificadas. Se não for especificado, são devolvidas entidades completas por predefinição. As consultas de projeção são mais rápidas e baratas do que as que devolvem entidades completas.

Nota: a especificação deste parâmetro pode alterar os requisitos de índice da consulta.

distintos
No caso de consultas de projeção, distinct=True especifica que apenas os resultados totalmente únicos são devolvidos num conjunto de resultados. Isto só devolve o primeiro resultado para entidades que têm os mesmos valores para as propriedades que estão a ser projetadas.
Verdadeiro
Devolve apenas o primeiro resultado para cada conjunto distinto de valores para propriedades na projeção.
Falso
São devolvidos todos os resultados.

Métodos de instância

As instâncias da classe Query têm os seguintes métodos:

filter (property_operator, value)

Adiciona um filtro de propriedade à consulta. A consulta devolve apenas entidades cujas propriedades satisfazem todos os respetivos filtros.

Argumentos

property_operator
String composta por um nome de propriedade e um operador de comparação opcional (=, !=, <, <=, >, >=, IN), separados por um espaço: por exemplo, 'age >'. Se for especificado apenas um nome da propriedade sem um operador de comparação, o filtro compara a igualdade (=) por predefinição.
valor
Valor a comparar com o valor da propriedade. Por exemplo:

q.filter('height >', 42).filter('city =', 'Seattle')
q.filter('user =', users.get_current_user())

O valor de comparação especificado deve ser do mesmo tipo de valor que o da propriedade que está a ser comparada.

ancestor (ancestor)

Adiciona um filtro de antepassado à consulta. A consulta devolve apenas entidades com o antecessor especificado.

Argumento

ancestor
Entidade ou chave principal.
order (property)

Adiciona uma ordem de ordenação à consulta. Se for adicionada mais do que uma ordem de ordenação, estas são aplicadas na ordem especificada.

Argumento

propriedade
String que indica o nome da propriedade pela qual ordenar, opcionalmente precedida por um hífen (-) para especificar a ordem descendente. A omissão do hífen especifica a ordem ascendente por predefinição. Por exemplo:
# Order alphabetically by last name:
q.order('last_name')

# Order by height, tallest to shortest:
q.order('-height')
projection ()

Devolve a tupla de propriedades na projeção ou None.

is_keys_only ()

Devolve um valor booleano que indica se a consulta é uma consulta apenas de chaves.

run (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=None, batch_size=20, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Devolve um iterável para percorrer os resultados da consulta. Isto permite-lhe especificar a operação da consulta com definições de parâmetros e aceder aos resultados de forma iterativa:

  1. Obtém e rejeita o número de resultados especificado pelo argumento offset.
  2. Obtém e devolve até ao número máximo de resultados especificado pelo argumento limit.

Assim, o desempenho do ciclo é dimensionado linearmente com a soma de offset + limit. Se souber quantos resultados quer obter, deve definir sempre um valor limit explícito.

Este método usa a obtenção prévia assíncrona para melhorar o desempenho. Por predefinição, obtém os respetivos resultados do Datastore em pequenos lotes, o que permite à aplicação parar a iteração e evitar a obtenção de mais resultados do que os necessários.

Sugestão: para obter todos os resultados disponíveis quando o respetivo número é desconhecido, defina batch_size para um valor elevado, como 1000.

Dica: se não precisar de alterar os valores dos argumentos predefinidos, pode usar o objeto de consulta diretamente como um iterável para controlar o ciclo. Isto chama implicitamente run() com argumentos predefinidos.

Argumentos

read_policy
Leia a política que especifica o nível de consistência de dados pretendido:
STRONG_CONSISTENCY
Garante os resultados mais recentes, mas está limitado a um único grupo de entidades.
EVENTUAL_CONSISTENCY
Pode abranger vários grupos de entidades, mas, ocasionalmente, pode devolver resultados desatualizados. Em geral, as consultas eventualmente consistentes são executadas mais rapidamente do que as consultas fortemente consistentes, mas não existe qualquer garantia.

Nota: as consultas globais (não antecessoras) ignoram este argumento.

deadline
Tempo máximo, em segundos, de espera para que o Datastore devolva um resultado antes de anular com um erro. Aceita um número inteiro ou um valor de vírgula flutuante. Não pode ser definido acima do valor predefinido (60 segundos), mas pode ser ajustado para baixo para garantir que uma operação específica falha rapidamente (por exemplo, para devolver uma resposta mais rápida ao utilizador, repetir a operação, experimentar uma operação diferente ou adicionar a operação a uma fila de tarefas).
offset
Número de resultados a ignorar antes de devolver o primeiro.
limit
Número máximo de resultados a devolver. Se for omitido ou definido como None, todos os resultados disponíveis são obtidos por predefinição.
batch_size
Número de resultados a tentar obter por lote. Se limit estiver definido, a predefinição é o limite especificado. Caso contrário, a predefinição é 20.
keys_only
Se true, devolve apenas chaves em vez de entidades completas. As consultas apenas com chaves são mais rápidas e baratas do que as que devolvem entidades completas.
projeção
Lista ou tuplo de nomes de propriedades a devolver. Apenas são devolvidas as entidades que possuem as propriedades especificadas. Se não for especificado, são devolvidas entidades completas por predefinição. As consultas de projeção são mais rápidas e baratas do que as que devolvem entidades completas.

Nota: a especificação deste parâmetro pode alterar os requisitos de índice da consulta.

start_cursor
Posição do cursor na qual iniciar a consulta.
end_cursor
Posição do cursor na qual terminar a consulta.
get (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Executa a consulta e devolve o primeiro resultado ou None se não forem encontrados resultados.

Argumentos

read_policy
Leia a política que especifica o nível de consistência de dados pretendido:
STRONG_CONSISTENCY
Garante os resultados mais recentes, mas está limitado a um único grupo de entidades.
EVENTUAL_CONSISTENCY
Pode abranger vários grupos de entidades, mas, ocasionalmente, pode devolver resultados desatualizados. Em geral, as consultas eventualmente consistentes são executadas mais rapidamente do que as consultas fortemente consistentes, mas não existe qualquer garantia.

Nota: as consultas globais (não antecessoras) ignoram este argumento.

deadline
Tempo máximo, em segundos, de espera para que o Datastore devolva um resultado antes de anular com um erro. Aceita um número inteiro ou um valor de vírgula flutuante. Não pode ser definido acima do valor predefinido (60 segundos), mas pode ser ajustado para baixo para garantir que uma operação específica falha rapidamente (por exemplo, para devolver uma resposta mais rápida ao utilizador, repetir a operação, experimentar uma operação diferente ou adicionar a operação a uma fila de tarefas).
offset
Número de resultados a ignorar antes de devolver o primeiro.
keys_only
Se true, devolve apenas chaves em vez de entidades completas. As consultas apenas com chaves são mais rápidas e baratas do que as que devolvem entidades completas.
projeção
Lista ou tuplo de nomes de propriedades a devolver. Apenas são devolvidas as entidades que possuem as propriedades especificadas. Se não for especificado, são devolvidas entidades completas por predefinição. As consultas de projeção são mais rápidas e baratas do que as que devolvem entidades completas.

Nota: a especificação deste parâmetro pode alterar os requisitos de índice da consulta.

start_cursor
Posição do cursor na qual iniciar a consulta.
end_cursor
Posição do cursor na qual terminar a consulta.
fetch (limit, read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

Executa a consulta e devolve uma lista (possivelmente vazia) de resultados:

  1. Obtém e rejeita o número de resultados especificado pelo argumento offset.
  2. Obtém e devolve até ao número máximo de resultados especificado pelo argumento limit.

Assim, o desempenho do método é dimensionado linearmente com a soma de offset + limit.

Nota: este método é apenas uma pequena união em torno do método run(), e é menos eficiente e requer mais memória do que usar run() diretamente. Raramente precisa de usar fetch(). Este elemento é fornecido principalmente por conveniência nos casos em que precisa de obter uma lista completa na memória dos resultados da consulta.

Sugestão: o método fetch() foi concebido para obter apenas o número de resultados especificado pelo argumento limit. Para obter todos os resultados disponíveis de uma consulta quando o respetivo número é desconhecido, use run() com um tamanho do lote grande, como run(batch_size=1000), em vez de fetch().

Argumentos

limit
Número máximo de resultados a devolver. Se estiver definido como None, são obtidos todos os resultados disponíveis.
read_policy
Leia a política que especifica o nível de consistência de dados pretendido:
STRONG_CONSISTENCY
Garante os resultados mais recentes, mas está limitado a um único grupo de entidades.
EVENTUAL_CONSISTENCY
Pode abranger vários grupos de entidades, mas, ocasionalmente, pode devolver resultados desatualizados. Em geral, as consultas eventualmente consistentes são executadas mais rapidamente do que as consultas fortemente consistentes, mas não existe qualquer garantia.

Nota: as consultas globais (não antecessoras) ignoram este argumento.

deadline
Tempo máximo, em segundos, de espera para que o Datastore devolva um resultado antes de anular com um erro. Aceita um número inteiro ou um valor de vírgula flutuante. Não pode ser definido acima do valor predefinido (60 segundos), mas pode ser ajustado para baixo para garantir que uma operação específica falha rapidamente (por exemplo, para devolver uma resposta mais rápida ao utilizador, repetir a operação, experimentar uma operação diferente ou adicionar a operação a uma fila de tarefas).
offset
Número de resultados a ignorar antes de devolver o primeiro.
keys_only
Se true, devolve apenas chaves em vez de entidades completas. As consultas apenas com chaves são mais rápidas e baratas do que as que devolvem entidades completas.
projeção
Lista ou tuplo de nomes de propriedades a devolver. Apenas são devolvidas as entidades que possuem as propriedades especificadas. Se não for especificado, são devolvidas entidades completas por predefinição. As consultas de projeção são mais rápidas e baratas do que as que devolvem entidades completas.

Nota: a especificação deste parâmetro pode alterar os requisitos de índice da consulta.

start_cursor
Posição do cursor na qual iniciar a consulta.
end_cursor
Posição do cursor na qual terminar a consulta.
count (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=1000, start_cursor=None, end_cursor=None)

Devolve o número de resultados que correspondem à consulta. Isto é mais rápido por um fator constante do que obter realmente todos os resultados, mas o tempo de execução continua a ser dimensionado linearmente com a soma de offset + limit. A menos que se espere que a contagem de resultados seja pequena, é melhor especificar um argumento limit; caso contrário, o método continua até terminar a contagem ou expirar o tempo.

Argumentos

read_policy
Leia a política que especifica o nível de consistência de dados pretendido:
STRONG_CONSISTENCY
Garante os resultados mais recentes, mas está limitado a um único grupo de entidades.
EVENTUAL_CONSISTENCY
Pode abranger vários grupos de entidades, mas, ocasionalmente, pode devolver resultados desatualizados. Em geral, as consultas eventualmente consistentes são executadas mais rapidamente do que as consultas fortemente consistentes, mas não existe qualquer garantia.

Nota: as consultas globais (não antecessoras) ignoram este argumento.

deadline
Tempo máximo, em segundos, de espera para que o Datastore devolva um resultado antes de anular com um erro. Aceita um número inteiro ou um valor de vírgula flutuante. Não pode ser definido acima do valor predefinido (60 segundos), mas pode ser ajustado para baixo para garantir que uma operação específica falha rapidamente (por exemplo, para devolver uma resposta mais rápida ao utilizador, repetir a operação, experimentar uma operação diferente ou adicionar a operação a uma fila de tarefas).
offset
Número de resultados a ignorar antes de contar o primeiro.
limit
Número máximo de resultados a contabilizar.
start_cursor
Posição do cursor na qual iniciar a consulta.
end_cursor
Posição do cursor na qual terminar a consulta.
index_list ()

Devolve uma lista de índices usados por uma consulta executada, incluindo índices principais, compostos, de tipo e de propriedade única.

Atenção: invocar este método numa consulta que ainda não foi executada gera uma exceção AssertionError.

Nota: esta funcionalidade não é totalmente suportada no servidor de desenvolvimento. Quando usado com o servidor de desenvolvimento, o resultado é a lista vazia ou uma lista que contém exatamente um índice composto.

Por exemplo, o código seguinte imprime várias informações sobre os índices usados por uma consulta:

# other imports ...
import webapp2
from google.appengine.api import users
from google.appengine.ext import db

class Greeting(db.Model):
  author = db.StringProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp2.RequestHandler):
  def get(self):
    user = users.get_current_user()
    q = db.Query(Greeting)
    q.filter("author =", user.user_id())
    q.order("-date")
    q.fetch(100)
    index_list = q.index_list()
    for ix in index_list:
      self.response.out.write("Kind: %s" % ix.kind())
      self.response.out.write("<br />")
      self.response.out.write("Has ancestor? %s" % ix.has_ancestor())
      self.response.out.write("<br />")
      for name, direction in ix.properties():
        self.response.out.write("Property name: "+name)
        self.response.out.write("<br />")
        if direction == db.Index.DESCENDING:
          self.response.out.write("Sort direction: DESCENDING")
        else:
          self.response.out.write("Sort direction: ASCENDING")
        self.response.out.write("<br />")

Isto produz resultados semelhantes aos seguintes para cada índice:

Kind: Greeting
Has ancestor? False
Property name: author
Sort direction: ASCENDING
Property name: date
Sort direction: DESCENDING
cursor ()

Devolve uma string de cursor codificada em base64 que indica a posição no conjunto de resultados da consulta após o último resultado obtido. A string do cursor é segura para utilização nos parâmetros HTTP GET e POST e também pode ser armazenada no Datastore ou no Memcache. Uma invocação futura da mesma consulta pode fornecer esta string através do parâmetro start_cursor ou do método with_cursor() para retomar a obtenção de resultados a partir desta posição.

Atenção: invocar este método numa consulta que ainda não foi executada gera uma exceção AssertionError.

Nota: nem todas as consultas são compatíveis com cursores. Consulte a página Consultas do Datastore para mais informações.

with_cursor (start_cursor, end_cursor=None)

Especifica as posições de início e (opcionalmente) de fim no conjunto de resultados de uma consulta a partir das quais obter resultados. As strings do cursor que denotam as posições inicial e final podem ser obtidas chamando cursor() após uma invocação anterior da consulta. A consulta atual tem de ser idêntica à invocação anterior, incluindo o tipo de entidade, os filtros de propriedades, os filtros de antepassados e as ordens de ordenação.

Argumentos

start_cursor
String do cursor codificada em Base64 que especifica onde iniciar a consulta.
end_cursor
String do cursor codificada em Base64 que especifica onde terminar a consulta.