为每个用户提供自己的数据库

时间:2013-09-21 19:20:38

标签: python database sqlalchemy pyramid

我正在构建我的应用程序,以便每个用户都有自己的数据库(以便轻松隔离,并最大限度地减少分片需求)。这意味着每个Web请求和所有后台脚本都需要根据发出请求的用户连接到不同的数据库,并将该连接用于所有函数调用。

我想我可以制作某种中间件,通过将它连接到request变量来将正确的连接传递给我的Web请求,但我不知道应该如何确保所有函数和模型方法请求调用使用此连接。

1 个答案:

答案 0 :(得分:1)

如何“确保请求调用的所有函数和模型方法都使用此连接”很容易。您将连接传递给api,就像任何设计良好的代码一样,这些代码不依赖于全局变量。因此,您按请求加载了数据库会话对象,并将其传递下来。模型对象很容易在没有显式传递的情况下进一步传递会话对象,因为每个托管对象都知道会话拥有它,并且您可以从那里查询它。

db = request.db
user = db.query(User).get(1)
user.add_group('foo')

class User(Base):

    def add_group(self, name):
        db = sqlalchemy.orm.object_session(self)
        group = Group(name=name)
        db.add(group)

我不建议你使用那个确切的模式,但它是一个如何从托管对象中获取会话的示例,避免必须在任何地方明确地传递会话。

关于您的原始问题,如何处理多租户...在您的数据模型中!设计一个系统,在这个系统中你将事物分解到一个低水平是一个巨大的维护负担,它不能很好地扩展。例如,当您具有任意数量的独立连接时,使用任何类型的连接池变得非常困难。为了解决这些问题,人们通常使用某些数据库支持的SQL SCHEMA功能。这允许您使用相同的连接,但每个会话可以访问不同的表结构。这样做更好,但是再次独立管理所有这些模式应该会引发一些危险信号,在数据模型中出现所有重复项,从而违反DRY。在该级别的任何重复很快就会成为您需要做好准备的负担。