在 python appengine 中,我有一个 polymodel 类(例如Animal
)。我在数据存储中存储了一些子类的实例(例如Horse
)。
Horse
如果我在python源代码中删除类的定义(或更改其名称),并Horse
使用db.get
和实体键获取存储的实体,会发生什么?
例如,检索到的实体是类型Animal
吗?PolyModel
? 会有例外吗?
在 python appengine 中,我有一个 polymodel 类(例如Animal
)。我在数据存储中存储了一些子类的实例(例如Horse
)。
Horse
如果我在python源代码中删除类的定义(或更改其名称),并Horse
使用db.get
和实体键获取存储的实体,会发生什么?
例如,检索到的实体是类型Animal
吗?PolyModel
? 会有例外吗?
数据存储本身并不真正了解/关心 python 类或数据模型本身,这些实际上只是特定于 GAEdb
或ndb
客户端库的实现细节。您可以在创建实体示例(使用通用 python 客户端库,没有模型定义)中看到 - 实体数据很简单,是一个具有名称-值对的字典:
task = datastore.Entity(client.key('Task'))
task.update({
'category': 'Personal',
'done': False,
'priority': 4,
'description': 'Learn Cloud Datastore'
})
在应用程序中重命名/删除实体模型不会删除数据存储区中的实体,您仍然可以在数据存储区浏览器中看到它们。
已创建实体的键中嵌入了实体类型(作为字符串)。尝试db.get()
对已保存的密钥执行操作将引发KindError
异常,因为它会根据导入的模型检查从数据存储返回的数据:
Traceback (most recent call last):
File "/usr/local/google_appengine/google/appengine/tools/devappserver2/python/request_handler.py", line 226, in handle_interactive_request
exec(compiled_code, self._command_globals)
File "<string>", line 12, in <module>
File "/usr/local/google_appengine/google/appengine/ext/db/__init__.py", line 1540, in get
return get_async(keys, **kwargs).get_result()
File "/usr/local/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
return self.__get_result_hook(self)
File "/usr/local/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1715, in __get_hook
entities = extra_hook(entities)
File "/usr/local/google_appengine/google/appengine/api/datastore.py", line 643, in local_extra_hook
return extra_hook(result)
File "/usr/local/google_appengine/google/appengine/ext/db/__init__.py", line 1509, in extra_hook
cls1 = class_for_kind(entity.kind())
File "/usr/local/google_appengine/google/appengine/ext/db/__init__.py", line 299, in class_for_kind
raise KindError('No implementation for kind \'%s\'' % kind)
KindError: No implementation for kind 'Horse'
因此,如果您想对模型进行返工并重新使用已存储的数据,您应该保留旧模型以便能够读取数据并将其写回新模型下。