Как создать базу данных с определенным набором и сопоставлением при использовании doctrine: database: create?

Сначала короткая версия:

Я хочу, чтобы команда doctrine:database:create создала базу данных с правильной / определенной кодировкой и сопоставлением. Как этого добиться? (В лучшем случае без изменения каких-либо глобальных настроек на сервере.)


Подробная версия:

Контекст - это приложение Symfony 4 и Doctrine 2. СУБД: MySQL, ОС: Ubuntu 14.04. Я хочу создать базу данных с помощью Doctrine:

$ bin/console doctrine:database:create

Оператор SQL, выполняемый Doctrine в фоновом режиме:

CREATE DATABASE `mydb`

Значит: он не использует настройки charset и collate из .../config/packages/doctrine.yaml, а также игнорируется DATABASE_URL в .../.env.

.../config/packages/doctrine.yaml

parameters:
    env(DATABASE_URL): ''

doctrine:
    dbal:
        # configure these for your database server
        driver: 'pdo_mysql'
        server_version: '5.7'
        charset: utf8mb4
        default_table_options:
            charset: utf8mb4
            collate: utf8mb4_unicode_ci

        # With Symfony 3.3, remove the `resolve:` prefix
        url: '%env(resolve:DATABASE_URL)%'
        mapping_types:
            enum: string
    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Base/Entity'
                prefix: 'App\Base\Entity'
                alias: App

.../.env

###> doctrine/doctrine-bundle ###
DATABASE_URL=mysql://root:[email protected]:3306/mydb?charset=utf8mb4
###< doctrine/doctrine-bundle ###

База данных DEFAULT_CHARACTER_SET_NAME - это latin1, а DEFAULT_COLLATION_NAME - это latin1_swedish_ci:

SELECT
    `DEFAULT_CHARACTER_SET_NAME`, `DEFAULT_COLLATION_NAME`
FROM
    information_schema.SCHEMATA 
WHERE
    schema_name = 'mydb'
;

+----------------------------+------------------------+
| DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+----------------------------+------------------------+
| latin1                     | latin1_swedish_ci      |
+----------------------------+------------------------+
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
1 326
2

Ответы 2

Вот еще несколько ответов: Doctrine2: как настроить сопоставление всех таблиц с UTF8

Они рекомендуют использовать сопоставление в самом объекте, но вам нужно указать все такие объекты, и если у вас их много, это проблема

@ORM\Table(options = {"collate" = "utf8mb4_unicode_ci"})

Второй подход - использовать опции в doctrine.yml.

 doctrine:
  dbal:
        options:
            1002: "SET NAMES 'utf8mb4_unicode_ci'" 

И третье решение - отредактировать файл конфигурации mysql и добавить туда кодировку по умолчанию.

my.cnf

 [mysqld]
    character-set-server=utf8mb4_unicode_ci
    collation-server=utf8mb4_unicode_ci

ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ MySQL (для текущего сеанса)

SET GLOBAL `character_set_server` = 'utf8mb4';
SET GLOBAL `collation_server` = 'utf8mb4_unicode_ci';

Спасибо за ваш ответ! К решениям: 1. Я бы хотел избежать явной установки кодировки для каждой отдельной таблицы. Я хочу иметь это на уровне базы данных. 2. Опция 1002 у меня не работает. 1002: "SET NAMES 'utf8mb4_unicode_ci'" вызывает ошибку БД (An exception occurred in driver: SQLSTATE[42000] [1115] Unknown character set: 'utf8mb4_unicode_ci'). Поэтому я поменял его на utf8mb4. Без ошибок, но и без эффекта - база данных создается с кодировкой latin1 и сопоставлением latin1_swedish_ci. 3. Кажется, что эти настройки в my.cnf игнорируются. Что работает, так это SET GLOBAL.

automatix 19.06.2018 16:28

@automatix как это? 1002: «УСТАНОВИТЬ ГЛОБАЛЬНЫЙ 'utf8mb4_unicode_ci'»? Отправьте наш ответ, как вы это сделали :)

nicandr 19.06.2018 18:23

Только что обновил свой ответ. Но на самом деле это то, чего я хотел избежать - изменений на сервере.

automatix 19.06.2018 19:17

Похоже, текущая версия доктрины (doctrine / dbal v2.10.0) не поддерживает создание баз данных mysql с кодировкой и сопоставлением, отличными от по умолчанию. Команда Symfony php bin/console doctrine:database:create вызывает Doctrine\DBAL\Platforms\MySqlPlatform::getCreateDatabaseSQL() в фоновом режиме.

    public function getCreateDatabaseSQL($name)
    {
        return 'CREATE DATABASE ' . $name;
    }

См. https://github.com/doctrine/dbal/blob/c950aab16457b1b4fd4b0f78b976fbdec373473a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php#L352

Из дерева конфигурации Symfony не добавляется кодировка или сопоставление :-( Почему бы и нет? ^^

doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        driver: 'mysql'
        server_version: '5.7'

        # Only needed for MySQL (ignored otherwise)
        charset: utf8mb4
        default_table_options:
            collate: utf8mb4_unicode_ci

Так что в настоящее время это не поддерживается.

Другие вопросы по теме