PHP

Как писать миграции в yii framework 2.0

Наиболее уместный и удобный вариант написания миграций для фреймворка Yii 2.0.

В данной статье вы увидите одну из общепринятых практик написания миграций для популярного фреймворка Yii. Многие проекты блога catine используют данный подход, так как он считается общепринятым в нашей команде разработчиков. Надеюсь, вы используете Linux, как основную операционную систему для разработки. Если же вы используете Windows, то советую вам обратиться к Vagrant и начать использовать unix системы при разработке.

Давайте договоримся, что у нас есть следующая схема данных, которую необходимо реализовать:

  1. Таблица articles — таблица, которая уже существует в бд, в миграции будем на нее только ссылаться. Эта сущность обозначает новости на сайте, описывается следующим набором полей:id — идентификатор, первичный ключtitle — название новости, текстовое полеcontent — содержание новости, текстовое поле
  2. id — идентификатор, первичный ключ
  3. title — название новости, текстовое поле
  4. content — содержание новости, текстовое поле
  5. Таблица tasks — задачи для новостей, сущность будет создаваться в миграции. Имеет следующий набор полей:id — идентификатор, первичный ключtitle — текст задачи, текстовое полеsort — поле для сортировки, при создании равно нулю
  6. id — идентификатор, первичный ключ
  7. title — текст задачи, текстовое поле
  8. sort — поле для сортировки, при создании равно нулю
  9. Таблица articles_has_tasks — таблица пересечения задач и новостей, так как у нас связь между таблицами N:M многие ко многим. Имеет следующий набор полей:task_id — ссылка на задачуarticle_id — ссылка на новость
  10. task_id — ссылка на задачу
  11. article_id — ссылка на новость

