Laravel:在另一个数据库上运行迁移

mbyulnm0  于 2023-06-24  发布在  其他
关注(0)|答案(8)|浏览(75)

在我的应用中,每个用户都有自己的数据库,该数据库是在用户注册时创建的。连接和数据库数据(数据库名称、用户名、密码)保存在默认数据库的表中。

try{
    DB::transaction(function() {

        $website = new Website();
        $website->user_id = Auth::get()->id;
        $website->save();

        $database_name = 'website_'.$website->id;

        DB::statement(DB::raw('CREATE DATABASE ' . $database_name));

        $websiteDatabase = new WebsiteDatabase();
        $websiteDatabase->website_id = $website->id;
        $websiteDatabase->database_name = $database_name;
        $websiteDatabase->save();

    });
} catch(\Exception $e) {
    echo $e->getMessage();
}

现在,我想在新用户的数据库创建后运行一些迁移。
这可能吗?

pftdvrlh

pftdvrlh1#

如果将数据库配置放在database.php文件中,这可以帮助您:

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

kulphzqa2#

在你的app/config/database.php中你必须:

<?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'    => '',
        ),
    ),
);

现在您已经在迁移中准备了两个数据库连接,您可以执行以下操作:

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

这个应该能用更多信息:http://fideloper.com/laravel-multiple-database-connections

tyg4sfes

tyg4sfes3#

如果你的意思是使用不同的数据库连接,它存在于文档中:

Schema::connection('foo')->create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
});
kkih6yb8

kkih6yb84#

我也有同样的问题,我的解决方案是先用Config::set修改数据库,然后运行Artisan::call("migrate")。基于你的代码:

DB::statement(DB::raw('CREATE DATABASE ' . $database_name));
Config::set('database.connections.mysql.database', $database_name);
Artisan::call("migrate --database=mysql");

配置只在你的会话上改变,然后稍后重置为你的当前设置。

wfveoks0

wfveoks05#

记住哪个迁移对应于哪个数据库是乏味的。
对于Laravel 5.5,我使用了这种方法:

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

所有迁移都可以自动运行,无需在运行时手动指定数据库。
请注意,迁移表存储在默认数据库中。

ckocjqey

ckocjqey6#

我实际上面临着同样的问题,乔的答案在我的情况下不起作用,因为我有不同的数据库连接(所以不同的主机,端口,用户和通行证)。
因此,迁移必须始终执行大量的重新连接:

  • 迁移从默认数据库开始(在我的例子中是 client_1
  • 从表migrationsclients中获取内容
  • 断开默认数据库
  • 连接到client_2的数据库,运行迁移部件,断开client_2
  • 再次连接到默认数据库,存储迁移“日志”

然后为每个客户端循环它。

/**
     * 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);
        }
    }

而魔术师们所扮演的角色,

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

使用这个解决方案,我可以在每个客户机上运行完全相同的迁移,而迁移只是存储在client_1中,我的主客户机。
但是,注意两个DB::disconnect();。如果没有这些,那么迁移日志将存储在另一个客户机的数据库中,这将使情况变得一团糟。
啊,顺便说一下,ClientController没有做什么特别的事情:

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

pgky5nke7#

我想我终于搞清楚了这一团糟...此解决方案不需要为每个租户的数据库进行配置,并且只需运行一次。

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

其中我在database.php上有一个名为“teners”的连接,它包含了我所有teners的数据库名称。我还设置了与租户数据库的默认连接。该数据库负责处理迁移表。
使用foreach语句,它遍历租户数据库并在每个数据库上运行迁移。
在默认连接上,您应该配置一个可以访问所有租户数据库的用户,以便它工作。

j91ykkif

j91ykkif8#

最好的解决方法是在**AppServiceProvide上调用此方法
这是解决这类问题的最佳方案。我在我的项目中使用它。在我的例子中,我有两个环境
开发和 * 生产。因此,当项目处于开发模式时,它将在本地服务器上查找其他Live服务器。所以你可以在这里设置dynamic-DB概念。
你必须创建一个函数,然后你必须在** Boot ()函数onApp\Providers\AppServiceProvide.php**中调用它

public function boot()
    {
       DBConnection();

    }

我为此创建了Helper文件。所以我在helper.php中的代码

function DBConnection()
 {
  if( env('APP_ENV') ==  'local' )
   {   $databse_name = "test_me";
       $host = '127.0.0.1';
       $user="root";
      $password="";
   }
    else
  {
    $databse_name = 'tic_tac';
    $host = 'localhost';
    $user="";
    $password="";
  }
    $state = true;
   try {
      Config::set('database.connections.myConnection', array(
        'driver'    => 'mysql',
        'host'      => $host,
        'database'  => $databse_name,
        'username'  => $user,
        'password'  => $password,
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict' => false,
     ));
    /* \DB::setDefaultConnection('myConnection');
      $state = \DB::connection()->getPdo();*/

     Config::set('database.connections.myConnection.database', $databse_name);
     \DB::setDefaultConnection('myConnection');
      \DB::reconnect('myConnection');

   } catch( \Exception $e) {
      $state = false;
   }
 return $state;
}

相关问题