蒸气3:使用多个数据库

时间:2019-03-03 12:53:42

标签: database vapor

使用Vapor 3,在服务器运行时是否有一种简单的方法来切换数据库?

例如,用户使用“登录”数据库登录。然后我设置 该用户在其Cookie中的数据库。然后,该用户的任何后续请求都将使用cookie中标识的数据库(在这种情况下,“用户”实际上是一家公司)。

所有数据库都来自相同的数据库家族(例如MySQL)。 这样会将每个公司的数据保留在自己的数据库中,并限制 每个数据库的大小(希望总体上,数据库操作会更快)。 另外,还原数据库的任何需求只会影响一家公司,并且备份会更简单。

  1. 如何实现这一目标?
  2. 这会很低效吗?

还有其他更好的方法可以实现这一目标吗?

1 个答案:

答案 0 :(得分:5)

据我了解,您可以创建一些不同的数据库标识符,例如:

extension DatabaseIdentifier {
    static var db1: DatabaseIdentifier<MySQLDatabase> {
        return .init("db1")
    }
    static var db2: DatabaseIdentifier< MySQLDatabase > {
        return .init("db2")
    }
}

然后像这样在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)

之后,别忘了在各处使用.db1.db2标识符,而不是默认的.mysql(对于MySQL),例如在迁移中

migrations.add(model: User.self, database: .db1)

具有连接池

return req.requestPooledConnection(to: . db1).flatMap { conn in
    defer { try? req.releasePooledConnection(conn, to: . db1) }
    return User.query(on: conn).all()
}

和交易中

return req.transaction(on: .db1) { conn in
    return User.query(on: conn).all()
}

对不起,如果我没有回答您的问题。我知道,Fluent可以支持为每个查询传递数据库名称会很好,但是我没有在其中找到它。 (或者不清楚如何在查询中传递数据库名称)

但是从我的角度来看,每个客户端都有单独的数据库可能使您对迁移感到头疼……也许最好将它们全部存储在一个数据库中但要进行分区?例如适用于PostgreSQL,例如described here