簡體   English   中英

Laravel Migration重命名可空字段解決方法?

[英]Laravel Migration rename nullable field workaround?

如果您嘗試重命名字段可為空的日期時間列,那么mariadb 10.2.7中會出現重大更改,如果您運行遷移,則會出現錯誤:

[Illuminate\Database\QueryException]
  SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'due_date' (SQL: ALTER TABLE test
   CHANGE dueDate due_date DATETIME DEFAULT 'NULL')

創建遷移:

class CreateTestTable extends Migration
{
    public function up()
    {
        Schema::create('test', function (Blueprint $table) {
            $table->increments('id');
            $table->dateTime('dueDate')->nullable();
        });
    }
}

創建第二次遷移以重命名該列:

class RenameColumn extends Migration
{
    public function up()
    {
        Schema::table('test', function(Blueprint $table) {
            $table->renameColumn('dueDate', 'due_date');
        });
    }
}

是否有解決方法讓這個工作?

根據學說/ dbal 問題

為了允許表達式作為默認值並將它們與文字區分開來,Mariadb現在引用了information_schema.column表中的默認值。 這種變化帶來了(Oracle-)Mysql / MariaDB平台之間的許多不兼容性。

而不是為MariaDB創建特定的SchemaManager,在此P / R中采用的解決方案是映射當前MySQLSchemaManager中引入的更改(方法:getMariaDb1027ColumnDefault())。

從MariaDB 10.2.7開始,信息模式更改包括:

NULL現在被引用為'NULL'(當colum default不可為空且沒有提供默認值時出現異常:在information_schema中保存NULL),編輯:查看異常https://jira.mariadb.org/browse/MDEV-14053字符串默認值引用(要保存字符串'NULL',請將默認值設置為''NULL'')。 轉義:“'”在信息模式中默默地更改為“'”。 除非您在模型中使用“'”手動轉義默認值(架構差異),否則這不會產生影響。 另請參見第5點。必須引用默認文字值,以支持自動CURRENT_TIMESTAMP,CURRENT_DATE,CURRENT_TIME默認值默默地更改為“current_timestamp()”,“currdate()”,“currtime()”。 為了防止模式差異,它們被映射回原始值。

你可以嘗試這種方法:

創建新列並運行查詢以將舊列中的值復制到新列

class RenameColumn extends Migration
{
    public function up()
    {
        Schema::table('test', function(Blueprint $table){
            $table->dateTime('due_date')->nullable();
        });

        // copy values from column 'dueDate' to 'due_date'
        // DB::update returns number of affected rows
        DB::update('UPDATE `test` SET due_date = dueDate');

        Schema::table('test', function(Blueprint $table){
            $table->dropColumn('dueDate');
        });
    }

    public function down()
    {
        Schema::table('test', function(Blueprint $table){
            $table->dateTime('dueDate')->nullable();
        });

        DB::update('UPDATE `test` SET dueDate = due_date');

        Schema::table('test', function(Blueprint $table){
            $table->dropColumn('due_date');
        });
    }
}

雖然提供的解決方案有用,但我更喜歡更簡單的方法:

public function up()
{
    Schema::table('test', function (Blueprint $table) {
        DB::statement('ALTER TABLE `test` CHANGE `dueDate` `due_date` TIMESTAMP NULL DEFAULT NULL;');
    });
}

public function down()
{
    Schema::table('test', function (Blueprint $table) {
        DB::statement('ALTER TABLE `test` CHANGE `dueDate` `due_date` TIMESTAMP NULL DEFAULT NULL;');
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM