2

Google App Engine で Django-nonrel を使用しており、次のモデルがあります (簡略化されています)。

class Author(models.Model):
    name = models.CharField()

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField()

したがって、このようにクエリすると、

books = Book.objects.all()

ブックをテンプレートに渡し、以下のように表示します。

<ul>
{% for book in books %}
   <li>{{ book.title }}{{ book.author.name }}</li>
{% endfor %}
</ul>

book.author.name が原因で、AppStats に多数の datastore.get が表示されます。書籍を照会するときは select_related() を使用する必要があると考えていましたが、Google App Engine には JOIN がないため、明らかに django nonrel はサポートされていません。

この種のシナリオに対処する方法を誰か教えてもらえますか? モデルの非正規化を検討する必要がありますか? 操作方法を教えていただけると助かります。

ありがとう、ユウ

4

2 に答える 2

1

これは、参照プロパティで発生するRPC呼び出しの数が原因で発生します。RPCのオーバーヘッドを克服するには、参照プロパティをプリフェッチする必要があります。django-nonrelで参照プロパティのプリフェッチを行う方法がわかりません。Nickによるこのブログを見てください。これは、appengineで参照プロパティのRPCオーバーヘッドを克服する方法を説明しています。django-nonrelでは、自分で理解する必要があります。

于 2011-05-24T12:11:43.163 に答える
1

Abdul が数日間言ったように、Django-Nonrel で get_value_from_datastore の方法を見つけるのに苦労しました。しかし、運がありません。それで、ついに Twitter で @wkornewald に尋ねたところ、彼はmodel.<foreignkey>_id.

今、ニックのソリューションを Django-nonrel に移植しました。私は Python に比較的慣れていないので、これは適切なコーディングではないかもしれませんが、期待どおりに機能します。

def prefetch_refprop(entities, prop_id, prop, filter):
    ref_ids = [getattr(x, prop_id) for x in entities]
    ref_entities = dict((x.id, x) for x in filter(id__in=ref_ids))
    for entity, ref_id in zip(entities, ref_ids):
        setattr(entity, prop, ref_entities[ref_id])
    return entities   

#Usage
books = Book.objects.filter(...)
prefetch_refprop(books, 'author_id', 'author', getattr(Author.objects, 'filter'))

みんな、ありがとう。
ユー

于 2011-05-30T10:04:23.707 に答える