tutorial issue example descargar create python google-app-engine google-cloud-datastore

python - issue - jira rest api example



¿Cómo buscar más de 1000? (16)

A partir de la versión 1.3.6 (publicada el 17 de agosto de 2010) PUEDE

Desde el registro de cambios:

Los resultados de las consultas y compensaciones del conteo de datos () para todas las consultas del almacén de datos ya no tienen un límite de 1000 .

¿Cómo puedo obtener más de 1000 registros del almacén de datos y poner todo en una sola lista para pasar a django?


App Engine le ofrece una buena forma de "buscar" los resultados en 1000 ordenando Llaves y utilizando la última tecla como la siguiente compensación. Incluso proporcionan algunos ejemplos de código aquí:

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

Aunque su ejemplo extiende las consultas sobre muchas solicitudes, puede cambiar el tamaño de página de 20 a 1000 y consultar en un bucle, combinando los conjuntos de consulta. Además, puede usar itertools para vincular las consultas sin evaluarlas antes de que sean necesarias.

Por ejemplo, para contar cuántas filas más allá 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 esto aparece como una limitación, siempre me pregunto " ¿por qué necesitas más de 1,000 resultados?" ¿Sabías que Google no ofrece más de 1,000 resultados? Pruebe esta búsqueda: 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 No sabía eso hasta que Recientemente, porque nunca me había tomado el tiempo de hacer clic en la página 100 de resultados de búsqueda en una consulta.

Si en realidad le devuelve más de 1000 resultados al usuario, entonces creo que hay un problema mayor que el hecho de que el almacén de datos no le permitirá hacerlo.

Una posible razón (legítima) para necesitar tantos resultados es si realizaba una operación grande sobre los datos y presentaba un resumen (por ejemplo, cuál es el promedio de todos estos datos). La solución a este problema (del que se habla en la charla de Google I / O) es calcular los datos de resumen sobre la marcha, tal como vienen, y guardarlos.



Este problema de límite 1K está resuelto.

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

Al tratar el objeto Query como iterable: el iterador recupera los resultados del almacén de datos en lotes pequeños, lo que permite que la aplicación deje de iterar en los resultados para evitar obtener más de lo necesario. La iteración se detiene cuando se recuperan todos los resultados que coinciden con la consulta. Al igual que con fetch (), la interfaz del iterador no almacena los resultados en caché, por lo que la creación de un nuevo iterador a partir del objeto Query ejecutará nuevamente la consulta.

El tamaño máximo de lote es 1K. Y todavía tienes las cuotas automáticas de Datastore también.

Pero con el plan 1.3.1 SDK, introdujeron cursores que pueden ser serializados y guardados para que una invocación futura pueda comenzar la consulta donde la dejó por última vez.


Esto está cerca de la solución provista por Gabriel, pero no obtiene los resultados solo los cuenta:

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 perfectamente para mis consultas, y también rápido (1.1 segundos para contar 67,000 entidades)

Tenga en cuenta que la consulta no debe ser un filtro de desigualdad o un conjunto o que el cursor no funcionará y obtendrá esta excepción:

AssertionError: no hay cursor disponible para MultiQuery (consultas con operadores "IN" o "! =")


JJG: tu solución de arriba es increíble, excepto que causa un bucle infinito si tienes 0 registros. (Descubrí esto mientras probaba algunos de mis informes localmente).

Modifiqué el inicio del ciclo while para que se vea así:

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


La recuperación de la API remota todavía tiene problemas cuando hay más de 1000 registros. Escribimos esta pequeña función para iterar sobre una tabla en fragmentos:

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


La solución propuesta solo funciona si las entradas están ordenadas por clave ... Si primero ordena por otra columna, aún debe usar una cláusula de límite (compensación, recuento), y luego se aplicará la limitación de 1000 entradas. Es lo mismo si usa dos solicitudes: una para recuperar índices (con condiciones y ordenar) y otra usando donde index in () con un subconjunto de índices del primer resultado, ya que la primera solicitud no puede devolver más de 1000 claves. (La sección de Consultas de Google sobre claves no indica claramente si debemos ordenar por clave para eliminar la limitación de 1000 resultados)


Para agregar el contenido de las dos consultas juntas:

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

La Lista 1 ahora contiene todos los 2000 resultados.


