GAE,删除 NDB 命名空间

Posted

技术标签:

【中文标题】GAE,删除 NDB 命名空间【英文标题】:GAE, delete NDB namespace 【发布时间】:2013-09-14 21:59:49 【问题描述】:

在 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 )

但是,在开发服务器上,调用时命名空间仍然存在:

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】:

查看 SDK (https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/ndb/metadata.py#224) 中 ndb.metadata.get_namespaces 的实际实现,看起来命名空间列表存储在 Datastore 本身中,在名为 Namespace 的模型中,类型为 __namespace__

虽然我自己从未尝试过此操作,但也许您可以在数据存储区中为您想要删除的命名空间找到相应的实体,然后将其删除。然后,下次您调用ndb.metadata.get_namespaces 时,查询结果不应包含您刚刚删除的命名空间的实体。

【讨论】:

是的,这是可行的。但是,我不太喜欢弄乱未记录的保留系统名称。这些可能不像“正常”实体。例如,我无法删除 Stat_Ns_Kind(请参阅我的问题)。无论如何,我会试一试并报告。谢谢! 看起来__namespace__ 的行为不像正常类型。特别是删除实体无效。 (添加有问题的代码sn-p,直接修改__namespace__不起作用)

以上是关于GAE,删除 NDB 命名空间的主要内容,如果未能解决你的问题,请参考以下文章

删除 XML 命名空间,同时忽略根中的命名空间

从 XML 中删除多个 XML 命名空间

命名空间“卡住”为终止,我如何删除它

Socket.IO:如何删除命名空间

如何在Linux上一次删除所有网络命名空间

删除 Soap 标头和命名空间