0

データストアが参照されたエンティティに対して追加のクエリを実行するため、アプリケーションで遅延の問題が発生します。get_value_for_datastore()関数を使用して、単一値のプロパティに対してこれを処理する方法について、良いアドバイスを受けました。ただし、以下のコードに示すように、私のアプリケーションにも1対多の関係があり、これらのエンティティをプリフェッチする方法が見つかりませんでした。その結果、200個のドキュメントとそれに関連するdocumentFiles(> 6000ms)のテーブルを表示しようとすると、許容できない遅延が発生します。

(おそらく、10.000を超えるドキュメントまたはDocumentFileは存在しません)

これを解決する方法はありますか?

models.py

class Document(db.Expando):
    title = db.StringProperty()
    lastEditedBy = db.ReferenceProperty(DocUser, collection_name = 'documentLastEditedBy')  
...

class DocUser(db.Model):
    user = db.UserProperty()
    name = db.StringProperty()  
    hasWriteAccess= db.BooleanProperty(default = False)
    isAdmin = db.BooleanProperty(default = False)
    accessGroups = db.ListProperty(db.Key)
...

class DocumentFile(db.Model):
    description= db.StringProperty()
    blob = blobstore.BlobReferenceProperty()
    created = db.DateTimeProperty() # needs to be stored here in relation to upload / download of everything    
    document = db.ReferenceProperty(Document, collection_name = 'files')

    @property
    def link(self):     
        return '<a href="/file/serve/%s">%s</a>' % (self.key().id(),self.blob.filename) 
...

main.py

docUsers = DocUser.all()
docUsersNameDict = dict([(i.key(), i.name) for i in docUsers])

documents = Document.all()
for d idocuments:        
    out += '<td>%s</td>' % d.title    
    docUserKey = Document.lastEditedBy.get_value_for_datastore(d)
    out +='<td>%s</td>' % docUsersNameDict.get(docUserKey)
    out += '<td>'                           
    # Creates a new query for each document, resulting in unacceptable latency
    for file in d.files: 
        out +=  file.link + '<br>'
    out += '</td>'  
4

2 に答える 2

2

リンクを非正規化してドキュメントに保存すると、リンクをすばやく取得できます。

DocumentFile を更新するときは、関連する Document を更新する必要があることに注意する必要があります。これは、リンクを更新するよりもはるかに頻繁にデータストアからリンクを読み取るという前提で動作します。

非正規化は、多くの場合、App Engine でのパフォーマンスの低下を修正します。

于 2012-04-30T15:32:14.670 に答える
1

ファイルを非同期でロードします。d.files で get_value_for_datastore を使用すると、キーのコレクションが返されます。これにより、db.get_async(key) を実行して将来のオブジェクトを返すことができます。行ったように手続き的に結果を書き出すことはできませんが、保留中の将来の get() のコレクションを使用して、すべてのドキュメントの部分的な要求/辞書を組み立てるのは簡単なはずです。結果を構築すると、{~0ms のレイテンシ} をブロックすることなく終了する先物を完成させることができます。

基本的に、2 回の繰り返しが必要です。最初の反復では、必要なファイルを非同期で要求します。2 回目の反復では、gets を終了し、応答を作成します。

https://developers.google.com/appengine/docs/python/datastore/async

于 2012-04-30T15:43:25.117 に答える