3

我在设计一个使用命名空间的多租户系统。在命名空间多租户Appengine应用程序中管理全局数据

用户通过OpenID进行身份验证,用户模型保存在云数据存储中。用户将被分组到组织中,也在数据库中建模。应用程序数据需要按组织进行分区。

所以我们的想法是将命名空间映射到“组织”。

当用户登录时,他们的组织被查找并保存在会话中。

WSGI中间件检查会话并相应地设置命名空间。

我的问题涉及到如何最好地管理是“全球性”(即用户和组织)和应用程序数据(通过组织命名空间)

我目前的做法是使用Python装饰和上下文管理者的数据之间切换临时切换到访问这些全局数据的操作的全局名称空间。例如

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中的命名空间。我的另一种想法是将云数据存储中的所有“全局”数据提取到外部Web服务中,但我宁愿尽可能避免这种情况。

感谢您的建议。在此先感谢

+0

嗨。你有没有找到更好的解决方案?我有相同的体系结构,很难弄清楚如何使用例如全局(对于身份验证)和私有(对于外键)名称空间中的用户模型。 – 2013-06-23 19:07:00

回答

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的文档。

相关问题