Si estás 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


Solo para el registro: el límite de búsqueda de 1000 entradas ya no está:

http://googleappengine.blogspot.com/2010/02/app-engine-sdk-131-including-major.html

Cotización:

No más de 1000 límites de resultados: eso es correcto: con la adición de Cursores y la culminación de muchas mejoras más pequeñas de estabilidad y rendimiento del Almacén de datos en los últimos meses, ahora tenemos la confianza suficiente para eliminar por completo el límite máximo de resultados. Ya sea que esté haciendo una búsqueda, iterando o usando un Cursor, no hay límites en la cantidad de resultados.


estamos usando algo en nuestra clase ModelBase que es:

@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

Esto supera el límite de 1000 consultas en cada modelo sin tener que pensar en ello. Supongo que una versión de claves sería igual de fácil de implementar.


No puedes.

Parte de las preguntas frecuentes indica que no hay forma de que pueda acceder más allá de la fila 1000 de una consulta, aumentar el "DESPLAZAMIENTO" solo resultará en un conjunto de resultados más corto,

es decir: OFFSET 999 -> 1 resultado regresa.

De la Wikipedia:

App Engine limita las filas máximas devueltas desde una entidad a 1000 filas por llamada de Datastore. La mayoría de las aplicaciones de bases de datos web utilizan paginación y almacenamiento en caché, y por lo tanto no requieren esta cantidad de datos a la vez, por lo que esto no es un problema en la mayoría de los escenarios. [Cita requerida] Si una aplicación necesita más de 1,000 registros por operación, puede usar su propio software del lado del cliente o una página de Ajax para realizar una operación en un número ilimitado de filas.

Desde http://code.google.com/appengine/docs/whatisgoogleappengine.html

Otro ejemplo de un límite de servicio es la cantidad de resultados devueltos por una consulta. Una consulta puede devolver como máximo 1,000 resultados. Las consultas que devolverían más resultados solo devolverían el máximo. En este caso, una solicitud que realiza dicha consulta no es probable que devuelva una solicitud antes del tiempo de espera, pero el límite está en su lugar para conservar los recursos en el almacén de datos.

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

Nota: Una cláusula LIMIT tiene un máximo de 1000. Si se especifica un límite mayor que el máximo, se utiliza el máximo. Este mismo máximo se aplica al método fetch () de la clase GqlQuery.

Nota: Al igual que el parámetro de compensación para el método fetch (), un DESPLAZAMIENTO en una cadena de consulta GQL no reduce el número de entidades recuperadas del almacén de datos. Solo afecta los resultados que devuelve el método fetch (). Una consulta con un desplazamiento tiene características de rendimiento que se corresponden linealmente con el tamaño de desplazamiento.

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

Los argumentos de límite y desplazamiento controlan cuántos resultados se obtienen del almacén de datos y cuántos devuelve el método fetch ():

  • El almacén de datos obtiene los resultados de desplazamiento + límite a la aplicación. Los primeros resultados de compensación no son omitidos por el mismo almacén de datos.

  • El método fetch () omite los primeros resultados de desplazamiento, luego devuelve el resto (resultados límite).

  • La consulta tiene características de rendimiento que se corresponden linealmente con la cantidad de compensación más el límite.

Lo que esto significa es

Si tiene una consulta singular, no hay forma de solicitar nada fuera del rango 0-1000.

El desplazamiento creciente aumentará el 0, por lo tanto

LIMIT 1000 OFFSET 0

Devolverá 1000 filas,

y

LIMIT 1000 OFFSET 1000

Devolverá 0 filas , lo que imposibilitará, con una sola sintaxis de consulta, obtener los resultados de 2000 manualmente o utilizando la API.

La única excepción plausible

Es crear un índice numérico en la tabla, es decir:

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

Si sus datos o consultas no pueden tener este identificador de ''ID'' codificado, entonces no tiene suerte


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)

Simple como eso. Tenga en cuenta que hay un RPC hecho para cada entidad, que es mucho más lento que ir a buscar en trozos. Entonces, si le preocupa el rendimiento, haga lo siguiente:

Si tiene menos de 1 millón de elementos:

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

De lo contrario, use un cursor.

También se debe tener en cuenta que:

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

devuelve 1000 max y no debe usarse.