Laravel: Run migrations on another database

不羁岁月 提交于 2019-11-30 11:36:45
pietrovismara

In your app/config/database.php you have to:

<?php
return array(

    'default' => 'mysql',

    'connections' => array(

        # Our primary database connection
        'mysql' => array(
            'driver'    => 'mysql',
            'host'      => 'host1',
            'database'  => 'database1',
            'username'  => 'user1',
            'password'  => 'pass1'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),

        # Our secondary database connection
        'mysql2' => array(
            'driver'    => 'mysql',
            'host'      => 'host2',
            'database'  => 'database2',
            'username'  => 'user2',
            'password'  => 'pass2'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
    ),
);

Now that you prepared two database connections in your migration you can do:

Schema::connection('mysql2')->create('some_table', function($table)
{
    $table->increments('id');
});

This should work. More infos on: http://fideloper.com/laravel-multiple-database-connections

Fernando

If you place database config on the database.php file, this can help you:

php artisan migrate --database=**otherDatabase**

I actually faced the same problem and the answer of Joe did not work in my case, as I have different database connections (so different host, port, user and pass).

Therefore the migration must do a lot of reconnects all the time:

  • Migration starts with default database (in my case that is client_1)
  • Fetches stuff from table migrations and clients
  • Disconnect default database
  • Connect to database of client_2, run migration parts, disconnect client_2
  • Connect to default database again, store migration "log"

And then loop it for each client.

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $defaultConnection = BackendConfig::getDatabaseConfigArray();
        $clients = ClientController::returnDatabasesForArtisan();

        foreach ($clients as $client) {
            BackendConfig::setDatabaseFromClient($client);

            Schema::create('newtable', function (Blueprint $table) {
                $table->increments('id')->unsigned();
                $table->timestamps();
            });
            BackendConfig::setDatabaseFromArray($defaultConnection);
        }
    }

And the class where the magic is stored:

class BackendConfig
{
    public static function getDatabaseConfigArray($client_id = 1)
    {
        $connection = config('database.default');

        return [
            'id' => $client_id,
            'host' => config("database.connections.$connection.host"),
            'port' => config("database.connections.$connection.port"),
            'username' => config("database.connections.$connection.username"),
            'password' => config("database.connections.$connection.password"),
        ];
    }

    public static function setDatabaseFromArray($array)
    {
        self::setDatabase($array['id'], $array['host'], $array['port'], $array['username'], $array['password'], true);
        DB::disconnect();
    }

    public static function setDatabaseFromClient(Client $client)
    {
        DB::disconnect();
        self::setDatabase($client->id, $client->database->host, $client->database->port, $client->database->username, $client->database->password, true);
    }

    public static function setDatabase($client_id, $host, $port, $username, $password)
    {
        $connection = config('database.default');

        $database_name = $connection . '_' . $client_id;

        config([
            "database.connections.$connection.database" => $database_name,
            "database.connections.$connection.host" => $host,
            "database.connections.$connection.port" => $port,
            "database.connections.$connection.username" => $username,
            "database.connections.$connection.password" => $password,
        ]);
}

With this solution I can run the exact same migrations on every client, yet the migration is just stored in client_1, my sort of master client.

However, pay attention to the two DB::disconnect();. It will screw up the situation without those as then migrations logs are stored in another client's database or such.

Ah and by the way, ClientController does nothing special:

public static function returnDatabasesForArtisan()
{
    return Client::select('*')->with('database')->get();
}

I think I finally figured out this mess... This solution doesn't need a configuration for each tenant's database and has to be run only once.

class MigrationBlah extends Migration {
  public function up() {
    $dbs = DB::connection('tenants')->table('tenants')->get();
    foreach ($dbs as $db) {
      Schema::table($db->database . '.bodegausuarios', function($table){
        $table->foreign('usuario')->references('usuarioid')->on('authusuarios');
      });
    }
  }
}

Where I have a connection named "tenants" on my database.php, which contains the database name of all of my tenants. I have the default connection set to my tenants database as well. That database is the one responsible for taking care of the migrations table.

With the foreach statement, it goes through the tenant databases and runs the migration on each one.

On your default connection, you should configure a user that has access to all tenant's databases for it to work.

This is tedious to remember which migration corresponds to which database.

For Laravel 5.5 I used this approach:

public function up()
{

 // this line is important
  Illuminate\Support\Facades\DB::setDefaultConnection('anotherDatabaseConnection');


   Schema::table('product',
          function (Blueprint $table)
     {
        $table->string('public_id', 85)->nullable()->after('ProductID');
     });

  // this line is important, Probably you need to set this to 'mysql'
   Illuminate\Support\Facades\DB::setDefaultConnection('nameOfYourDefaultDatabaseConnection');
}

All migrations can be run automatically without taking care of specifying database manually when running them.

Please note that migrations table is stored inside your default database.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!