【问题标题】:Laravel change String Boolean value to Int Boolean in migrationLaravel 在迁移中将 String Boolean 值更改为 Int Boolean
【发布时间】:2021-10-08 01:24:33
【问题描述】:

我正在处理一个 Laravel 项目,该项目有两个现有的列,这些列设置为字符串,并拥有一个视觉上令人愉悦的布尔值 truefalse

我正在尝试在 Laravel 迁移中将这些列从 string 更改为 boolean,但需要转换列中的现有值,例如,如果记录的列值具有 @ 值987654326@,需要变成0

我当前修改这些列的迁移似乎无法自动实现,我该如何实现?

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddColumnsToNotificationContactsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('notification_contacts', function (Blueprint $table) {
            $table->boolean('canNotify')->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('notification_contacts', function (Blueprint $table) {
            //
        });
    }
}

我明白了:

SQLSTATE[HY000]:一般错误:1366 不正确的整数值:第 1 行的列“canNotify”为“false”(SQL:ALTER TABLE notification_contacts CHANGE canNotify canNotify TINYINT(1) NOT NULL)

【问题讨论】:

标签: php sql laravel


【解决方案1】:

分多个步骤执行,而不是在单个操作中运行。

步骤是:

  1. 添加一个新的临时列canNotifyTemp
  2. 使用来自列canNotify 的旧数据填充它
  3. 删除旧列
  4. 重命名临时列
class UpdateClientsTableAddRedesignColumns extends Migration
{
    public function up()
    {
        // step 1
        Schema::table('notification_contacts', function(Blueprint $table) {
            $table->boolean('canNotifyTemp')->default(0);
        });

        // step 2
        DB::table('notification_contacts')
            ->where('canNotify', 'true')
            ->update(["canNotifyTemp" => true]);

        DB::table('notification_contacts')
            ->where('canNotify', 'false')
            ->update(["canNotifyTemp" => false]);

        // step 3
        Schema::table('notification_contacts', function(Blueprint $table) {
            $table->dropColumn('canNotify');
        });

        // step 4
        Schema::table('notification_contacts', function(Blueprint $table) {
            $table->renameColumn('canNotifyTemp', 'canNotify');
        });
    }

    public function down()
    {
        // step 4 rollback
        Schema::table('notification_contacts', function (Blueprint $table) {
            $table->renameColumn('canNotify', 'canNotifyTemp');
        });

        // step 3 rollback
        Schema::table('notification_contacts', function (Blueprint $table) {
            $table->string('canNotify')->default('false');
        });

        // step 2 rollback
        DB::table('notification_contacts')
            ->where('canNotifyTemp', true)
            ->update(["canNotify" => 'true']);

        DB::table('notification_contacts')
            ->where('canNotifyTemp', false)
            ->update(["canNotify" => 'false']);

        // step 1 rollback
        Schema::table('notification_contacts', function (Blueprint $table) {
            $table->dropColumn('canNotifyTemp');
        });
    }
}

注意:我没有运行迁移,所以如果有任何问题,请告诉我。

【讨论】:

  • 这很棒,按预期工作,这里唯一的问题是索引,我最初在 canNotify 列上有一个索引,所以当我创建临时列时,我正在做: $table-&gt;boolean('can_notify_temp')-&gt;after('email')-&gt;index(); 但是当列重命名时,索引键名显示:notification_contacts_can_notify_temp_index。我尝试重命名索引,但没有成功:$table-&gt;renameIndex('can_notify_temp', 'can_notify');
  • @RyanH 你可以删除旧索引,在表的第 4 步之后添加新索引。
猜你喜欢
  • 1970-01-01
  • 2011-11-24
  • 2023-04-04
  • 1970-01-01
  • 2011-08-08
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多