【问题标题】:How do I insert into MySql database with select statement using Laravel 7 from two different connections?如何使用 Laravel 7 从两个不同的连接中插入带有 select 语句的 MySql 数据库?
【发布时间】:2022-01-13 23:21:33
【问题描述】:

我正在尝试将数据从一个数据库复制到另一台服务器上的另一个数据库。数据库在结构上是相同的。通过搜索,我尝试在 Laravel 中使用 insertUsing() 方法。

$new_connection = DB::connection('mysql2');
//Insert Using requires an array of columns
$column_list = Schema::getColumnListing('users');

//This is my select statement
$select = $new_connection->table('users')->select('*');

//This is my insert statement
DB::table('users')->insertUsing($column_list,$select);

这不会产生任何错误,但不会将数据插入表中。 如果我要复制到的数据库中有相同的数据,我会收到一条错误消息,指出主键已经存在,所以我知道它正在从其他服务器读取数据。

还有其他方法可以完成这项工作吗?

【问题讨论】:

  • 只使用insert() 有什么问题?我在the documentation 中没有看到任何提及insertUsing()。虽然实际上这可能在命令行上使用mysqldump | mysql 管道更好。
  • @miken32 来自源“使用子查询将新记录插入表中。”
  • 啊,我没有注意到您没有对旧数据库记录执行get()。我想您会发现问题在于子查询将无法使用单独的数据库连接。
  • @miken32 我可以进行插入,但不确定如果我要复制完整的数据库该怎么做。

标签: php mysql laravel


【解决方案1】:

insertUsing 使用的子查询将无法使用单独的数据库。没有潜在的限制,只是 Laravel 在构建查询时不使用数据库前缀。因此,如果您的数据库在同一台服务器上,您可以通过构建这样的原始查询来做到这一点:

DB::insert("INSERT INTO mysql1.users SELECT * FROM mysql2.users");

另一种选择是从一个数据库中提取数据并将其插入另一个数据库。假设您有一个相当大的表,您应该使用分块来确保不会将整个表加载到内存中。

如果您从“mysql2”连接移动到默认连接,它可能如下所示:

$users1 = DB::table('users');
$users2 = DB::connection('mysql2')->table('users');
$page = 0;
$size = 50;
while (true) {
    // get some records
    $users = $users2->skip($page * $size)->take($size)->get();
    // end the loop when there are no more results
    if ($users->count() === 0) {
        break;
    }
    // convert the results and each row to an array
    $user_array = $users->map(fn ($u) => (array)$u)->toArray();
    // save them into the new database
    $users1->insert($user_array);
    // increment the page for the next iteration
    $page++;
}

我建议使用适当的工具,例如 mysqldump 来执行此操作。

【讨论】:

  • 感谢您的回答。我不认为原始查询会起作用,因为这些前缀代表数据库名称,而不是连接。不过,另一个选项会起作用,如果我不能让另一个查询正常工作,我会尝试。
  • 在尝试第二个选项后我得到一个错误,参数 1 必须是数组类型,给定对象。
  • toArray() 在 Laravel 6+ 中不再存在
  • 是的,如果另一个连接完全在不同的服务器上,那么就没有办法做到这一点。 insert() 接受数组,因此您应该在集合结果及其子项上使用 toArray()。答案已更新。
  • 我向你保证,他们不会从 Laravel 中删除 toArray()。它会破坏一切。
猜你喜欢
  • 2014-06-05
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 2021-01-20
  • 2021-07-09
  • 2015-01-07
  • 1970-01-01
  • 2013-08-13
相关资源
最近更新 更多