mysql - 如何在 Laravel 迁移中使用多个数据库设置外键约束
问题描述
我目前正在做一个需要使用多个数据库的项目。在我的 .env 文件中,我有以下数据库变量:
DB_CONNECTION=mysql
DB_ONE_NAME=db1
DB_CONNECTION_TWO=mysql2
DB_TWO_NAME=db2
在我的 config/database.php 文件中,我有以下参考:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_ONE_NAME', 'db1'),
'username' => env('DB_USERNAME', 'user'),
'password' => env('DB_PASSWORD', 'root'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mysql2' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_TWO_NAME', 'db2'),
'username' => env('DB_USERNAME', 'user'),
'password' => env('DB_PASSWORD', 'root'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
在我的第一个迁移文件中,我有这个:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
public function up()
{
Schema::connection('mysql')->create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('username')->unique();
$table->timestamps();
$table->index('id');
});
}
public function down()
{
Schema::connection('mysql')->dropIfExists('users');
}
}
在第二个迁移表中,我有这个:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProjectsTable extends Migration
{
public function up()
{
Schema::connection('mysql2')->create('projects', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained('mysql.users')->onDelete('set null');
$table->string('name')->unique();
$table->timestamps();
$table->index(['id', 'user_id']);
});
}
public function down()
{
Schema::connection('mysql2')->dropIfExists('projects');
}
}
我可能做错了什么?我检查了任何重复的文件,但找不到任何错误。
同样,我最近在我的机器上将 PHP 和 MYSQL 都升级到了它们的最新版本。在 Laravel 项目上工作所需的所有扩展都已正确安装。
但是,我仍然收到此错误:
SQLSTATE[HY000]: General error: 1005 Can't create table `db2`.`projects` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `projects` add constraint `projects_user_id_foreign` foreign key (`user_id`) references `mysql`.`users` (`id`) on delete set null)
另外,当我运行这个命令时,
php artisan migrate --pretend
或者
php artisan migrate
我仍然得到同样的错误。
我也试过用这个:
$table->unsignedBigInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('mysql.users')->onDelete('set null');
但没有任何工作。还有其他方法可以解决这个问题吗?如果有,请给我建议。谢谢你的时间。
解决方案
因此,在使用不同类型的方法进行了 14 小时的测试之后,我最终得到了我所说的“你应该知道 hack”哈哈
我在迁移表中使用第二个数据库连接名称,而不是使用数据库名称。
我在外键上使用连接名称的初始代码:
Schema::connection('mysql2')->create('projects', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained('mysql.users')->onDelete('set null');
$table->string('name')->unique();
$table->timestamps();
$table->index(['id', 'user_id']);
});
现在什么有效!使用数据库名称而不是外键上的连接名称:
Schema::connection('mysql2')->create('projects', function (Blueprint $table) {
$table->id();
**$table->foreignId('user_id')->nullable()->constrained('db1.users')->onDelete('set null');**
$table->string('name')->unique();
$table->timestamps();
$table->index(['id', 'user_id']);
});
因此,第二个选项工作正常。我希望这对某人也有帮助!!!
推荐阅读
- ios - wkwebview 无法加载 http 图像
- r - 聚合,但函数使用两列
- go - 如何在一个文件中运行多个匿名结构?
- c# - Amazon.Util.EC2InstanceMetadata 返回 null
- json - 在 Spring Boot 的 logback json 日志中的消息下将 MAP 显示为 JSON 对象
- excel - IFS 在一个单元格中具有“大于”“小于”条件的多个单元格
- node.js - osascript:无法打开默认脚本组件
- python - 用于优化的 Deep Galerkin 方法
- vue.js - 通过调用创建模态的函数,将道具即时传递给 vue 3 中的子组件
- amazon-web-services - 认知应用程序域不适用于联合登录