GAE,删除NDB命名空间

时间:2013-09-14 21:59:49

标签: google-app-engine namespaces google-cloud-datastore

在Google App Engine中,使用NDB,如何完全删除整个命名空间?

以下代码删除所有实体:

def delete(namespace):

    namespace_manager.set_namespace(namespace)

    for kind in ndb.metadata.get_kinds():
        keys = [ k for k in ndb.Query(kind=kind).iter(keys_only=True) ]
        ndb.delete_multi( keys )

但是,在dev服务器上,调用时名称空间仍然存在:

ndb.metadata.get_namespaces()

并且,在生产中,尝试删除系统类型时会引发异常,例如:

illegal key.path.element.type: __Stat_Ns_Kind__

如何完全消除命名空间?

正如@jeremydw所指出的,名称空间信息以__namespace__种存储。但是,这不是正常类型,特别是删除实体似乎没有任何影响:

id_namepace = 'some_test'

print list( ndb.Query(kind='__namespace__') ) 
# id_namespace is not present
# SomeModel is some existing model
key_entity = ndb.Key('SomeModel', 'some_string_id', namespace=id_namepace)
entity = datastore.CustomerAction(key=key_entity)
entity.put()
print list( ndb.Query(kind='__namespace__') )
# id_namespace is present (expected, namespace was implicitly created by adding one entity in it)
key_entity.delete()
print list( ndb.Query(kind='__namespace__') )
# id_namespace is present (expected, namespace still exists but contains no entities)
key_namespace = ndb.metadata.Namespace.key_for_namespace(id_namepace)
key_namespace.delete()
print list( ndb.Query(kind='__namespace__') )
# id_namespace is still present (not expected, kind='__namespace__' does not behave as a normal kind)

1 个答案:

答案 0 :(得分:1)

在SDK(https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/ndb/metadata.py#224)中查看ndb.metadata.get_namespaces的实际实现,看起来命名空间列表存储在数据存储区本身,名为Namespace的模型中,具有kind { {1}}。

虽然我自己没有尝试过这种方法,但也许您可以在数据存储区中找到要删除的命名空间的相应实体,然后将其删除。然后,下次调用__namespace__时,查询结果不应包含刚刚删除的命名空间的实体。