我处在一个非常独特的问题,但我确信其他人必须在laravel中面对类似的事情。
所以我的应用程序现在正在生产中,真实数据在数据库中,因此我无法再编辑旧的迁移文件。我能做的就是创建新的迁移,这就是我正在做的事情。
我的数据库中的用户表将不再使用,将使用另一个数据库的用户表。所以我需要删除用户表,并删除我在其他表中设置的所有外键,所以我创建了一个类似的迁移:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class DropUserIdForeignKeyConstraintFromTables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
\DB::statement('ALTER TABLE accessible_by_role DROP FOREIGN KEY accessible_by_role_role_id_foreign');
\DB::statement('ALTER TABLE accessible_by_user DROP FOREIGN KEY accessible_by_user_user_id_foreign');
\DB::statement('ALTER TABLE document_term DROP FOREIGN KEY document_term_user_id_foreign');
\DB::statement('ALTER TABLE file DROP FOREIGN KEY file_user_id_foreign');
\DB::statement('ALTER TABLE mail DROP FOREIGN KEY mail_from_user_id_foreign');
\DB::statement('ALTER TABLE mail DROP FOREIGN KEY mail_to_user_id_foreign');
\DB::statement('ALTER TABLE `order` DROP FOREIGN KEY order_user_id_foreign');
\DB::statement('ALTER TABLE report DROP FOREIGN KEY report_user_id_foreign');
\DB::statement('ALTER TABLE role_user DROP FOREIGN KEY role_user_user_id_foreign');
\DB::statement('ALTER TABLE termable DROP FOREIGN KEY termable_user_id_foreign');
\DB::statement('ALTER TABLE document_term DROP KEY document_term_user_id_foreign');
\DB::statement('ALTER TABLE file DROP KEY file_user_id_foreign');
\DB::statement('ALTER TABLE mail DROP KEY mail_from_user_id_foreign');
\DB::statement('ALTER TABLE mail DROP KEY mail_to_user_id_foreign');
\DB::statement('ALTER TABLE `order` DROP KEY order_user_id_foreign');
\DB::statement('ALTER TABLE report DROP KEY report_user_id_foreign');
\DB::statement('ALTER TABLE role_user DROP KEY role_user_user_id_foreign');
\DB::statement('ALTER TABLE termable DROP KEY termable_user_id_foreign');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accessible_by_user', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('document_term', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('file', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('mail', function (Blueprint $table) {
$table->foreign('from_user_id')->references('id')->on('user')->onDelete('cascade');
$table->foreign('to_user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('order', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('report', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('role_user', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
Schema::table('termable', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('user')->onDelete('cascade');
});
}
}
现在还有另一个迁移,在此之后删除了用户表:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class DropUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::drop('user');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::create('user', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name')->comment('First name of user');
$table->string('last_name')->comment('Last name of user');
$table->string('email')->unique()->comment('Unique email address');
$table->string('password')->comment('Password used for authentication');
$table->string('reset_password')->comment('Token for resetting forgotten passwords');
$table->boolean('inactive')->comment('True if user is frozen for some reason');
$table->string('mobile_number')->comment('Mobile phone number');
$table->string('mobile_code')->comment('As an added security factor, the user need to add this code for authentication (sent by sms)');
$table->string('mobile_timer')->comment('');
$table->string('street');
$table->string('country', 2);
$table->string('city');
$table->string('postal_code');
$table->softDeletes();
$table->timestamps();
});
}
}
所以会发生的情况是,即使删除了外键约束,来自其他数据库的用户ID仍会出现在记录中,例如在用户填充数据时在文件表中。
当我尝试回滚时,会再次创建用户表,并且laravel也会尝试回放外键,但是文件表中的user_id
字段已经包含了值,但是不存在于刚刚在回滚上创建的用户表中,并且mysql无法将外键约束放在那里。我希望我有意义,因为这是一个棘手的问题需要解释。
我能想到的一个解决方案是不会在down方法中放回外键而不让它们再次返回以便它不会失败。还有其他人遇到过这样的情况吗?