我正在使用命名空间设计多租户系统。
用户通过OpenID进行身份验证,用户模型保存在Cloud Datastore中。用户将被分组到组织中,也在数据库中建模。应用程序数据需要按组织进行分区。
因此,我们的想法是将名称空间映射到“组织”。
当用户登录时,会查找其组织并将其保存在会话中。
WSGI中间件检查会话并相应地设置名称空间。
我的问题涉及如何最好地管理“全局”(即用户和组织)数据与应用程序数据(按组织命名)之间的切换
我目前的方法是使用python装饰器和上下文管理器临时切换到访问此类全局数据的操作的全局名称空间。 e.g。
standard_datastore_op()
with global_namespace():
org = Organization.query(Organization.key=org_key)
another_standard_datastore_op(org.name)
或
@global_namespace
def process_login(user_id):
user = User.get_by_id(user_id)
这也意味着模型具有跨命名空间KeyProperties:
class DomainData(ndb.Model): # in the current user's namespace
title = ndb.StringProperty()
foreign_org = ndb.KeyProperty(Organization) #in the "global" namespace
这看起来是否合理?这对我来说感觉有点脆弱,但我怀疑这是因为我不熟悉App Engine中的命名空间。我的另一个想法是将所有“全局”数据从Cloud Datastore提取到外部Web服务中,但如果可能的话我宁愿避免这种情况。
建议感激不尽。提前致谢
答案 0 :(得分:0)
装饰器是一种非常精细的方法,它还具有明确标记哪些功能在组织特定的命名空间边界之外运行的好处。
def global_namespace(global_namespace_function):
def wrapper():
# Save the current namespace.
previous_namespace = namespace_manager.get_namespace()
try:
# Empty string = default namespace, change to whatever you want to use as 'global'
global_namespace = ''
# Switch to 'global' namespace
namespace_manager.set_namespace(global_namespace)
# Run code that requires global namespace
global_namespace_function()
finally:
# Restore the saved namespace.
namespace_manager.set_namespace(previous_namespace)
return wrapper
在相关说明中,我们还提供了有关使用namespaces for multitenenacy。
的文档