문제

데이터 저장소에서 1000개가 넘는 레코드를 가져와서 하나의 목록에 모두 넣어 django에 전달하려면 어떻게 해야 하나요?

도움이 되었습니까?

해결책

버전 1.3.6 (2010 년 8 월 17 일 -20110 년 출시)부터 시작합니다 할 수 있다

Changelog에서 :

DataStore Count () 쿼리의 결과 모든 데이터 스토어 쿼리에 대한 오프셋은 더 이상 1000에 캡핑되지 않습니다..

다른 팁

기록을 위해서만 - 1000 개의 항목의 가져 오기 제한이 사라졌습니다.

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

인용:

더 이상 1000 결과 한도 - 맞습니다 : 커서를 추가하고 지난 몇 개월 동안 많은 소규모 데이터 저장소 안정성 및 성능 향상의 정점으로 인해 최대 결과 한도를 완전히 제거 할 수있을만큼 확신합니다. 페치, 반복 또는 커서를 사용하든 결과 수에는 제한이 없습니다.

App Engine은 키를 주문하고 마지막 키를 다음 오프셋으로 사용하여 1000까지 결과를 통해 "페이징"을 제공합니다. 여기에는 샘플 코드도 제공합니다.

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

예제는 많은 요청에 걸쳐 쿼리를 퍼 뜨리지 만 페이지 크기를 20에서 1000으로 변경하고 루프에서 쿼리를 결합하여 쿼리를 변경할 수 있습니다. 또한 ITERTOOLS를 사용하여 쿼리가 필요하기 전에 평가하지 않고 쿼리를 연결할 수 있습니다.

예를 들어, 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

이것이 제한으로 나타날 때마다 항상 궁금합니다. " 1,000 개 이상의 결과가 필요하십니까? "Google 자체가 1,000 개 이상의 결과를 제공하지 않는다는 것을 알고 있습니까?이 검색을 시도해보십시오. 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 나는 최근까지 쿼리에서 100 번째 검색 결과를 클릭하는 데 시간을 절대 가져 가지 않았기 때문에 그것을 몰랐습니다.

실제로 1,000 개 이상의 결과를 사용자에게 돌려 보내고 있다면 데이터 저장소에서 수행 할 수 없다는 사실보다 더 큰 문제가 있다고 생각합니다.

많은 결과가 필요한 한 가지 가능한 (합법적 인) 이유는 데이터에 대해 큰 작업을 수행하고 요약을 제시하는 경우 (예 :이 모든 데이터의 평균)입니다. 이 문제에 대한 해결책 (Google I/O Talk에서 논의)은 요약 데이터를 즉시 계산하여 저장하는 것입니다.

당신은 할 수 없습니다.

FAQ의 일부는 쿼리의 행 1000을 넘어 액세스 할 수있는 방법이 없다고 말하면 "오프셋"을 늘리면 결과 세트가 짧아집니다.

IE : 오프셋 999-> 1 결과가 돌아옵니다.

Wikipedia에서 :

앱 엔진은 엔티티에서 반환 된 최대 행을 데이터 저장소 호출 당 1000 행으로 제한합니다. 대부분의 웹 데이터베이스 응용 프로그램은 페이징 및 캐싱을 사용하므로 한 번 에이 많은 데이터가 필요하지 않으므로 대부분의 시나리오에서는 문제가되지 않습니다. 자체 클라이언트 측 소프트웨어 또는 AJAX 페이지를 사용하여 무제한 수의 행에서 작업을 수행합니다.

에서 http://code.google.com/appengine/docs/whatisgoogleappengine.html

서비스 제한의 또 다른 예는 쿼리에서 반환 된 결과 수입니다. 쿼리는 최대 1,000 개의 결과를 반환 할 수 있습니다. 더 많은 결과를 반환하는 쿼리는 최대 값 만 반환합니다. 이 경우, 이러한 쿼리를 수행하는 요청은 타임 아웃 전에 요청을 반환하지 않을 가능성이 없지만 데이터 저장소에서 리소스를 보존하기 위해 한도가 있습니다.

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

참고 : 한계 절은 최대 1000입니다. 최대보다 큰 한계가 지정되면 최대 값이 사용됩니다. 이 동일한 최대 값은 GQLQuery 클래스의 Fetch () 메소드에 적용됩니다.

참고 : Fetch () 메소드의 오프셋 매개 변수와 마찬가지로 GQL 쿼리 문자열의 오프셋은 데이터 스토어에서 가져온 엔티티 수를 줄이지 않습니다. Fetch () 메소드에 의해 반환되는 결과에만 영향을 미칩니다. 오프셋이있는 쿼리에는 오프셋 크기와 선형으로 해당하는 성능 특성이 있습니다.

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

한계 및 오프셋 인수는 데이터 스토어에서 가져온 결과 수와 Fetch () 메소드에 의해 반환되는 수를 제어합니다.

  • Datastore는 오프셋 + 제한 결과를 응용 프로그램에 가져옵니다. 첫 번째 오프셋 결과는 다음과 같습니다 ~ 아니다 데이터 스토어 자체에 의해 건너 뜁니다.

  • Fetch () 메소드는 첫 번째 오프셋 결과를 건너 뜁니다. 그런 다음 나머지를 반환합니다 (결과 제한).

  • 쿼리에는 오프셋 금액과 한계와 선형으로 해당하는 성능 특성이 있습니다.

