سؤال

كيف يمكنني جلب أكثر من 1000 سجل من مخزن البيانات ووضعها كلها في قائمة واحدة لتمريرها إلى جانغو؟

هل كانت مفيدة؟

المحلول

بدءًا من الإصدار 1.3.6 (تم إصداره في 17 أغسطس 2010) لك يستطيع

من سجل التغيير:

نتائج استعلامات عدد مخزن البيانات (). ولم تعد الإزاحات لجميع استعلامات مخزن البيانات بحد أقصى 1000.

نصائح أخرى

وفقط للسجل - جلب حدود 1000 والآن ذهب:

HTTP: //googleappengine.blogspot. كوم / 2010/02 / التطبيق محرك-SDK-131-بما في ذلك major.html

والاقتباس:

<اقتباس فقرة>   

ولا مزيد من 1000 الحد النتيجة - وهذا هو   الحق: مع اضافة المؤشرات و   تتويجا للعديد أصغر   الاستقرار مخزن البيانات والأداء   تحسينات على مدى الأشهر القليلة الماضية،   نحن الآن على ثقة بما فيه الكفاية لإزالة   نتيجة الحد الأقصى تماما.   سواء كنت تفعل جلب،   بالتكرار، أو باستخدام المؤشر، هناك   لا حدود لعدد من النتائج.

ومحرك التطبيقات يتيح لك طريقة لطيفة من "الترحيل" من خلال النتائج بحلول عام 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

في كل مرة يأتي هذا كقيد، أتساءل دائمًا "لماذا هل تحتاج إلى أكثر من 1000 نتيجة؟" هل تعلم أن Google نفسه لا يقدم أكثر من 1000 نتيجة؟جرب هذا البحث: 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 من نتائج البحث في أي استعلام.

إذا كنت تقوم بالفعل بإرجاع أكثر من 1000 نتيجة إلى المستخدم، فأعتقد أن هناك مشكلة أكبر في متناول اليد من حقيقة أن مخزن البيانات لن يسمح لك بالقيام بذلك.

أحد الأسباب المحتملة (المشروعة) للحاجة إلى العديد من النتائج هو إذا كنت تقوم بعملية كبيرة على البيانات وتقدم ملخصًا (على سبيل المثال، ما هو متوسط ​​كل هذه البيانات).الحل لهذه المشكلة (التي تم الحديث عنها في Google I/O talk) هو حساب البيانات التلخيصية فور ورودها وحفظها.

لا يمكنك.

ينص جزء من الأسئلة الشائعة على أنه لا توجد طريقة يمكنك من خلالها الوصول إلى ما بعد الصف 1000 من الاستعلام، وأن زيادة "الإزاحة" ستؤدي فقط إلى مجموعة نتائج أقصر،

أي:الإزاحة 999 --> نتيجة واحدة تعود.

من ويكيبيديا:

يحد محرك التطبيق من الحد الأقصى للصفوف التي يتم إرجاعها من كيان يصل إلى 1000 صف لكل مكالمة مخزن البيانات.تستخدم معظم تطبيقات قاعدة بيانات الويب الترحيل والتخزين المؤقت ، وبالتالي لا تتطلب الكثير من البيانات في وقت واحد ، لذلك هذا غير قضية في معظم السيناريوهات. [الاقتباس ضروري] إذا كان التطبيق يحتاج إلى أكثر من 1000 سجل لكل عملية برنامج خاص من جانب العميل أو صفحة AJAX لإجراء عملية على عدد غير محدود من الصفوف.

من http://code.google.com/appengine/docs/whatisgoogleappengine.html

مثال آخر على حد الخدمة هو عدد النتائج التي يتم إرجاعها عن طريق الاستعلام.يمكن أن يعود الاستعلام على الأكثر 1000 نتيجة.الاستعلامات التي من شأنها أن تعيد المزيد من النتائج فقط إرجاع الحد الأقصى.في هذه الحالة ، من غير المحتمل أن يعيد الطلب الذي يؤدي هذا الاستعلام طلبًا قبل المهلة ، ولكن الحد الأقصى الموجود للحفاظ على الموارد على مخزن البيانات.

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

ملحوظة:شرط الحد الأقصى 1000.إذا تم تحديد حد أكبر من الحد الأقصى ، يتم استخدام الحد الأقصى.ينطبق هذا الحد الأقصى نفسه على طريقة Fetch () لفئة GQLquery.

