我们正在使用Laravel Migration(v8.x
(来更改一个现有的表,我们想在其中将列重命名为现有列,但在此之前,我们删除了它。在up()
上,它运行得很好。但在down()
上,它不能先重命名列,然后再添加列。以下代码是我们所做工作的删节版本:
public function up()
{
Schema::table('extensions', function (Blueprint $table) {
$table->dropColumn('extended_amount'); // Runs 1st.
$table->renameColumn('extended_amount_final', 'extended_amount'); // Runs 2nd.
});
}
public function down()
{
Schema::table('extensions', function (Blueprint $table) {
$table->renameColumn('extended_amount', 'extended_amount_final'); // Not running 1st.
$table->decimal('extended_amount', 22, 2)->nullable(); // Error with 'duplicate column'.
});
}
不知怎的,down()
上的重命名命令在开始执行第二行时没有执行完毕。
但是,我们尝试了原始MySQL查询,如:
ALTER TABLE extensions
CHANGE extended_amount extended_amount_final DECIMAL(22,2),
ADD COLUMN extended_amount DECIMAL(22,2) NOT NULL;
它工作得很好。所以我们得出结论,这是Laravel迁移的一个bug。
但是,为什么我们使用Laravel迁移以所需的方式更改表,因为我们在表中有数据,而不想删除列?
正如您所怀疑的,问题可能在Laravel迁移中。但是您仍然可以使用Laravel迁移来更改表,只需分离执行,因为它们没有以您期望的方式运行。我们只修改了down()
方法,因为问题实际上在哪里
方法1
public function down()
{
Schema::table('extensions', function (Blueprint $table) {
$table->renameColumn('extended_amount', 'extended_amount_final');
});
Schema::table('extensions', function (Blueprint $table) {
$table->decimal('extended_amount', 22, 2)->nullable();
});
}
方法2
您可以使用DB
Facade在单独的查询中通过原始SQL来实现这一点。
use IlluminateSupportFacadesDB;
public function down()
{
Schema::table('extensions', function (Blueprint $table) {
$table->renameColumn('extended_amount', 'extended_amount_final');
// $table->decimal('extended_amount', 22, 2)->nullable();
});
DB::statement("ALTER TABLE project_extensions ADD COLUMN extended_amount DECIMAL(22,2) NOT NULL;
}
感谢我的同事:Mowshana Farhana女士和Nazmul Hasan先生协助调试该问题并找到解决方案。