Pergunta

Como posso buscar mais de 1000 registro de armazenamento de dados e colocar tudo em uma única lista para passar para Django?

Foi útil?

Solução

A partir da Versão 1.3.6 (lançado Aug-17-2010) você pode

Desde o changelog:

Os resultados de armazenamento de dados de contagem () consultas e deslocamentos para todas as consultas do armazenamento de dados não são seladas em 1000 .

Outras dicas

Apenas para o registro - buscar limite de 1000 entradas é ido agora:

http: //googleappengine.blogspot. com / 2010/02 / app-motor-sdk-131, incluindo-major.html

Cotação:

Não há mais 1000 resultado limite - que é direita: com adição de cursores e o culminar de muitos menor Datastore estabilidade e desempenho melhorias ao longo dos últimos meses, estamos bastante agora confiante para remover o limite máximo resultado completamente. Se você está fazendo uma busca, iteração, ou usando um cursor, não há há limites para o número de resultados.

App Engine dá-lhe uma boa maneira de "paginação" através dos resultados em 1000 por ordenação em chaves e usando a última chave como o próximo deslocamento. Eles ainda fornecer um código de exemplo aqui:

http://code.google.com/appengine /docs/python/datastore/queriesandindexes.html#Queries_on_Keys

Embora o seu exemplo se espalha as consultas ao longo de muitos pedidos, você pode alterar o tamanho da página de 20 a 1000 e de consulta em um loop, combinando os querysets. Além disso, você pode usar itertools para ligar as consultas sem avaliá-los antes que eles são necessários.

Por exemplo, para contar quantas linhas para além de 1000:

class MyModel(db.Expando):
    @classmethod
    def count_all(cls):
        """
        Count *all* of the rows (without maxing out at 1000)
        """
        count = 0
        query = cls.all().order('__key__')

        while count % 1000 == 0:
            current_count = query.count()
            if current_count == 0:
                break

            count += current_count

            if current_count == 1000:
                last_key = query.fetch(1, 999)[0].key()
                query = query.filter('__key__ > ', last_key)

        return count

Cada vez que isso surge como uma limitação, eu sempre maravilha " por você precisa de mais de 1.000 resultados?" Você sabia que o Google si não serve mais de 1.000 resultados? Tente esta pesquisa: http://www.google.ca/search?hl=en&client=firefox-a&rls=org.mozilla:en-US:official&hs=qhu&q=1000+results&start=1000&sa=N eu não 't sabe que, até recentemente, porque eu nunca tinha tido tempo para clicar na página 100 dos resultados da pesquisa em uma consulta.

Se você está realmente voltando mais de 1.000 resultados de volta para o usuário, então eu acho que há um problema maior na mão do que o fato de que o armazenamento de dados não vai deixar você fazer isso.

Uma possível (legítima) razão para necessidade que muitos resultados é se você estivesse fazendo uma grande operação nos dados e apresentar um resumo (por exemplo, qual é a média de todos esses dados). A solução para este problema (que é falado no O talk / Google I) é calcular os dados de resumo on-the-fly, como ele entra, e guardá-lo.

Você não pode.

Parte dos FAQ estados que não há nenhuma maneira você pode acessar além fileira 1000 de uma consulta, aumentando o "OFFSET" só vai resultar em um conjunto de resultados mais curto,

ou seja: OFFSET 999 -> 1 resultado volta.

De Wikipedia:

App Engine limita as linhas máximas retornado de uma get entidade até 1000 linhas por chamada Datastore. A maioria dos web aplicações de banco de dados usar paginação e caching, e, portanto, não exigem esta quantidade de dados de uma só vez, então isso é uma não-problema na maioria dos cenários. [citação necessário] Se um aplicativo precisa de mais de 1.000 registros por operação, pode usar o seu próprio software do lado do cliente ou uma página Ajax para realizar uma operação em um número ilimitado de linhas.

A partir http://code.google.com/appengine/docs/whatisgoogleappengine. html

Outro exemplo de um limite de serviço é o número de resultados devolvidos por uma inquerir. A consulta pode retornar no máximo 1.000 resultados. As consultas que faria retornar mais resultados só devolver o máximo. Neste caso, um pedido para que executa tal uma consulta não é provável que devolver um pedido antes do tempo limite, mas o limite está em vigor para conservar recursos sobre o armazenamento de dados.

A partir http://code.google.com/appengine/docs/ datastore / gqlreference.html

Nota: cláusula UM LIMITE tem um máximo de 1000. Se um limite maior do que o máximo especificado, o máximo está usava. Esta mesma máxima se aplica ao fetch () método da classe GqlQuery.

Nota: Como o parâmetro de deslocamento para o método buscar (), um deslocamento em um GQL string de consulta não reduz a número de entidades obtido a partir da banco de dados. Ela afeta apenas que os resultados são devolvidos pela busca () método. Uma consulta com um deslocamento tem características de desempenho que correspondem linearmente com o deslocamento tamanho.

A partir http://code.google.com/appengine/docs/ datastore / queryclass.html

O limite e controle argumentos compensado quantos resultados são obtidos a partir da armazenamento de dados, e quantos são devolvidos pelo método fetch ():

  • As buscas do armazenamento de dados offset + resultados limite para a aplicação. Os resultados do primeiro deslocamento são não ignorado pelo próprio armazenamento de dados.

  • O buscar () método ignora os resultados do primeiro deslocamento, em seguida, devolve o resto (resultados limite).

  • A consulta tem características de desempenho que correspondem linearmente com a quantidade de desfasamento além do limite.

O que isto significa é

Se você tiver uma consulta singular, não há nenhuma maneira de solicitar qualquer coisa fora do intervalo 0-1000.

