Можно ли выполнить миграцию при динамическом подключении к базе данных с Laravel 5?

Я пытаюсь динамически создавать базу данных для разных пользователей. (у каждого пользователя будет свой собственный сервер базы данных, поэтому не спрашивайте, почему я не использую единую базу данных для всех пользователей) Для этого у меня есть база данных по умолчанию, в которой хранится вся информация о подключении. Мне нужно будет:

  1. Создайте новую базу данных и запустите все файлы миграции при регистрации нового пользователя.
  2. Запустите новые файлы миграции для всей базы данных, записанной в этой базе данных по умолчанию, когда в схеме есть обновления.

Есть ли способ динамически установить соединение с базой данных файла миграции на основе информации, которая у меня есть в базе данных по умолчанию?


P.S. Под «динамической установкой соединения с базой данных» я НЕ имею в виду обычную настройку, как в контроллере или классе. Я ожидаю что-то, что хотя бы создаст таблицу миграции в целевой базе данных и сможет самостоятельно определять, какой файл миграции запускать.


person cytsunny    schedule 14.10.2016    source источник


Ответы (4)


Да, есть. Сначала вам нужно добавить в конфигурацию детали подключения. После того, как вы настроили именованное соединение, просто вызовите команду migrate на фасаде Artisan, выбрав имя соединения (в данном примере «новое») в качестве опции:

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]);
person alepeino    schedule 18.10.2016
comment
Пока нет времени на тестирование, но этот ответ кажется наиболее надежным. Сначала я назначу награду и отмечу ответ как правильный после тестирования. - person cytsunny; 25.10.2016
comment
Очень интересный подход. Мне это нравится +1 - person Andre F.; 05.11.2016

Для начала нужно создать базу данных

 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')

person Kliment    schedule 18.10.2016

Привет, небольшая помощь для тебя,

прежде всего добавьте "% new_connection%" в файл database.php, чтобы обрабатывать новое соединение и для будущего использования.

Чтобы динамически создать соединение, допустим, у вас есть маршрут с переменной $ name для имени базы данных.

шаг 1: в файле routes.file, который я создал, и вызываю его по желаемому URL-адресу маршрута в routes.php

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]);
person codebob    schedule 19.10.2016
comment
На бумаге это звучит хорошо, я видел, как этот тип реализации использовался раньше, но это плохая практика. Laravel считает закрытие файлов конфигурации плохой практикой. При попытке запустить config:clear или config:cache будут возникать ошибки остановки приложения, и единственный способ исправить их - удалить кеш конфигурации и никогда не запускать его снова github.com/laravel/framework/issues/9625 Если у вас небольшое приложение, возможно, вам не стоит кэшировать конфигурацию. Однако имейте в виду, что если вы воспользуетесь этим решением, вы столкнетесь с ошибками остановки приложения при кешировании config. - person WhyAyala; 20.11.2017

Вот у меня есть подсказка, как это сделать:

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
    ]]);

Бинго, теперь вы готовы к игре: D

person Akshay    schedule 24.10.2016