Я привык рассматривать миграции Laravel как ярлыки для быстрого создания таблиц без необходимости написания SQL. В более широкой среде я видел ее использование как способ «контроля версий» схемы базы данных. Тем не менее, я нашел другое отличное применение для миграции, особенно вместе с семенами.
Прежде всего, как вы должны использовать миграции?
«Versioning»
Миграции хороши тем, что позволяют отслеживать пошаговые изменения в настройке базы данных, а также обновлять или откатывать эти изменения. Например, если вы добавите новую таблицу, это миграция. Если вы отбросите таблицу, это откат на миграцию. Если вы хотите добавить новый столбец в таблицу, вы можете легко настроить миграцию для этого, а также откат для удаления этого дополнительного столбца.
Вот как выглядит миграция:
<?php use Illuminate\Database\Migrations\Migration; class CreateUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function($table) { $table->increments('id'); $table->string('email')->unique(); $table->string('username'); $table->string('name'); $table->string('password'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('users'); } }
Функция «up ()» определяет, что делать, когда вы выполняете миграцию (через командную строку и Artisan), а функция «down ()» сообщает Laravel, как выполнить откат. Функции миграции идут дальше, вы можете:
- создавать индексы
- создавать внешние ключи
- добавить / удалить / переименовать столбцы
Кроме того, вы можете в значительной степени указать все, что вы хотите, чтобы миграция выполняла, включая перемещение данных и выполнение необработанных запросов.
Что хорошо в «down ()» — это то, что вы только что сделали. Ок, и что?
Что ж, в больших системах вы можете сразу запускать функции и готово к их изменению, подобно тому, как вы можете отменить коммит в репозитории Git и развернуть его.
Посев
Итак, посев — это именно то, на что это похоже. Вы добавляете данные в свои таблицы. Да, вы можете сделать это с помощью миграции, но это плохая практика, поскольку это может повлиять на ваши производственные данные. Представьте, что вы добавляете примеры данных в вашу систему каждый раз, когда запускаете миграцию. Не очень хорошая практика. Так что вот где начинается посев. На самом деле посев больше предназначен для среды тестирования.
Вместо выборки реальных данных вы можете использовать Seeds для работы. Вы можете заполнить каждую таблицу с таким количеством данных, сколько хотите. Laravel возьмет семена и поместит их в вашу базу данных, чтобы вы были готовы к работе (заполнение выполняется с помощью командной строки и файла). Вот как выглядит файл заполнения:
<?php class UserTableSeeder extends Seeder { public function run() { DB::table('users')->delete(); $user = new User; $user->fill(array( 'email' => '[email protected]', 'username' => 'antjanus', 'name' => 'Antonin Januska' )); $user->password = Hash::make('admin'); $user->save(); } }
Фу, итак, давайте пройдемся очень быстро. Это моя таблица пользователя. Во-первых, обратите внимание, что первое, что делает мой читатель, это удаляет все существующие данные. Это хорошо, но не обязательно. Я бы сделал это потому, что каждый раз, когда я запускаю сеялку, я эффективно дублирую свои данные. Зачем мне запускать сеялку несколько раз? Потому что каждый раз, когда я делаю миграцию, я хочу, чтобы данные тестирования были готовы. Так что, да, удалите все строки в таблице. Я использую Laravel Eloquent ORM для создания объекта на основе моей пользовательской модели, использую массовое назначение (не забудьте включить его!) И сохраняю его в базе данных.
Каждый раз, когда я запускаю сеялку, я запускаю вот это:
<?php class DatabaseSeeder extends Seeder { public function run() { $this->call('UserTableSeeder'); $this->command->info('User table seeded!'); $this->call('LinkTableSeeder'); $this->command->info('Link table seeded!'); $this->call('PostTableSeeder'); $this->command->info('Post table seeded!'); } }
Проверьте это: когда я запускаю сеялку через командную строку, я получаю обратную связь, когда посев завершен. Это файл DatabaseSeeder, который запускается. Вы можете пропустить семена и добавлять новые семена, когда это имеет смысл. Например, если вы только что удалили таблицу, нет причин продолжать заполнять ее (потому что вы получите ошибку), поэтому вы удаляете строку. Вы все еще можете сохранить исходный файл сеялки на случай, если вы захотите откатить миграцию (и добавить таблицу обратно).
Это пример того, как я запустил две миграции для своего проекта: ссылки и посты. Затем я посеял свои столы.
Куда это нас ведет?
Конечная среда тестирования воспроизводима на разных платформах. Если вы когда-либо клонируете мое хранилище с Laravel с миграциями или семенами, у вас нет причин загружать файл SQL или запускать какой-то странный скрипт. Все встроено. С помощью нескольких команд вы можете:
- запустить все миграции, создать все таблицы, индексы, внешние ключи и все остальное
- запустите все сеялки и заполните все ваши таблицы, которые будут снабжены готовыми данными тестирования
Больше нет необходимости создавать «тестовые записи» для вашего блога, выполнять SQL-запросы, чтобы заполнить вашу БД случайными данными. У вас единая среда. Что еще лучше? Вы можете поиграть с базой данных, добавить данные, использовать свои вещи, а затем сбросить.
Да, как только вы закончите играть, просто откатите ваши миграции, запустите их снова, и вы будете готовы с новой базой данных. Запустите сеялку еще раз, и вы готовы продолжать работать.
Это означает, что ваша среда в значительной степени неразрушима. Вы не привязаны к производственной базе данных и не застряли при загрузке или загрузке больших файлов SQL или копий рабочей базы данных. Вы в основном «застряли», выполняя две команды и позволяя Laravel делать все. Подождите, подождите, давайте сделаем это проще:
php artisan migrate:refresh --seed
Эта маленькая команда откатывает ВСЕ ваши миграции, переносит их снова и заполняет базу данных. Это окончательное «обновление». ; D
Я играл с этим некоторое время.
А как насчет других фреймворков?
Конечно, это не уникально для Laravel. Я впервые столкнулся с этим с Symfony, у которого также есть миграции и «приспособления», которые в основном являются «семенами».
Итак … как ты это делаешь?
Это просто. Документация Laravel довольно хорошо объясняет все, но вот краткий обзор. Не забывайте требования:
- доступ из командной строки к Laravel
- PHP доступ через командную строку
Создание миграции
Первый шаг — создание миграции. Все, что для этого требуется, — это одна команда для Artisan (инструмент командной строки для Laravel):
php artisan migrate:make create_your_table
Это создаст файл в вашей папке app / database / migrations с именем «create_your_table» с отметкой времени. Вы можете захотеть быть более семантическими, чем в вашем проекте. Откройте файл и заполните его:
<?php use Illuminate\Database\Migrations\Migration; class CreateUserTable extends Migration { public function up() { Schema::create('users', function($table) { $table->increments('id'); $table->string('email')->unique(); $table->string('username'); $table->string('name'); $table->string('password'); $table->timestamps(); }); } public function down() { Schema::drop('users'); } }
Продолжайте читать документацию Schema по Laravel, чтобы лучше понять универсальность, которую вы получаете с миграциями. Большой! Обратите внимание, что я использовал мой предыдущий «пользовательский» пример с именем CreateUserTable (create_user_table в командной строке).
Перенести
ОК, время для переноса ваших данных.
php artisan migrate
Вы должны получить либо сообщение об ошибке, либо сообщение об ошибке в отношении вашей миграции. Если это ваша первая миграция, Laravel также создаст таблицу «миграций», в которой будут указаны имена и серии выполненных миграций. Если вы создадите пять разных миграций и перенесете их одновременно, они будут сгруппированы в «пакет» и, таким образом, будут откатываться вместе. Это полезно, если ваши миграции зависят друг от друга по функциональности.
Создать сеялку
Для заполнения вы должны будете создать свой собственный файл, например:
<?php class UserTableSeeder extends Seeder { public function run() { DB::table('users')->delete(); $user = new User; $user->fill(array( 'email' => '[email protected]', 'username' => 'antjanus', 'name' => 'Antonin Januska' )); $user->password = Hash::make('admin'); $user->save(); } }
Опять же, убедитесь, что имя класса имеет смысл. Кроме того, убедитесь, что у вас уже есть модель! Сохраните этот файл в папке базы данных / семян. Затем добавьте ссылку на этот класс в DatabaseSeeder:
<?php class DatabaseSeeder extends Seeder { public function run() { $this->call('UserTableSeeder'); $this->command->info('User table seeded!'); } }
Удостоверьтесь, что вы добавили это немного, чтобы сообщить, была ли база данных заполнена. Это хорошая информация обратной связи.
Семя!
Последнее, запусти свою начальную команду!
php artisan db:seed
Готово!