google-app-engine - App Engine 多个命名空间

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

最近我们的应用程序发生了一些数据结构变化,我们决定使用命名空间来分隔不同版本的数据,并使用 mapreduce 任务将旧实体转换为新格式。

现在一切都很好,但我们不想总是孤立我们拥有的整个数据集。我们数据的大部分存储在一种非常简单且不需要经常更改的类型中。所以我们决定使用每个种类的命名空间。

类似于:

class Author(ndb.model.Model):
    ns = '2'

class Book(ndb.model.Model):
    ns = '1'

因此,当迁移到版本 2 时,我们不需要转换所有数据(并将所有“书籍”类型复制到其他 namespace ),只需转换“作者”类型的实体。然后,我们不定义 appengine_config.namespace_manager_default_namespace_for_request,而是将“namespace”关键字参数添加到我们的查询中:

Author.query(namespace=Author.ns).get()

问题如何使用这些不同的命名空间来存储(即put())不同的种类?像这样的东西:

# Not an API
Author().put(namespace=Author.ns)

当然,以上是行不通的。 (是的,我可以向数据存储区询问该命名空间中的可用 key ,然后使用该 key 来存储实例,但这是我想避免的额外 API 调用。)

最佳答案

为了解决这样的问题我写了一个装饰器如下:

MY_NS = 'abc'

def in_my_namespace(fn):
    """Decorator: Run the given function in the MY_NS namespace"""
    from google.appengine.api import namespace_manager

    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        orig_ns = namespace_manager.get_namespace()
        namespace_manager.set_namespace(MY_NS)

        try:
            res = fn(*args, **kwargs)
        finally: # always drop out of the NS on the way up.
            namespace_manager.set_namespace(orig_ns)

        return res

    return wrapper

所以我可以简单地写,对于应该出现在一个单独的命名空间中的函数:

@in_my_namespace
def foo():
   Author().put() # put into `my` namespace

当然,将其应用于系统以获得您想要的结果有点超出了本文的范围,但我认为它可能会有所帮助。

编辑:使用 with 上下文

以下是使用 with 上下文完成上述操作的方法:

class namespace_of(object):
    def __init__(self, namespace):
        self.ns = namespace

    def __enter__(self):
        self.orig_ns = namespace_manager.get_namespace()
        namespace_manager.set_namespace(self.ns)

    def __exit__(self, type, value, traceback):
        namespace_manager.set_namespace(self.orig_ns)

然后在别处:

with namespace_of("Hello World"):
    Author().put() # put into the `Hello World` namespace

关于google-app-engine - App Engine 多个命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9296303/

相关文章:

java - 数据存储和 Memcache 一致性 - Google App Engine 和 Objectify

python - NDB 查询生成器无法按预期工作

android - GCM 注册适用于调试 APK 但不适用于发布 APK

c# - 从数据存储中检索 key (更新和删除实体)

python - 祖先索引消耗的存储空间更少吗?大约会消耗多少存储空间?

java - 为什么应用程序引擎应用程序不断调用数据存储区 v3.Put

java - 更新 gwt CellList 中的图像

php - 将 MySQL(通过 MAMP 安装)连接到 Google App Engine SDK

ios - 我们是否必须生成并使用客户端库才能使用 Google App Engine 的端点?

java - 如何使用数据存储 api 对子实体进行排序