如何使用 Doctrine 更改列字符集和排序规则?

How to change column charset and collation with Doctrine?

我正在开发一个 Symfony 3.4 项目,我希望 table 的某些列使用字符集 utf8mb4。这背后的目的是允许表情符号。

这是我的 Doctrine 实体的摘要:

/**
 * @ORM\Table(name="categories")
 */
class Category {
    // ...

    /**
     * @var string
     * @ORM\Column(name="description", type="string", length=255)
     */
    private $description;
}

我先更新了学说配置:

doctrine:
  charset: utf8mb4

然后,我更新了字段的Doctrine配置category.description:

-    * @ORM\Column(name="description", type="string", length=255)
+    * @ORM\Column(name="description", type="string", length=191, options={"charset"="utf8mb4"})

请注意,我将长度从 255 更改为 191,因为 utf8mb4 使用 4 个字节而不是 utf8 的 3 个字节。

最后,我运行更新命令:

bin/console doctrine:schema:update --dump-sql

返回的内容:

ALTER TABLE categories CHANGE description description VARCHAR(191)  NOT NULL;

如您所见,没有关于字符集的更新。此外,我们可以看到关键字 VARCHAR(191)NOT 之间有一个双空格,让我们假设这里应该有一些东西。 我期望的查询是这样的:

ALTER TABLE categories MODIFY `description` VARCHAR(191) COLLATE utf8mb4_unicode_ci NOT NULL;

然后我运行更新命令:

bin/console doctrine:schema:update --force

但是当我重新运行 --dump-sql 命令时,returns 一遍又一遍地执行相同的查询(带有双空格)。

即使我手动将列的字符集设置为 utf8mb4,查询仍然相同。

我使用 doctrine/orm 的 v2.6.3。

我是否遗漏了配置中的某些内容? Doctrine 是否处理列字符集?

This 没有回答我的问题,因为它是关于更改 all tables 的排序规则。就我而言,我想更改特定 table.

的单个列的排序规则

简答

Doctrine won't do this for you.

备选方案

使用 DoctrineMigrationBundle 允许在 SQL 中创建迁移。因此,您可以编辑自动生成的迁移以在所需列上添加 charset/collation。

生成新的空白迁移:

bin/console doctrine:migrations:generate

然后,添加ALTER语句:

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20200113131732 extends AbstractMigration {
    public function up(Schema $schema) : void {
        $this->addSql('ALTER TABLE categories MODIFY `description` VARCHAR(191) COLLATE utf8mb4_unicode_ci NOT NULL;');
    }

    public function down(Schema $schema) : void {
        $this->addSql('ALTER TABLE categories MODIFY `description` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL;');        
    }
}

最后,只是 运行 迁移:

bin/console doctrine:migrations:migrate

看起来 doctrine 部分支持更改列排序规则(仅 Drizzle、Mysql、PostgreSQL>=9.1、Sqlite 和 SQL Server 支持)。

doctrine annotations reference

    /**
     * @ORM\Table(name="categories")
     */
    class Category {
        // ...
    
        /**
         * @var string
         * @ORM\Column(name="description", type="string", length=255, options={"collation"="ascii_general_ci"})
         */
        private $description;
    }