ملحوظة:مثل المعلمة الإزاحة لطريقة Fetch () ، لا تقلل الإزاحة في سلسلة استعلام GQL من عدد الكيانات التي تم جلبها من مخزن البيانات.لا يؤثر إلا على النتائج التي يتم إرجاعها بواسطة طريقة Fetch ().يحتوي الاستعلام مع الإزاحة على خصائص أداء تتوافق بشكل خطي مع حجم الإزاحة.

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

تتحكم الحد الأقصى والإزاحة في عدد النتائج التي يتم جلبها من مخزن البيانات ، وعدد العدد الذي يتم إرجاعه بواسطة طريقة Fetch ():

  • يقوم مخزن البيانات بجلب نتائج الإزاحة + الحد إلى التطبيق.نتائج الإزاحة الأولى هي لا تم تخطيه بواسطة مخزن البيانات نفسه.

  • تتخطى طريقة الجلب () نتائج الإزاحة الأولى، ثم تقوم بإرجاع الباقي (النتائج المحددة).

  • يحتوي الاستعلام على خصائص أداء تتوافق بشكل خطي مع كمية الإزاحة بالإضافة إلى الحد الأقصى.

ما يعنيه هذا هو

إذا كان لديك استعلام فردي، فلا توجد طريقة لطلب أي شيء خارج النطاق 0-1000.

زيادة الإزاحة ستؤدي فقط إلى رفع الرقم 0، لذا

LIMIT 1000  OFFSET 0    

سيعود 1000 صف ،

و

LIMIT 1000 OFFSET 1000 

سيعود 0 صفوف, مما يجعل من المستحيل، باستخدام صيغة استعلام واحدة، جلب 2000 نتيجة إما يدويًا أو باستخدام واجهة برمجة التطبيقات.

الاستثناء الوحيد المعقول

هو إنشاء فهرس رقمي على الجدول، أي:

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

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

إذا كانت بياناتك أو استعلامك لا يمكن أن تحتوي على معرف "المعرف" هذا، فأنت كذلك نفد منى الحظ

ويتم حل هذه المشكلة الحد 1K.

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

وعن طريق التعامل مع الكائن سؤال وiterable: إن مكرر باسترداد النتائج من مخزن البيانات على دفعات صغيرة، مما يسمح للتطبيق لإيقاف بالتكرار على النتائج لتجنب جلب أكثر مما هو مطلوب. يتوقف التكرار عندما تم استرداد كافة النتائج التي تطابق الاستعلام. كما هو الحال مع إحضار ()، واجهة مكرر لا نتائج مخبأ، لذلك خلق مكرر جديد من وجوه سؤال سوف أعد تنفيذ الاستعلام.

وحجم دفعة الحد الأقصى هو 1K. وكنت لا تزال لديها حصص السيارات مخزن البيانات أيضا.

ولكن مع SDK 1.3.1 خطة، لقد قدم المؤشرات التي يمكن إجراء تسلسل وحفظها بحيث الاحتجاج في المستقبل يمكن أن يبدأ الاستعلام من النقطة التي توقفت عندها في.

والحد سجل 1000 هو الحد من الصعب في جوجل إلى AppEngine.

HTTP: / يفسر /sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine كيفية بكفاءة الصفحة من خلال البيانات باستخدام إلى AppEngine.

و(أساسا باستخدام معرف رقمي كمفتاح وتحديد جملة WHERE على الهوية.)

وجلب على الرغم من أن المعهد بعيد لا يزال لديه مشاكل عند أكثر من 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 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 نتيجة)

وهذا هو أقرب إلى الحل التي قدمتها غابرييل، ولكن لا تجلب النتائج التي فقط التهم لهم:

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)

ويعمل تماما للاستعلامات بلدي، وبسرعة كبيرة (1.1 ثواني لحساب 67000 الكيانات)

لاحظ أن الاستعلام يجب ألا يكون عامل تصفية عدم المساواة أو مجموعة أو أن المؤشر لا يعمل وستحصل على هذا الاستثناء:

<اقتباس فقرة>   

وAssertionError: لا المؤشر متاحة لMultiQuery (الاستعلامات باستخدام "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