gpt4 book ai didi

php - Laravel - 迁移,表结构修改 - 正确方法

转载 作者:行者123 更新时间:2023-11-29 07:17:52 25 4
gpt4 key购买 nike

我现在的 table 是

Schema::create('students', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name', 255);
$table->string('last_name', 255);
$table->enum('gender', ['m', 'f']);
$table->date('date_of_birth');
$table->integer('roll_number');
$table->char('section', 1);
$table->integer('class');
$table->unsignedBigInteger('school_id');
$table->string('photo')->nullable;
$table->timestamps();

$table->foreign('school_id')
->references('id')->on('schools')
->onUpdate('cascade')->onDelete('cascade');

$table->unique(['roll_number', 'section', 'class', 'school_id']);
});

标准

Schema::create('standards', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->unsignedBigInteger('school_id');
$table->timestamps();

$table->foreign('school_id')
->references('id')->on('schools')
->onUpdate('cascade')->onDelete('cascade');
});

章节

Schema::create('sections', function (Blueprint $table) {
$table->bigIncrements('id');
$table->char('name', 1);
$table->unsignedBigInteger('standard_id');
$table->timestamps();

$table->foreign('standard_id')
->references('id')->on('standards')
->onUpdate('cascade')->onDelete('cascade');
});

现在我有了标准和部分表,这些表中的外键将替换现有结构中的类和部分列,并保持 roll_numbersection_idstandard_idschool_id 是唯一的。

我试过了

 public function up()
{
Schema::table('students', function (Blueprint $table) {
$table->dropUnique(['roll_number', 'section', 'class', 'school_id']);

$table->dropColumn('section');
$table->dropColumn('class');
$table->unsignedBigInteger('standard_id')->after('roll_number');
$table->unsignedBigInteger('section_id')->after('standard_id');

$table->foreign('standard_id')->references('id')->on('standards')
->onUpdate('cascade')->onDelete('cascade');
$table->foreign('section_id')->references('id')->on('sections')
->onUpdate('cascade')->onDelete('cascade');

$table->unique(['roll_number', 'standard_id', 'section_id', 'school_id']); // unique combination
});
}

但是好像不行。

错误

Illuminate\Database\QueryException : SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (myapp_extra.#sql-2f78_29d, CONSTRAINT students_standard_id_foreign FOREIGN KEY (standard_id) REFERE NCES standards (id) ON DELETE CASCADE ON UPDATE CASCADE) (SQL: alter table students add constraint students_standard_id_foreign foreign key (standard_id) references standards (id) on delete cascade on update cascade)

  at \myapp\vendor\laravel\framework\src\Illuminate\Database\Connection.php:664

注意:标准和部分表是在进行此迁移之前创建的,因此两列均可用。

最佳答案

为什么会这样?

发生此错误是因为您要插入一个没有默认值且没有 NULLABLE 的新列到您已经有行的表。

当你这样做时,MySQL 会将它的值设置为 0 , 所以你所有的表都会有 standard_idsection_id设置为 0 ,因此当您尝试添加外部索引时,它会失败,因为 0不是您的 standards 上的有效 ID/sections表。

那么如何解决呢?

你有一些方法可以解决这个问题:

第一步:设置默认值

如果对您的应用程序有意义,您可以为您的列设置一个默认(有效)值,这样外键就不会失败:

        $table->unsignedBigInteger('standard_id')->default(1)->after('roll_number');
$table->unsignedBigInteger('section_id')->default(1)->after('standard_id');

大多数时候不是那么简单,所以你需要动态定义值

第二:动态设置值

如果您有一些逻辑来为这个新列设置默认值,您可以将迁移分为两个步骤:

// Add the fields first
Schema::table('students', function (Blueprint $table) {
$table->dropUnique(['roll_number', 'section', 'class', 'school_id']);

$table->dropColumn('section');
$table->dropColumn('class');
$table->unsignedBigInteger('standard_id')->after('roll_number');
$table->unsignedBigInteger('section_id')->after('standard_id');
}

App\Students::get()->each(function($student) {
// Apply your logic here
$student->standard_id = 3;
$student->section_id = 3;
$student->save();
});

// Now you can add your foreign keys.
Schema::table('students', function (Blueprint $table) {
$table->foreign('standard_id')->references('id')->on('standards')
->onUpdate('cascade')->onDelete('cascade');
$table->foreign('section_id')->references('id')->on('sections')
->onUpdate('cascade')->onDelete('cascade');

$table->unique(['roll_number', 'standard_id', 'section_id', 'school_id']); // unique combination
});

第三:使字段可为空

如果您只是不知道或没有此字段的默认值,那么您的字段应该可以为空:

    $table->unsignedBigInteger('standard_id')->nullable()->after('roll_number');
$table->unsignedBigInteger('section_id')->nullable()->after('standard_id');

关于php - Laravel - 迁移,表结构修改 - 正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58234552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com