2011-01-18 56 views
18

Google App Engineには、アイテムのリスト(配列)を保持できるListPropertyなどがあります。保持するアイテムのタイプ(文字列、整数など)を指定することもできます。Google App Engine for Pythonのリファレンスリスト

Google App Engineでは、参照プロパティを持つこともできます。 ReferencePropertyには、別のGoogle App Engine Modelエンティティへの参照が含まれています。 ReferencePropertyにアクセスすると、参照先が指す実際のエンティティが自動的に取得されます。これは、キーを取得するのに勝つので、便利です。そして、そのキーのエンティティを取得します。

しかし、ListReferenceProperty(またはReferenceListProperty)のようなものは表示されません。私はリスト内の要素にアクセスしようとすると自動的に解決される、他のエンティティへの参照のリストを保持したいと思います。私が得ることができる最も近いのは、db.Keyオブジェクトのリストを保持することです。これらのキーを使用して、関連するエンティティをサーバーから手動で取得できます。

これには良い解決策はありますか?基本的には、他のエンティティへの参照のコレクション(自動参照解除)が必要です。私は他のエンティティへのキーのコレクションを持っていることでほぼそこに着くことができますが、これらが重要な項目であることを「知る」ことができ、それを私のサービスとして参照することができます。

あなたは

答えて

13

ステップ1:

使用db.ListProperty(db.Key)の関係を作成します。 ListPropを、多対多リレーションシップで参照が少ないEntity上に配置したいとします。これはまたあなたに後方参照を与えるでしょう。したがって:

class Spam 
    prop1 = db.String 
    eggs = db.List 

class Eggs 
    prop1 = db.string 
    @property 
    def spams(self): 
    return Spam.all().filter('eggs', self.key()) 

これは両方の方法を参照します。

ステップ2:

性質をderefrences utlilityメソッドを作成します。

def prefetch_refprops(entities, *props): 
    """Dereference Reference Properties to reduce Gets. See: 
    http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine 
    """ 
    fields = [(entity, prop) for entity in entities for prop in props] 
    ref_keys = [prop.get_value_for_datastore(x) for x, prop in fields] 
    ref_entities = dict((x.key(), x) for x in db.get(set(ref_keys))) 
    for (entity, prop), ref_key in zip(fields, ref_keys): 
     prop.__set__(entity, ref_entities[ref_key]) 
    return entities 

使用法は次のようになります。

derefrenced_spams = prefetch_refprops(Spams, models.Spam.eggs)  
+0

スティーブンあなたはこれを試してみたのですか?私はいつもこの方法を使いますが、それはもともとGoogle App Engine IRCで仲良くしている人々によって提案されました。 –

+0

申し訳ありませんが、私は現在の反復ループの外に出てすぐにこれを試してみます。ご回答いただきありがとうございます。 –

+0

ええ、それは何かです。私はそれがReferencesのリストであり、それでもなおだということを理解していた実際のPropertyなら、それはうまくいくでしょう。これは私がこれまで見てきた最高の答えです。 –

6

そうだね、何がReferenceListPropertyに建てありませんありがとうございました。カスタムPropertyサブクラスは一般的にはかなり簡単ですが、参照のリストを参照およびキャッシングする場合は、思うよりも難しくなります。

ただし、db.ListProperty(db.Key)を使用すると、キーのリストを保存できます。次に、バッチを使用して個別にまたはすべてを一度にロードすることができますdb.get()操作。これを行うには、自分で解決手順を実行する必要がありますが、エンティティの参照を解除するタイミングをより詳細に制御できます。

関連する問題