使用 Laravel,您可以在迁移过程中更改列名吗?

Posted

技术标签:

【中文标题】使用 Laravel,您可以在迁移过程中更改列名吗?【英文标题】:With Laravel, can you change a column name as part of a migration? 【发布时间】:2012-11-02 01:46:58 【问题描述】:

几乎就是标题所说的;作为迁移的一部分,我需要更改列名,可以这样做吗?如果可以,怎么做?

【问题讨论】:

Schema Builder docs 中没有关于重命名列的描述,并且语法文件中没有包含“更改”的代码。我认为 Laravel 3 是不可能的。 感谢收看。我觉得很奇怪,作为迁移的一部分,这似乎是一件显而易见的事情...... 【参考方案1】:

Laravel 3

是的,它可以完成,但只能使用原始查询。某些 DBMS 不支持更改列名,因此决定不实现此类功能,因为对于某些 DBMS,它会失败。

所以不要忘记,您可以在迁移中使用 DB::raw() 来利用原始查询。您可以通过这种方式更改列名。

Laravel 4

在 Laravel 4.1 中,您必须在 composer.json 中添加 doctrine/dbal 作为依赖项。

"doctrine/dbal": "2.4.*"

运行composer update 后,您现在可以使用renameColumn 方法。

Schema::table('users', function($table)

    $table->renameColumn('location', 'address');
);

这会将location 列重命名为address.

【讨论】:

请在 Laravel 5 的情况下解释 我很确定它在 Laravel 5 中仍然是一样的。【参考方案2】:

请注意,从 Laravel 4 开始,DB Schema确实允许通过 $table->renameColumn('from', 'to') 重命名列。

【讨论】:

【参考方案3】:

在 Laravel 4 的 renameColumn() 功能被修复之前(现在它失败并出现 There is no column with name 错误),你可以使用这样的东西:

Schema::table('table_name', function(Blueprint $table) 
    $table->string('new_name')->after('some_other_column_name');
);
DB::table('table_name')->update(array('new_name' => DB::raw('old_name')));
Schema::table('table_name', function(Blueprint $table) 
    $table->dropColumn('old_name');
);

【讨论】:

【参考方案4】:

在 Laravel 4.1 中默认不提供 renameColumn() 方法,请参阅发行说明:

如果您在迁移中使用 renameColumn 函数,您 将需要将教义/dbal 依赖项添加到您的 composer.json 文件。 Laravel 默认不再包含这个包。

http://laravel.com/docs/releases

【讨论】:

【参考方案5】:

我尝试使用 laravel 架构构建器中提到的 syntax,如下所示:

public function up()

    if (Schema::hasColumn('lesson_plans', '`desc`'))
    
        Schema::table('lesson_plans', function(Blueprint $table)
        
                $table->renameColumn('`desc`', 'comment');
        );
    

    ..

虽然这在我的 localhost 机器上运行良好。但是,它在 prod 上出现以下错误:

[PDO Exception]
SQLSTATE [HY000]: General error: 1366 incorrect string value: '\xD9\x8A\xD8\xB1\xD8\xAC\...' for column 'comment' at row 115

做一些研究.. 它turns out 这个错误与字符集和排序规则有关.. 我在网上找不到任何东西告诉我如何使用 laravel 的模式构建器指定这些人(示例坦率地说,非常稀缺).. 我只是像这样使用 DB::RAW:

public function up()

    if (Schema::hasColumn('lesson_plans', '`desc`'))
    
        DB::select(DB::raw('alter table lesson_plans change `desc` `comment` longtext character set utf8 collate utf8_general_ci default null'));
    

在本地和产品上都像魅力一样工作!

关键是 DB::Raw 可以做任何你想做的迁移,而不会遇到 Laravel 的限制..

【讨论】:

【参考方案6】:

根据https://github.com/laravel/laravel/issues/2146 ,renameColumn 已被删除并且没有可用的修复:

public function renameColumn($oldColumnName, $newColumnName) 
    throw new DBALException("Table#**renameColumn() was removed**, because it drops and recreates the column instead. **There is no fix available**, because a schema diff cannot reliably detect if a column was renamed or one column was created and another one dropped.");

对于 Laravel 4.1 和学说/dbal 2.2,这可以在 vendor/doctrine/dbal/UPGRADE 中找到

【讨论】:

以上是关于使用 Laravel,您可以在迁移过程中更改列名吗?的主要内容,如果未能解决你的问题,请参考以下文章

迁移后的 Laravel 种子

PHPMYADMIN中的laravel更改表而无需迁移

Laravel 迁移更改表名

如何使用 laravel 迁移和种子正确处理数据库数据更改

Laravel 从数据库生成迁移

我可以更改在 laravel 的身份验证系统中使用的模型用户吗?