2

こんにちは、次のケースのクエリを構造化する方法を見つけようとしています。

まず、モデルを定義します

class Variant(ndb.Expando):
    test = ndb.StringProperty()


class Item(ndb.Model):
    test2 = ndb.StringProperty()
    variants = ndb.StructuredProperty(Variant, repeated=True)

variant = Variant(test="test", dynamic="a")
item = Item(test2="test", variants=[variant, ])
item.put()

そして、クエリのもののために..これまでのところ、私は試しました

dynamic = "dynamic"
Item.query(ndb.GenericProperty("variants.%s" % dynamic) == "a")
Item.query(Item._properties["variants.%s" % dynamic] == "a")
Item.query(getattr(Item.variants, dynamic) == "a")
Item.query(getattr(Item, "variants.%s" % dynamic) == "a")
Item.query(ndb.query.FilterNode("variants.%s" % dynamic, "=", "a"))

generic_prop = ndb.GenericProperty()
generic_prop._name = "variants.%s" % dynamic
Item.query(generic_prop == "a")

そして、これらのどれも機能しません..データストアのプロパティ名は

variants.dynamic = ["a", ]

ご協力ありがとうございました

4

3 に答える 3

4

GQL を使用すると簡単です。

Item.gql("WHERE variants.dynamic = 'a'").fetch()

これも機能します:

s = StringProperty()
s._name = 'variants.dynamic')
Item.query(s == 'a').fetch()

機能リクエストを提出してください。ただし、バランスをとる行為になります。どの構文を使用しますか?

アップデート:

同じことが GenericProperty() やその他の Property サブクラスでも機能します。

GenericProperty('variants.dynamic') が禁止されている理由は、人々が次のようなハッキングを行うのを防ぐためです:

class MyHack(ndb.Model):
  foo = StringProperty('bar.baz')

これにより、シリアライゼーションとデシリアライゼーションのコードが混乱します。

おそらく、このチェックをスキップするフラグをプロパティに追加できますが、モデル定義でのプロパティの使用は許可されません (クエリでのみ許可されます)。

または、これを機能させることもできます (ただし、これは難しいと思います)。

Item.query(Item.variants.dynamic == 'a').fetch()

(バリアントが Expando の場合のみ)。

于 2012-11-30T17:59:48.580 に答える
1

ちょっとした魔法でこれを行うことができます。

短い答え:

variants_dynamic_property = ndb.GenericProperty()
variants_dynamic_property._name = 'variants.dynamic'
q = Item.query(variants_dynamic_property == 'a')

長い答え:

をクエリしているため、ドキュメントの状態GenericPropertyとして作成する必要があります。たとえば、次のようになります。

FlexEmployee.query(ndb.GenericProperty('location') == 'SF')

同様に、 をクエリする場合StucturedPropertyドキュメントにはプロパティのプロパティを使用できると記載されています。

Contact.query(Contact.address.city == 'Amsterdam')

したがって、これらを組み合わせると、必要になります

Item.query(ndb.GenericProperty('variants.dynamic') == 'a')

ただし、プロパティを介して構築しようとするとndb.GenericProperty('variants.dynamic')、次の例外が発生します。

  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/utils.py", line 136, in positional_wrapper
    return wrapped(*args, **kwds)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2366, in __init__
    super(GenericProperty, self).__init__(name=name, **kwds)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/utils.py", line 136, in positional_wrapper
    return wrapped(*args, **kwds)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 765, in __init__
    raise ValueError('Name %r cannot contain period characters' % (name,))
ValueError: Name 'variants.dynamic' cannot contain period characters

ただし、プロパティ名を指定せずにコンストラクターを使用し、事後に名前を設定することで、これを回避できます。

variants_dynamic_property = ndb.GenericProperty()
variants_dynamic_property._name = 'variants.dynamic'
于 2012-11-30T07:37:22.020 に答える
0

ハックな解決策

一時的な解決策: a を使用しComputedPropertyてクエリを実行 - この場合:

(モデル定義に以下を追加)

computed_prop = ndb.ComputedProperty(lambda self: self.repeating_prop[0].sub_prop if self.repeating_prop else None)
于 2012-12-04T13:32:42.070 に答える