db.字符串属性但属性偶尔为datastore_types.文本

2024-04-19 12:42:01 发布

您现在位置:Python中文网/ 问答频道 /正文

在什么情况下GAE数据存储可能会将属性类型从StringProperty更改为{}(实际上忽略了模型定义)?在

考虑以下情况(简化):

class MyModel(db.Model):
    user_input = db.StringProperty(default='', multiline=True)

我的数据存储中此模型的一些实体实例的数据类型为TextProperty,用于“用户输入”(而不是简单的str),因此没有索引。我可以通过检索实体、设置model_instance.user_input = str(model_instance.user_input)并将该实体放回数据存储中来解决这个问题。在

我不明白的是,在这个模型没有改变的情况下,这种情况是如何发生在一些实体上的。有没有可能数据库模型的属性是否可以从StringProperty重写为TextProperty?在


Tags: 数据instance模型实体类型inputdbmodel
3条回答

至少在ndb中,如果StringProperties未被索引,则包含Unicode的StringProperties有一个特殊的代码路径。在这种情况下,它将更改为文本属性: 相关片段是:

if isinstance(value, str):
  v.set_stringvalue(value)
elif isinstance(value, unicode):
  v.set_stringvalue(value.encode('utf8'))
  if not self._indexed:
    p.set_meaning(entity_pb.Property.TEXT)

我无法在Python端观察到这一点(请参见db.StringProperty but property is occasionally datastore_types.Text?),但我在数据存储中看到了这一点,并且在将数据存储加载到BigQuery时会引起一些麻烦。在

所以只使用:

  • StringProperty(indexed=True)
  • 文本属性()

如果可能向属性写入混合的unicode和{}值,请避免StringProperty(indexed=False),因为这往往发生在外部数据中。在

通过使用setattrsetattr(some_instance, 'string_type', some_instance.text_type),您实际上已经使名为string_type property的实例属性实际指向text_type属性。所以两个名字一个财产

The db, ndb, users, urlfetch, and memcache modules are imported.
> from google.appengine.ext import db
> class TestModel(db.Model):
...    string_type = db.StringProperty(default='', multiline=True)
...    text_type = db.TextProperty()
... 
> 
> some_instance = TestModel()
> some_instance.text_type = 'foobar'
> setattr(some_instance, 'string_type', some_instance.text_type)
> print type(some_instance.string_type)
<class 'google.appengine.api.datastore_types.Text'>
y> repr(some_instance.string_type)
"u'foobar'"
> id(some_instance.string_type)
168217452
> id(some_instance.text_type)
168217452
> some_instance.string_type.__class__
<class 'google.appengine.api.datastore_types.Text'>
> some_instance.text_type.__class__
<class 'google.appengine.api.datastore_types.Text'>
> dir(some_instance.text_type.__class__)

注意上面两个属性的id。在

因此,您可以有效地重新绑定实例级属性定义,然后将修改后的模型与字段类型一起写入数据存储。在

如果您想使用setattr(虽然在这个人为的例子中看不出原因),您应该首先使用setattr(some_instance.string_type,TestModel.string_type.get_value_for_datastore(some_instance) )从属性中获取值,以获得要分配的值,而不是重新绑定instances属性。在

StringProperty有500个字符的长度限制。我不确定,但如果超过限制,数据存储可能会将StringProperty转换为TextProperty。在

尽管如此,我怀疑GAE是否会隐式地将索引属性更改为非索引属性。我想得出来。在

相关问题 更多 >