aumento do desfasamento só vai aumentar a 0, então

LIMIT 1000  OFFSET 0    

retornará 1000 linhas,

e

LIMIT 1000 OFFSET 1000 

retornará 0 linhas , assim, tornando-se impossível, com uma única sintaxe de consulta, buscar 2000 resultados manualmente ou usando a API.

A exceção única plausível

é criar um índice numérico na tabela, isto é:

 SELECT * FROM Foo  WHERE ID > 0 AND ID < 1000 

 SELECT * FROM Foo WHERE ID >= 1000 AND ID < 2000

Se os seus dados ou consulta não pode ter esse 'ID' identificador codificado, então você está fora de sorte

Esta questão 1K limite for resolvido.

query = MyModel.all()
for doc in query:
    print doc.title

Ao tratar o objeto Query como iterável: Os Recupera iteradoras resultados do armazenamento de dados em pequenos lotes, permitindo o aplicativo para parar a iteração nos resultados para evitar a buscar mais do que é necessário. Iteração pára quando todos os resultados que correspondem à consulta foram recuperados. Tal como acontece com fetch (), a interface do iterador não armazena resultados, criando assim uma nova iteração do objeto de consulta será re-executar a consulta.

O tamanho do lote máximo é de 1K. E você ainda tem as quotas auto armazenamento de dados também.

Mas com o SDK plano 1.3.1, eles introduziram cursores que pode ser serializado e salvos para que a invocação futuro pode começar a consulta onde última parou em.

O limite de registro de 1000 é um limite rígido no Google AppEngine.

Esta apresentação http: / /sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine explica como eficientemente página através de dados usando AppEngine.

(Basicamente, usando um ID numérico como chave e especificando uma cláusula WHERE na id.)

Buscando embora a api remota ainda tem problemas quando mais de 1000 registros. Nós escrevemos esta pequena função para iterar sobre uma mesa em pedaços:

def _iterate_table(table, chunk_size = 200):
    offset = 0
    while True:
        results = table.all().order('__key__').fetch(chunk_size+1, offset = offset)
        if not results:
            break
        for result in results[:chunk_size]:
            yield result
        if len(results) < chunk_size+1:
            break
        offset += chunk_size

estamos usando algo em nossa classe ModelBase que é:

@classmethod
def get_all(cls):
  q = cls.all()
  holder = q.fetch(1000)
  result = holder
  while len(holder) == 1000:
    holder = q.with_cursor(q.cursor()).fetch(1000)
    result += holder
  return result

Este fica em torno do limite de 1.000 consulta em cada modelo sem ter que pensar sobre isso. Suponho que uma versão chaves seria tão fácil de implementar.

class Count(object):
def getCount(self,cls):
    class Count(object):
def getCount(self,cls):
    """
    Count *all* of the rows (without maxing out at 1000)
    """
    count = 0
    query = cls.all().order('__key__')


    while 1:
        current_count = query.count()
        count += current_count
        if current_count == 0:
            break

        last_key = query.fetch(1, current_count-1)[0].key()
        query = query.filter('__key__ > ', last_key)

    return count
entities = []
for entity in Entity.all():
    entities.append(entity)

Simples assim. Note-se que há uma RPC feitas para cada entidade que é muito mais lento do que buscar em pedaços. Então, se você está preocupado com o desempenho, faça o seguinte:

Se você tem menos de itens 1M:

entities = Entity.all().fetch(999999)

Caso contrário, use um cursor.

Deve também ser observado que:

Entity.all().fetch(Entity.all().count())

retorna 1000 máximo e não deve ser utilizado.

JJG: sua solução acima é incrível, exceto que ele faz com que um loop infinito se você tem 0 registros. (Descobri isso ao testar alguns dos meus relatórios localmente).

Eu modifiquei o início do loop while para ficar assim:

while count % 1000 == 0:
    current_count = query.count()
    if current_count == 0:
        break

Para adicionar o conteúdo das duas consultas junto:

list1 = first query
list2 = second query
list1 += list2

Lista 1 agora contém todos os resultados de 2000.

A solução proposta só funciona se as entradas são classificadas segundo a chave ... Se você está classificando por outra coluna, primeiro, você ainda tem que usar um limite (offset, contam) cláusula, em seguida, as 1000 entradas limitação ainda se aplicam. É a mesma coisa se você usar dois pedidos: um para recuperar índices (com condições e tipo) e outro utilizando, onde índice em () com um subconjunto dos índices do primeiro resultado, como o primeiro pedido não pode retornar mais de 1000 chaves? (O Google Consultas em chaves seção não estado claramente se tivermos que classificar por tecla para remover a limitação de 1000 resultados)

Esta é perto da solução fornecida pela Gabriel, mas não buscar os resultados que apenas conta deles:

count = 0
q = YourEntityClass.all().filter('myval = ', 2)
countBatch = q.count()
while countBatch > 0:
    count += countBatch
    countBatch = q.with_cursor(q.cursor()).count()

logging.info('Count=%d' % count)

funciona perfeitamente para minhas consultas, e rápido também (1,1 segundos para contar 67.000 entidades)

Note que a consulta não deve ser um filtro de desigualdade ou um conjunto ou o cursor não vai funcionar e você terá essa exceção:

AssertionError: No cursor disponível para um MultiQuery (consultas usando "IN" ou "! =" Operadores)

Se você estiver usando NDB:

@staticmethod
def _iterate_table(table, chunk_size=200):
    offset = 0
    while True:
        results = table.query().order(table.key).fetch(chunk_size + 1, offset=offset)
        if not results:
            break
        for result in results[:chunk_size]:
            yield result
        if len(results) < chunk_size + 1:
            break
        offset += chunk_size
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top