Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GAE, delete NDB namespace

In Google App Engine, using NDB, how can an entire namespace be entirely removed?

The following code removes all entities:

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 )

However, on the dev server, the namespace is still there when calling:

ndb.metadata.get_namespaces()

and, in production, exceptions are raised when trying to delete system kind, for example:

illegal key.path.element.type: __Stat_Ns_Kind__

How can a namespace be wiped out entirely?

As pointed out by @jeremydw, namespace information is stored in a __namespace__ kind. However, this does not behave as a normal kind and in particular, deleting entities does not seem to have any effect:

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)
like image 794
Eric PICHON Avatar asked Nov 12 '22 22:11

Eric PICHON


1 Answers

Looking at the actual implementation of ndb.metadata.get_namespaces in the SDK (https://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/ndb/metadata.py#224), it looks like the list of namespaces is stored in Datastore itself, in a model named Namespace with kind __namespace__.

While I haven't attempted this ever myself, perhaps you can find the corresponding entity in the Datastore for the namespace that you want to obliterate, and then delete it. Then, next time you call ndb.metadata.get_namespaces, the query results should not include the entity for the namespace that you just deleted.

like image 193
jeremydw Avatar answered Dec 19 '22 20:12

jeremydw