Создание Doctrine YAML через MySQL Workbench

Недавно стал пользоваться программой MySQL Workbench. Приложение меня очень порадовало, в нем очень удобно проектировать структуру базы данных, которую затем можно легко экспортировать на сервер Баз Данных (Forward Engineering). Так же можно использовать обратную разработку (Reverse Engineering): создание ER диаграммы по существующей структуре Базы Данных. Кроме того, в приложении есть синхронизация модели и существующей БД, что тоже очень удобно при разработке.

Но так как мы разрабатываем наши продукты с использованием ORM Doctrine, то кроме структуры БД необходимо было создать модели для доступа к данным. И тут я вспомнил, что один хороший человек, как-то говорил, что для Workbench есть дополнение, которое создает Doctrine YAML сразу из приложения. Немного поискав в инете, плагин был успешно найден. Страница разработчика находится вот здесь.

Используя данный плагин очень удобно и быстро можно создавать схемы для будущих моделей.

Доступные стабильные версии можно найти на этой странице. На момент написания статьи актуальная версия была 0.4.1 от 03 Января 2010 года. Последняя девелоперская версия — 0.4.2. Советую использовать ее. Доступна по адресу http://mysql-workbench-doctrine-plugin.googlecode.com/svn/trunk/DoctrineExport.grt.lua

После распаковки архива Вы найдете файл «DoctrineExport.grt.lua» — это и есть необходимый плагин. Теперь его надо установить в MySQL Workbench. Для этого запускаем приложение и идем в меню «Scripting» – «Install Plugin/Module», указываем файл с плагином. Не забудьте указать тип добавляемого плагина «lua files (*.lua)». После этого плагин будет успешно добавлен.

Перезапускаем приложение Workbench, чтобы плагин активировался.

На следующем шаге создадим несложную ER диаграмму (если у вас ещё нет существующего подключения к серверу Баз Данных – создайте его в разделе «SQL Development» — «New Connection») Для этого, после запуска приложения, в разделе «Data modeling» нажмите «Create New EER Model».

После открытия нового окна, вы можете либо сначала создать необходимые таблицы, а потом перейти к созданию ER диаграммы, либо сразу перейти к моделированию и параллельно создать таблицы. Воспользуемся сразу вторым способом. Для этого в самом верху жмем на иконку «Add diagram».
Открывается рабочая область для проектирования.

Создадим таблицы и раставим связи между ними. Существует таблица пользователей, групп и комментариев. Каждый пользователь входит в какую-либо группу (связь одна ко многим). Пользователи могут оставлять коментарии(связь одна ко многим). Не забывайте, что внешние ключи невозможны при работе с MyISAM. По умолчанию MySQL Workbench работает с InnoDB.

После проектирования Вы можете экспортировать созданую стуктуру на сервер Баз Данных с помощью меню «Database» — «Forward Engineer».

Для создания Doctrine YAML в верхнем меню откроем раздел «Plugins» — «Catalog» — «Doctrine Export: Copy Generated Schema to Clipboard». И схема моделей попадет в буфер обмена. Так же, в данном разделе меню, вы можете указать в какой файл выгрузить данные.

В итоге у нас получилась вот такая схема данных (представлена ниже). Плагин правильно обработал таблицы и создал модели без множественного окончания. Так если таблица называется «users», то будущая модель будет именоваться «user» — это очень приятно. Кроме того, когда я создавал нужную мне модель, плагин также правильно обработал название «categories» и создал схему с названием «category». И, как видно, все связи раставлены правильно. В необходимых классах сразу прописан «foreignAlias», сама Doctrine так не прописывает. Она пишет связи в каждой схеме отдельно.

Единственное, что меня не устроило – это то, что первая буква у моделей идет в нижнем регистре, а мы работаем по нотации Zend, где название класса должно начинаться с заглавной буквы. Но данная проблема была решена в версии 0.4.2, которая позволяет использовать различные конфигурационные переменные. Теперь по умолчанию первая буква идет заглавная.

Чтобы подключить свой файл конфигурационных настроек необходимо создать файл «doctrinePluginConfig.lua», который должен быть размещен в директории «%PROGRAMFILES%/MySQL/Workbench/modules». Содержимое файла может быть вот таким

local _G = _G

-- do not touch the three points, they are intended
module(...);

-- declare config and add it
-- to the global namespace
_G.extConfig = {
 enableRecapitalizeTableNames="none" –-Отключение первой заглавной буквы
}

Подробнее о параметрах конфигурации можно найти вот на этой странице HowToUseConfigOptions

На официальном сайте в Wiki описаны некоторые дополнительные возможности плагина при работе с Doctrine. Например, что бы добавить Email валидатор Doctrine необходимо в комментарий к названию колонки добавить

{doctrine:validators}
email: true
{/doctrine:validators}

Используемые ресурсы

UPD: У кого возникает ошибка с функцией getInfoFromTableComment, то замените ее на
getCommentToken в файле «%APPDATA%\MySQL\Workbench\modules\DoctrineExport.grt.lua».

Пример созданного YAML .

---
detect_relations: true
options:
  collate: utf8_bin
  charset: utf8
  type: InnoDB

User:
  tableName: users
  columns:
    id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
      autoincrement: true
    name:
      type: string(45)
    login:
      type: string(45)
      email: true
    password:
      type: string(45)
    group_id:
      type: integer(4)
      unsigned: true
  relations:
    group:
      class: Group
      local: group_id
      foreign: id
      foreignAlias: users
      onDelete: cascade
      foreignType: many
      owningSide: true
  indexes:
    fk_users_groups:
      fields: [group_id]

Group:
  tableName: groups
  columns:
    id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
      autoincrement: true
    name:
      type: string(45)

UserComment:
  tableName: user_comments
  columns:
    id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
      autoincrement: true
    user_id:
      type: integer(4)
      unsigned: true
      notnull: true
    created_at:
      type: timestamp
    title:
      type: string(200)
    text:
      type: clob(65535)
  relations:
    user:
      class: User
      local: user_id
      foreign: id
      foreignAlias: userComments
      foreignType: many
      owningSide: true
  indexes:
    fk_user_comments_users1:
      fields: [user_id]