Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine NDB在重复Expando StructuredProperty中查询GenericProperty_Google App Engine_Python 2.7_App Engine Ndb - Fatal编程技术网

Google app engine NDB在重复Expando StructuredProperty中查询GenericProperty

Google app engine NDB在重复Expando StructuredProperty中查询GenericProperty,google-app-engine,python-2.7,app-engine-ndb,Google App Engine,Python 2.7,App Engine Ndb,嘿,伙计们,我正试图找出如何为下面的案例构造我的查询 首先我定义了一个模型 class Variant(ndb.Expando): test = ndb.StringProperty() class Item(ndb.Model): test2 = ndb.StringProperty() variants = ndb.StructuredProperty(Variant, repeated=True) variant = Variant(test="test",

嘿,伙计们,我正试图找出如何为下面的案例构造我的查询

首先我定义了一个模型

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", ]

谢谢你的帮助

你可以用一点魔法做到这一点

简短回答

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

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')
类似地,在查询
结构化属性时,可以使用属性属性的状态,例如:

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'
使用GQL很容易:

Item.gql("WHERE variants.dynamic = 'a'").fetch()
这也适用于:

s = StringProperty()
s._name = 'variants.dynamic')
Item.query(s == 'a').fetch()
请提交功能请求;然而,这将是一个平衡的行动。您希望使用什么语法

更新:

这同样适用于GenericProperty()或任何其他属性子类

禁止GenericProperty('variants.dynamic')的原因是为了防止人们进行这样的黑客行为:

class MyHack(ndb.Model):
  foo = StringProperty('bar.baz')
这将混淆序列化和反序列化代码

也许我们可以向属性添加一个标志,该标志跳过此检查,但不允许在模型定义中使用该属性(它只允许在查询中使用)

或者我们可以做到这一点(我认为这很难做到):


(仅当变体是Expando时)。

黑客解决方案

variants_dynamic_property = ndb.GenericProperty()
variants_dynamic_property._name = 'variants.dynamic'
q = Item.query(variants_dynamic_property == 'a')
临时解决方案:使用
ComputedProperty
查询-在本例中:

(将以下内容添加到模型定义中)


您是否尝试过
Item.query(ndb.GenericProperty('variants.dynamic')=='a')
?尝试实例化
ndb.GenericProperty('variants.dynamic')
会导致
ValueError:Name'variants.dynamic'不能包含
ndb/model.py
第765行中的句点字符。这似乎应该是一个功能请求。这不是等同于Item.query(ndb.query.FilterNode(“变体。%s”%dynamic,“=”,“a”)?你测试过这是否真的有效吗?是的,它确实有效,但正如我在写下这篇文章后痛苦地发现的,不是针对重复的属性。我还在努力。我不确定这两者是否相等,但它们很可能是相等的。当已经完全忘记了gql,这当然是一个简单的解决方案。我认为正确的语法应该是GenericProperty(“variants.dynamic”),因为目标属性毕竟是GenericProperty。您的示例适用于任何类型还是仅适用于字符串?最后一个解决方案不适用于我,因为我必须从字符串引用属性。