Привет, %username%.
Иногда пользуюсь Docrine 2.1/Symfony 2.0. + doctrine migrations. В один прекрасный момент возникла проблема с кодировкой БД mysql при автоматическом создании таблиц. Покопавшить немного в Docrine DBAL выяснилось, что при создании схемы, параметры кодировки не учитываются.
Схема БД генерится в примерно так:
А нам нужно:
После этого можете запускать doctrine:migrations:diff и получать правильный SQL код.
Написал мини патч, чтобы при каждом обновлении не править, написал патч:
UPD:
Ура, мой баг закрыли. Просто обновите Doctrine2 и посмотрите настройки внимательно.
Иногда пользуюсь Docrine 2.1/Symfony 2.0. + doctrine migrations. В один прекрасный момент возникла проблема с кодировкой БД mysql при автоматическом создании таблиц. Покопавшить немного в Docrine DBAL выяснилось, что при создании схемы, параметры кодировки не учитываются.
Схема БД генерится в примерно так:
/* было */ CREATE TABLE TABLENAME ( /* ... */ ) ENGINE = InnoDB
А нам нужно:
/* нужно */ CREATE TABLE TABLENAME ( /* ... */ )DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDBПричем ни на какие настройки Docrine DBAL не реагировал.
Решение проблемы:
Открываем код. Находим файл doctrine-dbal/lib/Doctrine/DBAL/Schema/Schema.php ищем строку "new Table". Она там одна, код выглядит как-то так:<?php /** * Create a new table * * @param string $tableName * @return Table */ public function createTable($tableName) { $table = new Table($tableName); $this->_addTable($table); return $table; } ?>Добавляем в конструктор объекта Table параметры:
array(),array(),array(),0,array('charset'=>'utf8','collate'=>'utf8_general_ci')
Получится что-то типа такого:
<?php /** * Create a new table * * @param string $tableName * @return Table */ public function createTable($tableName) { $table = new Table($tableName,array(),array(),array(),0,array('charset'=>'utf8','collate'=>'utf8_general_ci')); $this->_addTable($table); return $table; } ?>
После этого можете запускать doctrine:migrations:diff и получать правильный SQL код.
Написал мини патч, чтобы при каждом обновлении не править, написал патч:
#!/usr/bin/php <?php /** * Doctrine DBAL Patch * fix table creation query encode * (c) _Nicolay */ system ('cp ./vendor/doctrine-dbal/lib/Doctrine/DBAL/Schema/Schema.php ./vendor/doctrine-dbal/lib/Doctrine/DBAL/Schema/Schema.php.Orig'); $data = file_get_contents('./vendor/doctrine-dbal/lib/Doctrine/DBAL/Schema/Schema.php'); $data = str_replace("new Table(\$tableName);", "new Table(\$tableName,array(),array(),array(),0,array('charset'=>'utf8','collate'=>'utf8_general_ci'));", $data); file_put_contents('./vendor/doctrine-dbal/lib/Doctrine/DBAL/Schema/Schema.php', $data);Про проблему создал задачу на баг фикс. На этом всё, надеюсь кому-нибудь помог.
UPD:
Ура, мой баг закрыли. Просто обновите Doctrine2 и посмотрите настройки внимательно.
Стоит упомянуть о более простом варианте - просто выставить сравнение по-умолчанию в utf_general_ci в настройках базы. Конечно, такой вариант не подойдет, если используются различные кодировки.
ОтветитьУдалитьСогласен, Такой вариант предлагается в официальной документации доктрины. Где-то они так и советуют делать.
ОтветитьУдалитьно:
1. не всегда есть возможность это сделать
2. настройки по умолчанию в БД я выставлял, но кодировка всё-равно оказывалась поломанной, т.к. есть ещё глобальные настройки сервера. Их я тоже менял, лучше не стало. Либо я что-то сделал не так, либо это баг mysql. Если не указывать явно кодировку, то по-умолчанию она всё-равно выставлялась latin1.
Убив на это порядочно времени я полез копаться в исходниках Doctrine, чтобы понять что же за SQL она генерит, так родилась эта статья.