이것이 의미하는 바입니다

단일 쿼리가있는 경우 0-1000 범위를 벗어난 것을 요청할 방법이 없습니다.

오프셋이 증가하면 0이 증가합니다

LIMIT 1000  OFFSET 0    

1000 줄을 반환합니다.

그리고

LIMIT 1000 OFFSET 1000 

돌아올 것입니다 0 줄, 따라서 단일 쿼리 구문으로 2000 결과를 수동으로 또는 API를 사용하여 불가능하게 만들 수 있습니다.

유일한 그럴듯한 예외

테이블에 숫자 인덱스를 만드는 것입니다.

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

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

데이터 나 쿼리 가이 'ID'하드 코딩 된 식별자를 가질 수 없다면 운없는

이 1K 제한 문제가 해결되었습니다.

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

Query 객체를 반복 가능한 개체로 처리하면 다음과 같습니다.반복자는 데이터 저장소에서 작은 배치로 결과를 검색하므로 앱이 필요한 것보다 더 많은 것을 가져오는 것을 방지하기 위해 결과 반복을 중지할 수 있습니다.쿼리와 일치하는 모든 결과가 검색되면 반복이 중지됩니다.fetch()와 마찬가지로 반복자 인터페이스는 결과를 캐시하지 않으므로 Query 객체에서 새 반복자를 생성하면 쿼리가 다시 실행됩니다.

최대 배치 크기는 1K입니다.그리고 여전히 자동 Datastore 할당량도 있습니다.

그러나 계획 1.3.1 SDK에서는 향후 호출이 마지막으로 중단된 위치에서 쿼리를 시작할 수 있도록 직렬화하고 저장할 수 있는 커서를 도입했습니다.

1000 레코드 한도는 Google Appengine의 단단한 한도입니다.

이 프레젠테이션 http://sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine Appengine을 사용하여 데이터를 효율적으로 페이지를 페이지로 만드는 방법을 설명합니다.

(기본적으로 숫자 ID를 키로 사용하고 ID에서 WHERE 절을 지정합니다.)

원격 API에 1000 개가 넘는 레코드가있을 때 여전히 문제가 있습니다. 우리는이 작은 기능을 작성하여 덩어리의 테이블 위에 반복합니다.

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

우리는 우리에게 무언가를 사용하고 있습니다 ModelBase 수업은 :

@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

이것은 생각할 필요없이 모든 모델에서 1000 쿼리 제한을 나타냅니다. 키 버전이 구현하기 쉽다고 생각합니다.

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)

그렇게 간단합니다. 덩어리를 가져 오는 것보다 훨씬 느린 모든 엔티티에 대한 RPC가 있습니다. 따라서 성능이 걱정된다면 다음을 수행하십시오.

1m 미만의 항목이있는 경우 :

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

그렇지 않으면 커서를 사용하십시오.

또한 다음과 같이 언급해야합니다.

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

최대 1000을 반환하고 사용해서는 안됩니다.

JJG : 위의 솔루션은 0 개의 레코드가있는 경우 무한 루프를 유발한다는 점을 제외하고는 훌륭합니다. (내 보고서 중 일부를 로컬로 테스트하는 동안 이것을 발견했습니다).

while 루프의 시작을 다음과 같이 수정했습니다.

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

두 쿼리의 내용을 함께 추가하려면 다음과 같습니다.

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

목록 1은 이제 2000 결과를 모두 포함합니다.

제안 된 솔루션은 항목이 키별로 정렬되는 경우에만 작동합니다 ... 다른 열로 먼저 정렬하는 경우에도 여전히 한계 (오프셋, 카운트) 절을 사용해야합니다. 그러면 1000 항목 제한이 여전히 적용됩니다. 첫 번째 요청이 1000 개 이상의 키를 반환 할 수 없으므로 인덱스를 검색하기 위해 (조건 및 정렬) 인덱스를 사용하는 곳을 사용하는 두 가지 요청을 사용하는 경우와 동일합니까? (구글 키의 쿼리 우리가 정렬 해야하는 경우 섹션은 명확하게 진술하지 않습니다. 열쇠 1000 결과 제한을 제거하려면)

이것은 Gabriel이 제공 한 솔루션에 가깝지만 결과를 가져 오지는 않습니다.

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)

내 쿼리에 완벽하게 작동하고 빠르게 작동합니다 (67,000 개 엔티티를 계산하는 데 1.1 초)

쿼리는 불평등 필터 나 세트가되어서는 안됩니다. 그렇지 않으면 커서가 작동하지 않으며이 예외를 얻을 수 있습니다.

AssertionError : 다중 실용에 사용할 수있는 커서가 없습니다 ( "in"또는 "! ="연산자를 사용한 쿼리)

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top