7

私は、GAEとPython2.7ランタイムの上に最初のRESTfulWebサービスを作成しているところです。Guidoの光沢のある新しいndbAPIを使い始めました。

ただし、元のdbAPIの暗黙的な後方参照機能を使用せずに特定のケースを解決する方法がわかりません。ユーザーエージェントが特定のリソースを要求し、それらのリソースが1度削除された場合:

host / api / kind / id?depth = 2

関連するエンティティの種類が開発時に不明であるとすると、1対多の関係にある「1つ」から関連するエンティティのコレクションを見つけるための最良の方法は何ですか?

  • 後者の制限のため、前のSO照会で説明したように置換照会を使用できません。モデルが実行時に定義可能である(したがってハードコーディングされていない)という事実により、クエリを使用して一致するキーのプロパティをフィルタリングすることができません。

  • データストアの制限により、種類を指定せずにプロパティをフィルタリングできないため、祖先やその他の種類のないクエリも使用できなくなります。

これまでのところ、(db apiに戻る以外に)私が持っていた唯一のアイデアは、グループ間トランザクションを使用して、次のようなndb.StringProperty(repeat = True)を更新することにより、「1つ」に独自の参照を書き込むことです。新しい種類のエンティティが導入されたとき、または関連する「多くの」エンティティがデータストアに書き込まれるたびに「1つの」ndb.KeyProperty(repeat = True)にキーのリストを保持することによって、関連するすべての種類。

私よりも経験豊富な人がより良いアプローチを提案できることを願っています。

jmort253の提案を踏まえて、ドキュメントから採用した具体的な例を使用して、質問を補強してみます。

class Contact(ndb.Expando):
    """ The One """

    # basic info
    name = ndb.StringProperty()
    birth_day = ndb.DateProperty()

    # If I were using db, a collection called 'phone_numbers' would be implicitly 
    # created here.  I could use this property to retrieve related phone numbers 
    # when this entity was queried.  Since NDB lacks this feature, the service 
    # will neither have a reference to query nor the means to know the 
    # relationship exists in the first place since it cannot be hard-coded.  The
    # data model is extensible and user-defined at runtime; most relationships
    # will be described only in the data, and must be discoverable by the server.
    # In this case, when Contact is queried, I need a way to retrieve the
    # collection of phone numbers.

    # Company info.
    company_title = ndb.StringProperty()
    company_name = ndb.StringProperty()
    company_description = ndb.StringProperty()
    company_address = ndb.PostalAddressProperty()

class PhoneNumber(ndb.Expando):
    """ The Many """

    # no collection_name='phone_numbers' equivalent exists for the key property
    contact = ndb.KeyProperty(kind='Contact')
    number = ndb.PhoneNumberProperty()
4

2 に答える 2

8

面白い質問です!したがって、基本的には、Contactクラスを調べて、それを参照するKeyPropertyを持つ他のモデルクラスがあるかどうかを確認する必要があります。この例ではPhoneNumberです(ただし、多くの場合があります)。

解決策は、PhoneNumberクラスの作成時に、このリンクを明示的に追加するようにユーザーに依頼することだと思います。

これを処理するKeyPropertyのサブクラスをユーザーに与えることで、ユーザーがこれを簡単に行えるようにすることができます。例えば

class LinkedKeyProperty(ndb.KeyProperty):
    def _fix_up(self, cls, code_name):
        super(LinkedKeyProperty, self)._fix_up(cls, code_name)
        modelclass = ndb.Model._kind_map[self._kind]
        collection_name = '%s_ref_%s_to_%s' % (cls.__name__,
                                               code_name,
                                               modelclass.__name__)
        setattr(modelclass, collection_name, (cls, self))

コレクションの名前とそこに保存する値を正確に選択する方法はあなた次第です。そこに何かを置くだけで、リンクを簡単にたどることができます。この例では、Contactに新しい属性を作成します。

Contact.PhoneNumber_ref_contact_to_Contact == (PhoneNumber, PhoneNumber.contact)

[コードを機能させ、例を追加するように編集しました。:-)]

于 2012-05-24T14:04:00.273 に答える
2

の良いユースケースのように聞こえますndb.StructuredProperty

于 2012-05-24T11:49:39.070 に答える