是否可以使用 Laravel 5 对动态数据库连接进行迁移?

Posted

技术标签:

【中文标题】是否可以使用 Laravel 5 对动态数据库连接进行迁移?【英文标题】:Is it possible to do migration on dynamic database connection with Laravel 5? 【发布时间】:2017-02-23 09:09:40 【问题描述】:

我正在尝试为不同的用户动态创建数据库。 (每个用户都有自己的数据库服务器,所以不要问我为什么不为所有用户使用单个数据库)为此,我有一个默认数据库来存储所有连接信息。我需要:

    创建一个新数据库并在新用户注册时运行所有迁移文件。 当架构中有更新时,在此默认数据库中记录的所有数据库上运行新的迁移文件。

有没有办法可以根据我对默认数据库的信息动态设置迁移文件的数据库连接?


附:对于“动态设置数据库连接”,我并不是指您在控制器或类中所做的正常设置。我希望至少可以在目标数据库中创建迁移表并能够自行检测要运行的迁移文件。

【问题讨论】:

【参考方案1】:

是的,有。首先,您需要将连接详细信息添加到配置中。配置命名连接后,只需在 Artisan 外观上调用 migrate 命令,选择连接的名称(在本例中为“新”)作为选项:

use Illuminate\Support\Facades\Artisan;
//...

$new_connection = 'new';

config(["database.connections.$new_connection" => [
    // fill with dynamic data:
        "driver" => "mysql",
        "host" => "",
        "port" => "",
        "database" => "",
        "username" => "",
        "password" => "",
        "charset" => "utf8",
        "collation" => "utf8_unicode_ci",
        "prefix" => "",
        "strict" => true,
        "engine" => null
    ]]);

Artisan::call('migrate', ['--database' => $new_connection]);

【讨论】:

还没有时间测试,但这个答案似乎最可靠。我会先奖励赏金,测试后将答案标记为正确。 非常有趣的方法。我喜欢 +1【参考方案2】:

首先你需要创建数据库

 DB::getConnection()->statement('CREATE DATABASE :schema', array('schema' => $schemaName)); 

然后像这样动态更改数据库的名称

$config = app(\Illuminate\Config\Repository::class);
$config->set('database.connections.mysql.database', UserRepotory::getCurrentDatabase());

您可以像这样包含Config 或通过 laravel 的服务容器。

最后你打电话给Artisan::call('migrate')

【讨论】:

【参考方案3】:

您好,对您有帮助,

首先在 database.php 文件中添加 '%new_connection%' 以处理新连接以供将来使用。

要动态创建连接,假设您有一个带有变量 $name 作为数据库名称的路由。

第 1 步: 在 routes.file 我创建并在 routes.php 中您想要的路由 url 上调用它

function appendNewConnection($name)
$path = base_path('config' . DIRECTORY_SEPARATOR . 'database.php');
            $contents = file_get_contents($path);
            $updatedContents = str_replace('%new_connection%', $name . '\' => [
            \'driver\' => \'mysql\',
            \'host\' => \'127.0.0.1\',
            \'database\' => \'' . $name . '\',
            \'username\' => \'root\',
            \'password\' => \'\',
            \'charset\' => \'utf8\',
            \'collation\' => \'utf8_unicode_ci\',
            \'prefix\' => \'\',
            \'strict\' => false,
        ],
        \'%new_connection%', $contents);
            file_put_contents($path, $updatedContents);


第 2 步:

//to generate migration add below line in top of routes.php

use Illuminate\Support\Facades\Artisan;

add this line in function created above 
Artisan::call('migrate', ['--database' => $name]);

【讨论】:

这在纸上听起来不错,我以前见过这种类型的实现,但这是不好的做法。 Laravel 认为配置文件中的闭包是不好的做法。当您尝试运行config:clearconfig:cache 时,它会产生应用程序停止错误,修复它们的唯一方法是删除配置缓存并且不再运行它github.com/laravel/framework/issues/9625 如果您有一个小应用程序,它可能不会缓存配置对你来说是值得的。请注意,如果您使用此解决方案,您将在缓存配置时遇到应用停止错误。【参考方案4】:

这里我有一些关于如何做到这一点的线索:

1。将有一个全局数据库,您可以在其中维护所有用户 登录详细信息,对吗?

2。为数据库名称添加一个额外的字段。

3。当用户完全成功登录时,将他们的数据库详细信息存储在会话中 变量。

现在,

4。创建一个动态的数据库文件,并从该会话变量中给出数据库名称:

config(["database.connections.$new_connection" => [
    // fill with dynamic data:
        "driver" => "mysql",
        "host" => "",
        "port" => "",
        "database" => "",//Here you need to set value of session variable
        "username" => "",// credential will be the same for all
        "password" => "",// credential will be the same for all
        "charset" => "utf8",
        "collation" => "utf8_unicode_ci",
        "prefix" => "",
        "strict" => true,
        "engine" => null
    ]]);

Bingo 你现在准备好了:D

【讨论】:

以上是关于是否可以使用 Laravel 5 对动态数据库连接进行迁移?的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 5 中将多行从动态表单保存到数据库

在 Laravel 5.1 和 Vue JS 中保存多个数据动态表单

在 Laravel 5.1 中关闭数据库连接

laravel 5 的动态中间件

Laravel 5.2 基于用户的动态环境变量

vue.js 2.0 在 laravel 5.3 中动态加载组件