Laravel Migration重命名可以为空的字段解决方法?

时间:2017-10-21 21:21:38

标签: php laravel laravel-5 doctrine-orm laravel-5.4

如果您尝试重命名字段可为空的日期时间列,那么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 issue

  

为了允许表达式作为默认值并区分它们   从文字中,Mariadb现在引用默认值   information_schema.column表。这种变化带来了很多   (Oracle-)Mysql / MariaDB平台之间不兼容。

     

解决方案不是为MariaDB创建特定的SchemaManager   在此P / R中采用的是映射当前引入的变化   MySQLSchemaManager(方法:getMariaDb1027ColumnDefault())。

     

从MariaDB 10.2.7开始,信息架构更改包括:

     

NULL现在被引用为' NULL' (当colum default不是时,例外   可以为空且没有提供默认值:保存为NULL   information_schema),编辑:看一个例外   https://jira.mariadb.org/browse/MDEV-14053引用字符串默认值   (要保存字符串' NULL',请将默认值设置为'' NULL'')。转义:   "'"默默地改为"''"在信息模式中。这应该   除非您使用"'""""""""在   你的模型(模式差异)。另请参见第5点。默认文字值   必须引用,它支持自动CURRENT_TIMESTAMP,   CURRENT_DATE,CURRENT_TIME默认值以静默方式更改为   ' current_timestamp()',' currdate()',' currtime()'。防止架构   diff,它们被映射回原始值。

2 个答案:

答案 0 :(得分:1)

您可以尝试这种方法:

创建新列并运行查询以将旧列中的值复制到新列

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');
        });
    }
}

答案 1 :(得分:0)

虽然提供的解决方案有效但我更喜欢更简单的方法:

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;');
    });
}