使用Vapor 3,有没有一种简单的方法可以在服务器运行时切换数据库?
例如,用户使用“登录”数据库登录。然后,我在他们的Cookie中为该用户设置数据库。然后,来自该用户的任何后续请求都将使用cookie中标识的数据库(在这种情况下,“用户”实际上是一家公司)。
所有数据库都来自相同的数据库家族(例如MySQL)。这样可以将每个公司的数据保留在各自的数据库中,并限制每个数据库的大小(并且希望总体而言,数据库操作会更快)。此外,还原数据库的任何需求只会影响一家公司,并且备份会更简单。
还有其他更好的方法来实现这一目标吗?
据我了解,您可以创建一些不同的数据库标识符,例如:
extension DatabaseIdentifier {
static var db1: DatabaseIdentifier<MySQLDatabase> {
return .init("db1")
}
static var db2: DatabaseIdentifier< MySQLDatabase > {
return .init("db2")
}
}
Run Code Online (Sandbox Code Playgroud)
然后configure.swift像这样注册他们
let db1 = MySQLDatabase(config: MySQLDatabaseConfig(hostname: "localhost", username: "root", database: "db1"))
let db2 = MySQLDatabase(config: MySQLDatabaseConfig(hostname: "localhost", username: "root", database: "db2"))
var databaseConfig = DatabasesConfig()
databaseConfig.add(database: db1, as: .db1)
databaseConfig.add(database: db2, as: .db2)
services.register(databaseConfig)
Run Code Online (Sandbox Code Playgroud)
之后,别忘了在各处使用.db1和.db2标识符,而不是默认值.mysql(对于MySQL),例如在迁移中
migrations.add(model: User.self, database: .db1)
Run Code Online (Sandbox Code Playgroud)
与池连接
return req.requestPooledConnection(to: . db1).flatMap { conn in
defer { try? req.releasePooledConnection(conn, to: . db1) }
return User.query(on: conn).all()
}
Run Code Online (Sandbox Code Playgroud)
和交易中
return req.transaction(on: .db1) { conn in
return User.query(on: conn).all()
}
Run Code Online (Sandbox Code Playgroud)
对不起,如果我没有回答您的问题。我了解如果Fluent可以支持为每个查询传递数据库名称,那就太好了,但是我没有在其中找到它。(或者不清楚如何在查询中传递数据库名称)
但是顺便说一句,从我的角度来看,为每个客户端使用单独的数据库可能会让您对迁移感到头疼……也许最好将它们全部存储在一个数据库中但要进行分区?例如对于PostgreSQL,如此处所述