在Laravel迁移中是否可以从MySQL数据库更改字符集编码?

4
我正在尝试在Laravel-5中更改mysql DB的编码,我已经尝试使用迁移,按照这个示例:https://slashdot.io/blog/adding-emoji-support-to-your-blog-948181198 - 然而,没有任何更新,字符集/编码仍然保持原样。
是否可能使用迁移来实现这一点?还是我需要编写一个单独的脚本?
迁移(为了完整起见)
/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    DB::raw('ALTER TABLE homestead.survey_responses CONVERT TO CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci');
    DB::raw('REPAIR TABLE homestead.survey_responses');
    DB::raw('OPTIMIZE TABLE homestead.survey_responses');
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    DB::raw('ALTER TABLE homestead.survey_responses CONVERT TO CHARACTER SET = utf8 COLLATE utf8_unicode_ci');
    DB::raw('REPAIR TABLE homestead.survey_responses');
    DB::raw('OPTIMIZE TABLE homestead.survey_responses');
}

上述迁移运行时没有出现错误,但不幸的是它什么也没做。

3个回答

11

通常在迁移类中使用的 Schema/Blueprint 类是不可能实现的。但你仍然可以使用 DB 门面运行任何需要的 SQL - 在你的情况下:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

class ChangeCharsetAndCollation Migration
{
    public function up()
    {
        DB::statement('ALTER DATABASE database CHARACTER SET new_charset COLLATE new_collation');
    }

    public function down()
    {
        DB::statement('ALTER DATABASE database CHARACTER SET old_charset COLLATE old_collation');
    }
}

只需将database, old_charset, old_collation, new_charset, new_collation替换为所需的值,并确保您的用户有权限运行此查询。


7
谢谢你的帮助 :) 看到这个信息是正常的吗:[Illuminate\Database\QueryException] SQLSTATE [HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement :: fetchAll(). 或者,如果您的代码仅会针对mysql运行,则可以通过设置PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY属性来启用查询缓冲。 (SQL:ALTER DATABASE homestead CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci)? - laminatefish
在执行该迁移时,是否有其他正在使用数据库的进程? - jedrzej.kurylo
那是我最初的想法,但经过检查,不是 :( - laminatefish
这可能与之前由PDO运行的查询有关。在运行DB :: statement()之前,请尝试执行DB :: reconnect()。 - jedrzej.kurylo
谢谢你的帮助。我决定为此编写一个bash脚本。像我这样运行,简直就是把所有东西都搞炸了。我可不喜欢那样 :D 不过还是要感谢你! - laminatefish
显示剩余2条评论

10

这里有一个重要的提示。

Laravel 7自带在表格上更改字符集和排序规则的功能。我需要这个功能来使用Cashier/stripe。

文档展示了如何在这里进行操作。

Schema::create('users', function (Blueprint $table) {
    ....
    $table->charset = 'utf8mb4';
    $table->collation = 'utf8mb4_bin';
});

编辑

或者,对我来说更好的解决方案是更改单个列上的排序规则。

$table->string('name')->collation('utf8mb4_bin');

哇!成功将这个老古董重启了! - laminatefish

1
如果你和我一样,尝试使用DB::statement('ALTER DATABASE database CHARACTER SET [...]')但被令人困惑的SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active错误困扰着...... 简单的解决方法是使用DB::unprepared():DB::unprepared('ALTER DATABASE database CHARACTER SET [...]')。感谢这个gist:https://gist.github.com/NBZ4live/04d5981eaf0244b57d0296b381e04195

让死代码复活的方法! :) - laminatefish
1
我遇到了同样的问题,最终来到这里,想分享一些经验! :) - Harry Lewis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接