我可以在不先选择数据库的情况下使用 Laravel 的 Schema::createDatabase() 吗?

Can I use Laravel's Schema::createDatabase() without first selecting a DB?

我在这里遇到了一些先有鸡还是先有蛋的问题。我正在 Laravel 中构建一个多租户应用程序,其中每个租户在 Postgrsql 服务器上都有自己的数据库。所以我有一份工作来创建一个新的租户,它调用:

Schema::connection($this->tenant->getDatabaseConnection())->createDatabase($this->tenant->getDatabaseName())

因此 $this->tenant->getDatabaseConnection() 选择要将租户添加到的租户数据库服务器,并且 return 是服务器连接名称。然后 $this->tenant->getDatabaseName() 将 return 该租户的数据库名称的字符串。

我遇到了一个小问题。这会引发异常:

SQLSTATE[08006] [7] FATAL: database "port=5432" does not exist (SQL: create database "local_tenant_(id)" encoding "utf8")

这是因为默认情况下连接的数据库名称为空。当用户登录他们的租户时,我们会动态地将租户模型中的 getDatabaseName() 注入其中。

但我不能在这里这样做,因为租户数据库还不存在。所以这是我看到的选项:

  1. 在创建新租户的数据库时,选择服务器上现有租户的随机数据库作为“充当”。我真的不喜欢像那样暂时劫持另一个租户的数据库,即使这对那个租户的影响应该是 0。如果它是在服务器上配置的第一个租户,则没有可用的数据库,这在我的书中是不可能的。

  2. 我可以只使用数据库提供程序 API 来创建租户数据库。这将是迄今为止最简单的,但会在本地和测试环境中中断,因此我想避免。

  3. 我可以绕过 Laravel 并为此建立到数据库的直接 PDO 连接,但如果我找不到更好的东西,我会说这是我最后的选择。

从技术上讲,您无需 select 数据库即可使用创建数据库命令。这是 Laravel 的 Schema Builder 的一个特性,它会在调用方法(在本例中为 CreatedDatabase)之前尝试 select 一个数据库。有没有办法解决这个问题,这样我就可以创建数据库而无需 Laravel 首先尝试 select 空数据库?

正确的解决方案是连接到postgres数据库以便运行CREATE DATABASEpostgres 数据库始终存在(除非有人丢弃它),这就是它的设计目的。