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
Python 将属性内置于GAE数据存储';s模型_Python_Google App Engine_Google Cloud Datastore - Fatal编程技术网

Python 将属性内置于GAE数据存储';s模型

Python 将属性内置于GAE数据存储';s模型,python,google-app-engine,google-cloud-datastore,Python,Google App Engine,Google Cloud Datastore,我想创建GAE模型属性的属性。原因是case喜欢在存储值之前将其转换为大写。对于普通Python类,我将执行以下操作: Foo(db.Model): def get_attr(self): return self.something def set_attr(self, value): self.something = value.upper() if value != None else None attr = property(get_at

我想创建GAE模型属性的属性。原因是case喜欢在存储值之前将其转换为大写。对于普通Python类,我将执行以下操作:

Foo(db.Model):
    def get_attr(self):
       return self.something
    def set_attr(self, value):
       self.something = value.upper() if value != None else None
    attr = property(get_attr, set_attr)
然而,GAE数据存储有自己的属性类概念,我研究了属性类,似乎可以覆盖
get\u value\u以实现我的目标。然而,我不知道什么是
model\u instance
,以及如何从中提取相应的字段

重写GAE属性类是提供类似getter/setter的功能的正确方法吗?如果是,怎么做

添加:

我想到的为_datastore
重写get_value_的一个潜在问题是,在将对象放入数据存储之前,它可能不会被调用。因此,在存储对象之前获取属性将产生不正确的值。

如果您希望在一个或多个模型中有多个具有类似行为的“字段”,则对GAE的类进行子类化尤其有用。别担心,
get_value\u for_datastore
make_value\u from_datastore
将分别在任何存储和获取上被调用——因此,如果您需要做任何花哨的事情(包括但不限于大写字符串,实际上并不那么花哨;-),在子类中重写这些方法很好

Edit:让我们看看一些示例代码(扣除导入和
main
):

这将显示字符串在数据存储中已大写——但是如果将
get
调用更改为简单的
mm=my
,您将看到内存中的实例没有受到影响

但是,
db.Property
实例本身就是一个描述符——将其包装到内置的
属性
(一个完全不同的描述符)中不会很好地用于数据存储(例如,您不能基于字段名编写GQL查询,这些字段名实际上不是
db.Property
的实例,而是
Property
的实例——这些字段在数据存储中不是

因此,如果您想同时使用数据存储和
Model
的实例,而这些实例实际上从未访问过数据存储并返回,那么您必须为逻辑上“相同”的内容选择两个名称字段——一个是要在内存模型实例上使用的属性的名称,一个可以是内置的
属性
;另一个是在数据存储中结束的属性的名称,该名称需要是
db.property
子类的实例,并且在查询中需要使用第二个名称。当然,第一个名字背后的方法需要读写第二个名字,但你不能只是“隐藏”第二个名字,因为这是数据存储中的名字,所以这是对查询有意义的名字!

如果你想要多个“字段”,子类化GAE的类尤其有用在一个或多个模型中,使用类似的行为。不要担心,
get\u value\u for_datastore
make\u value\u from_datastore
将分别在任何存储和获取上被调用——因此,如果您需要做任何花哨的事情(包括但不限于大写字符串,实际上并不那么花哨;-),在子类中重写这些方法就可以了

Edit:让我们看看一些示例代码(扣除导入和
main
):

这将显示字符串在数据存储中已大写——但是如果将
get
调用更改为简单的
mm=my
,您将看到内存中的实例没有受到影响

但是,
db.Property
实例本身就是一个描述符——将其包装到内置的
属性
(一个完全不同的描述符)中不会很好地用于数据存储(例如,您不能基于字段名编写GQL查询,这些字段名实际上不是
db.Property
的实例,而是
Property
的实例——这些字段在数据存储中不是


因此,如果您想同时使用数据存储和
Model
的实例,而这些实例实际上从未访问过数据存储并返回,那么您必须为逻辑上“相同”的内容选择两个名称字段——一个是要在内存模型实例上使用的属性的名称,一个可以是内置的
属性
;另一个是在数据存储中结束的属性的名称,该名称需要是
db.property
子类的实例,并且在查询中需要使用第二个名称。当然,第一个名字背后的方法需要读写第二个名字,但你不能只是“隐藏”后者是因为这是数据存储中的名称,因此这是对查询有意义的名称!

您想要的是一个。在那篇文章中概述了编写一个的过程-这与Alex所描述的类似,但是通过覆盖get而不是get\u value\u for\u数据存储,您避免了ne的问题正在写入数据存储以更新它。我的库中包含了它和其他有用的属性。

您想要的是一个。在那篇文章中概述了写入一个的过程-它与Alex描述的类似,但是通过覆盖get而不是get\u value\u for\u datastore,您可以避免需要写入数据的问题存储以更新它。我的库中包含了它和其他有用的属性。

我尝试使用覆盖的get\u value\u for\u数据存储扩展StringProperty,但我似乎没有做任何事情。为什么?忽略我的上述注释,这是我的错误。覆盖StringProperty确实有效。但是,我担心,只有在对象被放置到数据存储。我希望有一种方法
class MyStringProperty(db.StringProperty):
    def get_value_for_datastore(self, model_instance):
        vv = db.StringProperty.get_value_for_datastore(self, model_instance)
        return vv.upper()

class MyModel(db.Model):
    foo = MyStringProperty()

class MainHandler(webapp.RequestHandler):

    def get(self):
        my = MyModel(foo='Hello World')
        k = my.put()
        mm = MyModel.get(k)
        s = mm.foo
        self.response.out.write('The secret word is: %r' % s)