3

Google App Engine で参照プロパティをキャッシュするにはどうすればよいですか?

たとえば、次のモデルがあるとします。

class Many(db.Model):
    few = db.ReferenceProperty(Few) 

class Few(db.Model):
    year = db.IntegerProperty()

Many次に、1 つだけを指す多くの を作成しますFew

one_few = Few.get_or_insert(year=2009)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)

ここで、すべての を反復処理して値をMany読み取りたい場合は、次のようにします。few

for many in Many.all().fetch(1000):
  print "%s" % many.few.year

質問は:

  • アクセスごとmany.fewにデータベース ルックアップがトリガーされますか?
  • はいの場合、毎回同じエンティティを取得するには1回のルックアップで十分であるため、どこかにキャッシュすることは可能ですか?

あるコメントで述べたように、memcache については知っていますが、参照を介して他のエンティティを呼び出すときに「注入」する方法がわかりません。

いずれにせよ、実行間ではなく実行内でキャッシングする必要があるため、memcache は役に立ちません。memcache を使用しても、この呼び出しの最適化には役立ちません。

4

2 に答える 2

8

参照プロパティを初めて逆参照すると、別の参照プロパティに関連付けられた同じエンティティを以前にフェッチした場合でも、エンティティがフェッチされます。これにはデータストアの get 操作が含まれます。これはクエリほど高価ではありませんが、可能であれば避ける価値があります。

ここで利用可能なエンティティのシームレスなキャッシュを追加する優れたモジュールがあります。これはデータストアの下位レベルで機能し、ReferenceProperties を逆参照するだけでなく、すべてのデータストア取得をキャッシュします。

多数の参照プロパティを一度に解決したい場合は、別の方法があります。次のように、すべてのキーを取得し、エンティティを 1 回のラウンド トリップで取得できます。

keys = [MyModel.ref.get_value_for_datastore(x) for x in referers]
referees = db.get(keys)

最後に、リクエストごとにエンティティをローカルにキャッシュするように db モジュールにモンキーパッチを適用するライブラリを作成しました (memcache は関係ありません)。こちらから入手できます。ただし、1 つの警告があります。単体テストがありますが、広く使用されていないため、壊れている可能性があります。

于 2009-07-23T21:57:58.527 に答える
1

質問は:

  1. many.few にアクセスするたびに、データベース ルックアップがトリガーされますか? はい。呼び出しが 1 回なのか 2 回なのかわからない
  2. はいの場合、毎回同じエンティティを取得するには1回のルックアップで十分であるため、どこかにキャッシュすることは可能ですか? これを行うには、memcache リポジトリを使用できるはずです。これは google.appengine.api.memcache パッケージにあります。

memcache の詳細はhttp://code.google.com/appengine/docs/python/memcache/usingmemcache.htmlにあります。

于 2009-07-23T20:18:06.297 に答える