Для создания миграции необходимо перейти в рабочий каталог с установленным yii framework`ом и выполнить команду:

php yii migrate/create название_миграции

В нашем случае необходимо будет выполнить команду  php yii migrate/createcreate_task_table и в ответ на вопрос ответь yes. Более подробно можно увидеть на рисунке:

 И после того, как вы увидели заветную надпись New migration created successfully. , можно приступить к написанию кода миграции.

Как учит писать нас документация по yii 2.0 миграции:

<?php use yii\db\Schema; use yii\db\Migration; class m160511_031901_create_task_table extends Migration { public function safeUp() { $this->createTable('tasks', [ 'id' => Schema::TYPE_INTEGER . ' NOT NULL', 'lang' => 'CHAR(2) NOT NULL DEFAULT "ru" COLLATE utf8_unicode_ci', 'title' => Schema::TYPE_STRING . ' NOT NULL', 'sort' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', 'PRIMARY KEY (`id`, `lang`)' ], 'CHARSET=utf8 COLLATE=utf8_general_ci'); $this->createTable('articles_has_tasks', [ 'article_id' => Schema::TYPE_INTEGER . ' NOT NULL', 'task_id' => Schema::TYPE_INTEGER . ' NOT NULL', ], 'CHARSET=utf8 COLLATE=utf8_general_ci'); $this->addPrimaryKey('articles_has_tasks' . '_pk', 'articles_has_tasks', ['article_id', 'task_id']); $this->addForeignKey('task_' . 'articles_has_tasks' . '_fk', 'articles_has_tasks', 'task_id', 'tasks', 'id'); $this->addForeignKey('articles' . '_fk', 'articles_has_tasks', 'article_id', 'articles', 'id'); } public function safeDown() { $this->dropTable('articles_has_tasks'); $this->dropTable('tasks'); } }

Данная миграция уже будет работать, применяться (команда php yii migrate 1 ) и откатываться без ошибок (команда php yii migrate/down 1 ), но не всегда понятно какой sql запрос будет сформирован, поэтому советую вам использовать другой подход написания миграции, более приближенный к sql запросам.

Данную миграцию можно было бы написать следующим образом:

<?php use yii\db\Schema; use yii\db\Migration; class m160511_031901_create_task_table extends Migration { public function safeUp() { $this->createTable('tasks', [ 'id' => 'int(11) NOT NULL', 'lang' => 'CHAR(2) NOT NULL DEFAULT "ru" COLLATE utf8_unicode_ci', 'title' => 'char(255) NOT NULL COLLATE utf8_unicode_ci', 'sort' => 'int(11) NOT NULL DEFAULT 0', 'PRIMARY KEY (`id`, `lang`)' ], 'CHARSET=utf8 COLLATE=utf8_general_ci'); $this->createTable('articles_has_tasks', [ 'article_id' => 'int(11) NOT NULL', 'task_id' => 'int(11) NOT NULL', 'PRIMARY KEY (`article_id`, `task_id`)', 'FOREIGN KEY (`article_id`) REFERENCES `articles`(`id`)', 'FOREIGN KEY (`task_id`) REFERENCES `tasks`(`id`)' ], 'CHARSET=utf8 COLLATE=utf8_general_ci'); } public function safeDown() { $this->dropTable('articles_has_tasks'); $this->dropTable('tasks'); } }

Данный подход дает позволяет более точно определить какой запрос будет сформирован при выполнении миграции, что увеличивает понимание в команде разработчиков. Такой код легче всего читать и писать, так как он максимально приближен к sql. Если у вас остались вопросы, пишите их в комментариях.

{"time":1561660203112,"blocks":[{"type":"paragraph","data":{"text":"Наиболее уместный и удобный вариант написания миграций для фреймворка Yii 2.0."}},{"type":"paragraph","data":{"text":"В данной статье вы увидите одну из общепринятых практик написания миграций для популярного фреймворка Yii. Многие проекты блога catine используют данный подход, так как он считается общепринятым в нашей команде разработчиков. Надеюсь, вы используете Linux, как основную операционную систему для разработки. Если же вы используете Windows, то советую вам обратиться к Vagrant и начать использовать unix системы при разработке."}},{"type":"paragraph","data":{"text":"Давайте договоримся, что у нас есть следующая схема данных, которую необходимо реализовать:"}},{"type":"list","data":{"style":"ordered","items":["Таблица articles — таблица, которая уже существует в бд, в миграции будем на нее только ссылаться. Эта сущность обозначает новости на сайте, описывается следующим набором полей:id — идентификатор, первичный ключtitle — название новости, текстовое полеcontent — содержание новости, текстовое поле","id — идентификатор, первичный ключ","title — название новости, текстовое поле","content — содержание новости, текстовое поле","Таблица tasks — задачи для новостей, сущность будет создаваться в миграции. Имеет следующий набор полей:id — идентификатор, первичный ключtitle — текст задачи, текстовое полеsort — поле для сортировки, при создании равно нулю","id — идентификатор, первичный ключ","title — текст задачи, текстовое поле","sort — поле для сортировки, при создании равно нулю","Таблица articles_has_tasks — таблица пересечения задач и новостей, так как у нас связь между таблицами N:M многие ко многим. Имеет следующий набор полей:task_id — ссылка на задачуarticle_id — ссылка на новость","task_id — ссылка на задачу","article_id — ссылка на новость"]}},{"type":"paragraph","data":{"text":"Для создания миграции необходимо перейти в рабочий каталог с установленным yii framework`ом и выполнить команду:"}},{"type":"code","data":{"code":"php yii migrate/create название_миграции"}},{"type":"paragraph","data":{"text":"В нашем случае необходимо будет выполнить команду  php yii migrate/createcreate_task_table и в ответ на вопрос ответь yes. Более подробно можно увидеть на рисунке:"}},{"type":"image","data":{"file":{"url":"/storage/images/5I6dz6MmvlmUwDhONpsp0y3wwghhl7AbtbqZzrx1.png","thumbnails":["/storage/images/5I6dz6MmvlmUwDhONpsp0y3wwghhl7AbtbqZzrx1_small.png"]},"caption":"","withBorder":false,"stretched":false,"withBackground":false}},{"type":"paragraph","data":{"text":" И после того, как вы увидели заветную надпись New migration created successfully. , можно приступить к написанию кода миграции."}},{"type":"paragraph","data":{"text":"Как учит писать нас документация по yii 2.0 миграции:"}},{"type":"code","data":{"code":"<?php\n\nuse yii\\db\\Schema;\nuse yii\\db\\Migration;\n\nclass m160511_031901_create_task_table extends Migration\n{\n public function safeUp()\n {\n $this->createTable('tasks', [\n 'id' => Schema::TYPE_INTEGER . ' NOT NULL',\n 'lang' => 'CHAR(2) NOT NULL DEFAULT \"ru\" COLLATE utf8_unicode_ci',\n 'title' => Schema::TYPE_STRING . ' NOT NULL',\n 'sort' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0',\n 'PRIMARY KEY (`id`, `lang`)'\n ], 'CHARSET=utf8 COLLATE=utf8_general_ci');\n\n\t\t$this->createTable('articles_has_tasks', [\n\t\t\t'article_id' => Schema::TYPE_INTEGER . ' NOT NULL',\n\t\t\t'task_id' => Schema::TYPE_INTEGER . ' NOT NULL',\n\t\t], 'CHARSET=utf8 COLLATE=utf8_general_ci');\n\n\t\t$this->addPrimaryKey('articles_has_tasks' . '_pk', 'articles_has_tasks', ['article_id', 'task_id']);\n\n\t\t$this->addForeignKey('task_' . 'articles_has_tasks' . '_fk', 'articles_has_tasks', 'task_id', 'tasks', 'id');\n\n\t\t$this->addForeignKey('articles' . '_fk', 'articles_has_tasks', 'article_id', 'articles', 'id');\n }\n\n public function safeDown()\n {\n $this->dropTable('articles_has_tasks');\n $this->dropTable('tasks');\n }\n}"}},{"type":"paragraph","data":{"text":"Данная миграция уже будет работать, применяться (команда php yii migrate 1 ) и откатываться без ошибок (команда php yii migrate/down 1 ), но не всегда понятно какой sql запрос будет сформирован, поэтому советую вам использовать другой подход написания миграции, более приближенный к sql запросам."}},{"type":"paragraph","data":{"text":"Данную миграцию можно было бы написать следующим образом:"}},{"type":"code","data":{"code":"<?php\n\nuse yii\\db\\Schema;\nuse yii\\db\\Migration;\n\nclass m160511_031901_create_task_table extends Migration\n{\n public function safeUp()\n {\n $this->createTable('tasks', [\n 'id' => 'int(11) NOT NULL',\n 'lang' => 'CHAR(2) NOT NULL DEFAULT \"ru\" COLLATE utf8_unicode_ci',\n 'title' => 'char(255) NOT NULL COLLATE utf8_unicode_ci',\n 'sort' => 'int(11) NOT NULL DEFAULT 0',\n 'PRIMARY KEY (`id`, `lang`)'\n ], 'CHARSET=utf8 COLLATE=utf8_general_ci');\n\n $this->createTable('articles_has_tasks', [\n 'article_id' => 'int(11) NOT NULL',\n 'task_id' => 'int(11) NOT NULL',\n 'PRIMARY KEY (`article_id`, `task_id`)',\n 'FOREIGN KEY (`article_id`) REFERENCES `articles`(`id`)',\n 'FOREIGN KEY (`task_id`) REFERENCES `tasks`(`id`)'\n ], 'CHARSET=utf8 COLLATE=utf8_general_ci');\n }\n\n public function safeDown()\n {\n $this->dropTable('articles_has_tasks');\n $this->dropTable('tasks');\n }\n}"}},{"type":"paragraph","data":{"text":"Данный подход дает позволяет более точно определить какой запрос будет сформирован при выполнении миграции, что увеличивает понимание в команде разработчиков. Такой код легче всего читать и писать, так как он максимально приближен к sql. Если у вас остались вопросы, пишите их в комментариях."}}],"version":"2.13.0"}
image

Евгений

Специалист по разработке систем на современных PHP фреймворках.