我正在构建我的应用程序,以便每个用户都有自己的数据库(以便于隔离,并最大限度地减少对分片的需求)。这意味着每个 Web 请求和所有后台脚本都需要根据发出请求的用户连接到不同的数据库,并将该连接用于所有函数调用。
我想我可以制作某种中间件,通过将它附加到request
变量来传递正确的连接到我的网络请求,但我不知道我应该如何确保请求调用的所有函数和模型方法都使用这个连接。
我正在构建我的应用程序,以便每个用户都有自己的数据库(以便于隔离,并最大限度地减少对分片的需求)。这意味着每个 Web 请求和所有后台脚本都需要根据发出请求的用户连接到不同的数据库,并将该连接用于所有函数调用。
我想我可以制作某种中间件,通过将它附加到request
变量来传递正确的连接到我的网络请求,但我不知道我应该如何确保请求调用的所有函数和模型方法都使用这个连接。
那么如何“确保请求调用的所有函数和模型方法都使用这个连接”很容易。您将连接传递到您的 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。该级别的任何重复都会很快成为您需要做好准备的负担。