簡體   English   中英

在Google App Engine中的for循環中進行查詢的有效方法?

[英]Efficient way to query in a for loop in Google App Engine?

在GAE文檔中,它指出:

因為每個get()或put()操作都調用一個單獨的遠程過程調用(RPC),所以在循環內發出許多這樣的調用是一次性處理實體或鍵集合的低效率方法。

誰知道我的代碼中還有多少其他效率低下的問題,所以我想盡可能地減少效率。 目前,我確實有一個for循環,其中每個迭代都有一個單獨的查詢。 假設我有一個用戶,一個用戶有朋友。 我想為用戶的每個朋友獲取最新更新。 因此,我所擁有的是該用戶好友的數組:

for friend_dic in friends:
        email = friend_dic['email']
        lastUpdated = friend_dic['lastUpdated']
        userKey = Key('User', email)
        query = ndb.gql('SELECT * FROM StatusUpdates WHERE ANCESTOR IS :1 AND modifiedDate > :2', userKey, lastUpdated)
        qit = query.iter()
        while (yield qit.has_next_async()):
           status = qit.next()
           status_list.append(status.to_dict())
raise ndb.Return(status_list)

有沒有更有效的方法來執行此操作,也許以某種方式將所有這些批處理成一個查詢?

嘗試查看NDB的地圖功能: https : //developers.google.com/appengine/docs/python/ndb/queryclass#Query_map_async

示例(假設您將朋友關系保留在單獨的模型中,在本示例中,我假設使用“ Relationships模型):

@ndb.tasklet
def callback(entity):
  email = friend_dic['email']
  lastUpdated = friend_dic['lastUpdated']
  userKey = Key('User', email)
  query = ndb.gql('SELECT * FROM StatusUpdates WHERE ANCESTOR IS :1 AND modifiedDate > :2', userKey, lastUpdated)
  status_updates = yield query.fetch_async()
  raise ndb.Return(status_updates)

qry = ndb.gql("SELECT * FROM Relationships WHERE friend_to = :1", user.key)
updates = yield qry.map_async(callback)
#updates will now be a list of status updates

更新:

更好地了解您的數據模型:

queries = []
status_list = []
for friend_dic in friends:
  email = friend_dic['email']
  lastUpdated = friend_dic['lastUpdated']
  userKey = Key('User', email)
  queries.append(ndb.gql('SELECT * FROM StatusUpdates WHERE ANCESTOR IS :1 AND modifiedDate > :2', userKey, lastUpdated).fetch_async())

for query in queries:
  statuses = yield query
  status_list.extend([x.to_dict() for x in statuses])

raise ndb.Return(status_list)

您可以使用ndb異步方法同時執行這些查詢:

from google.appengine.ext import ndb

class Bar(ndb.Model):
   pass

class Foo(ndb.Model):
   pass

bars = ndb.put_multi([Bar() for i in range(10)])
ndb.put_multi([Foo(parent=bar) for bar in bars])

futures = [Foo.query(ancestor=bar).fetch_async(10) for bar in bars]
for f in futures:
  print(f.get_result())

這將啟動10個並發的Datastore Query RPC,並且總體延遲僅取決於最慢的延遲,而不是所有延遲的總和

另請參閱官方的ndb文檔,以獲取有關如何使用ndb異步API的更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM