Может войдёшь?
Черновики Написать статью Профиль

Миграции

перевод документация 5.х

  1. 1. Введение
  2. 2. Создание миграций
  3. 3. Структура миграций
  4. 4. Выполнение миграций
    1. 4.1. Откат миграций
  5. 5. Таблицы
    1. 5.1. Создание таблиц
    2. 5.2. Переименование/удаление таблиц
  6. 6. Столбцы
    1. 6.1. Создание столбцов
    2. 6.2. Модификаторы столбцов
    3. 6.3. Изменение столбцов
    4. 6.4. Удаление столбцов
  7. 7. Индексы
    1. 7.1. Создание индексов
    2. 7.2. Удаление индексов
    3. 7.3. Ограничения внешнего ключа
  8. 8. Загрузка начальных данных в БД
Этот перевод актуален для англоязычной документации на (ветка 5.3) , (ветка 5.2) , (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Миграции — что-то вроде системы контроля версий для вашей базы данных. Они позволяют вашей команде изменять структуру БД, в то же время оставаясь в курсе изменений других участников. Миграции обычно идут рука об руку с построителем структур для более простого обращения с архитектурой вашей базы данных. Если вы когда-нибудь просили коллегу вручную добавить столбец в его локальную БД, значит вы сталкивались с проблемой, которую решают миграции БД.

Фасад Laravel Schema обеспечивает поддержку создания и изменения таблиц в независимости от используемой СУБД из числа тех, что поддерживаются в Laravel.

Создание миграций

Для создания новой миграции используйте Artisan-команду shmake:migration:

shphp artisan make:migration create_users_table

Миграция будет помещена в папку database/migrations и будет содержать метку времени, которая позволяет фреймворку определять порядок применения миграций.

Можно также использовать параметры --table и --create для указания имени таблицы и того факта, что миграция будет создавать новую таблицу (а не изменять существующую — прим. пер.). Эти параметры просто заранее создают указанную таблицу в создаваемом файле-заглушке миграции:

shphp artisan make:migration create_users_table --create=users

php artisan make:migration add_votes_to_users_table --table=users

Если вы хотите указать свой путь для сохранения создаваемых миграций, используйте параметр --path при запуске команды shmake:migration. Этот путь должен быть указан относительно базового пути вашего приложения.

Структура миграций

Класс миграций содержит два метода: PHPup() и PHPdown(). Метод PHPup() используется для добавления новых таблиц, столбцов или индексов в вашу БД, а метод PHPdown() просто отменяет операции, выполненные методом PHPup().

В обоих методах вы можете использовать построитель структур Laravel для удобного создания и изменения таблиц. О всех доступных методах построителя структур читайте в его документации. Например, эта миграция создаёт таблицу flights:

PHP
<?php

use Illuminate\Support\Facades\Schema;
use 
Illuminate\Database\Schema\Blueprint;
use 
Illuminate\Database\Migrations\Migration;

class 
CreateFlightsTable extends Migration
{
  
/**
   * Выполнение миграций.
   *
   * @return void
   */
  
public function up()
  {
    
Schema::create('flights', function (Blueprint $table) {
      
$table->increments('id');
      
$table->string('name');
      
$table->string('airline');
      
$table->timestamps();
    });
  }

  
/**
   * Отмена миграций.
   *
   * @return void
   */
  
public function down()
  {
    
Schema::drop('flights');
  }
}

Выполнение миграций

Для запуска всех необходимых вам миграций используйте Artisan-команду shmigrate.

shphp artisan migrate

Если вы используете виртуальную машину Homestead, вам надо выполнить эту команду на ВМ.

+ 5.2 5.1 5.0

добавлено в 5.2 () 5.1 () 5.0 ()

Если при применении миграции вы получаете ошибку «class not found» («класс не найден»), попробуйте выполнить команду shcomposer dump-autoload и заново запустить команду shmigrate.

Принудительные миграции в продакшне

Некоторые операции миграций разрушительны, значит они могут привести к потере ваших данных. Для предотвращения случайного запуска этих команд на вашей боевой БД перед их выполнением запрашивается подтверждение. Для принудительного запуска команд без подтверждения используйте ключ sh--force:

shphp artisan migrate --force

Откат миграций

Для отмены изменений, сделанных последней миграцией, используйте команду shrollback. Эта команда отменит результат последней «партии» миграций, которая может включать несколько файлов миграций:

shphp artisan migrate:rollback
+ 5.3

добавлено в 5.3 ()

Вы можете сделать откат определённого числа миграций, указав параметр shstep для команды shrollback. Например, эта команда откатит последние пять миграций:

shphp artisan migrate:rollback --step=5

Команда shmigrate:reset отменит изменения всех миграций вашего приложения:

shphp artisan migrate:reset

Откат всех миграций и их повторное применение одной командой

Команда shmigrate:refresh отменит изменения всех ваших миграций, а затем выполнит команду shmigrate. Эта команда эффективно создаёт заново всю вашу БД:

shphp artisan migrate:refresh

// Обновить БД и запустить заполнение БД начальными данными...
php artisan migrate:refresh --seed
+ 5.3

добавлено в 5.3 ()

Вы можете откатить и повторно применить определённое число миграций, указав параметр shstep для команды shrefresh. Например, эта команда откатит и повторно применит последние пять миграций:

shphp artisan migrate:refresh --step=5

Таблицы

Создание таблиц

Для создания новой таблицы БД используйте метод PHPcreate() фасада Schema. Метод PHPcreate() принимает два аргумента. Первый — имя таблицы, второй — замыкание, которое получает объект Blueprint, который можно использовать для определения новой таблицы:

PHP
Schema::create('users', function (Blueprint $table) {
  
$table->increments('id');
});

Само собой, при создании таблицы вы можете использовать любые методы для работы со столбцами построителя структур.

Проверка существования таблицы/столбца

Вы можете легко проверить существование таблицы или столбца при помощи методов PHPhasTable() и PHPhasColumn():

PHP
if (Schema::hasTable('users')) {
  
//
}

if (
Schema::hasColumn('users''email')) {
  
//
}

Подключение и подсистема хранения данных

Если вы хотите выполнить операции над структурой через подключение к БД, которое не является вашим основным подключением, используйте метод PHPconnection():

PHP
Schema::connection('foo')->create('users', function (Blueprint $table) {
  
$table->increments('id');
});

Используйте свойство engine построителя структур, чтобы задать подсистему хранения данных для таблицы:

PHP
Schema::create('users', function (Blueprint $table) {
  
$table->engine 'InnoDB';

  
$table->increments('id');
});

Переименование/удаление таблиц

Для переименования существующей таблицы используйте метод PHPrename():

PHP
Schema::rename($from$to);

Для удаления существующей таблицы используйте методы PHPdrop() и PHPdropIfExists():

PHP
Schema::drop('users');

Schema::dropIfExists('users');
+ 5.2

добавлено в 5.2 ()

Переименование таблиц с внешними ключами

Перед переименованием таблицы вы должны проверить, что для всех ограничений внешних ключей таблицы есть явные имена в файлах вашей миграции, чтобы избежать автоматического назначения имён на основе принятого соглашения. Иначе имя ограничения внешнего ключа будет ссылаться на имя старой таблицы.

Столбцы

Создание столбцов

Для изменения существующей таблицы мы будем использовать метод PHPtable() фасада Schema. Как и метод PHPcreate(), метод PHPtable() принимает два аргумента: имя таблицы и замыкание, которое получает экземпляр Blueprint, который можно использовать для добавления столбцов в таблицу:

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->string('email');
});

Доступные типы столбцов

Разумеется, построитель структур содержит различные типы столбцов, которые вы можете указывать при построении ваших таблиц:

Команда Описание
$table->bigIncrements('id');Инкрементный ID (первичный ключ), использующий эквивалент "UNSIGNED BIG INTEGER"
$table->bigInteger('votes');Эквивалент BIGINT для базы данных
$table->binary('data');Эквивалент BLOB для базы данных
$table->boolean('confirmed');Эквивалент BOOLEAN для базы данных
$table->char('name', 4);Эквивалент CHAR для базы данных
$table->date('created_at');Эквивалент DATE для базы данных
$table->dateTime('created_at');Эквивалент DATETIME для базы данных
$table->dateTimeTz('created_at');Эквивалент DATETIME (с часовым поясом) для базы данных (для версии 5.2 и выше)
$table->decimal('amount', 5, 2);Эквивалент DECIMAL с точностью и масштабом
$table->double('column', 15, 8);Эквивалент DOUBLE с точностью, всего 15 цифр, после запятой 8 цифр
$table->enum('choices', ['foo', 'bar']);Эквивалент ENUM для базы данных
$table->float('amount', 8, 2);Эквивалент FLOAT для базы данных, всего 8 знаков, из них 2 после запятой (для версии 5.3 и выше)
$table->float('amount');Эквивалент FLOAT для базы данных (для версии 5.2 и ранее)
$table->increments('id');Инкрементный ID (первичный ключ), использующий эквивалент "UNSIGNED INTEGER"
$table->integer('votes');Эквивалент INTEGER для базы данных
$table->ipAddress('visitor');Эквивалент IP-адреса для базы данных (для версии 5.2 и выше)
$table->json('options');Эквивалент JSON для базы данных
$table->jsonb('options');Эквивалент JSONB для базы данных
$table->longText('description');Эквивалент LONGTEXT для базы данных
$table->macAddress('device');Эквивалент MAC-адреса для базы данных (для версии 5.2 и выше)
$table->mediumIncrements('id');Инкрементный ID (первичный ключ), использующий эквивалент "UNSIGNED MEDIUM INTEGER" (для версии 5.3 и выше)
$table->mediumInteger('numbers');Эквивалент MEDIUMINT для базы данных
$table->mediumText('description');Эквивалент MEDIUMTEXT для базы данных
$table->morphs('taggable');Добавление столбца taggable_id INTEGER (для версии 5.3 и выше Unsigned INTEGER) и taggable_type STRING
$table->nullableMorphs('taggable');Аналогично morphs(), но разрешено значение NULL (для версии 5.3 и выше)
$table->nullableTimestamps();Аналогично timestamps(), но разрешено значение NULL
$table->rememberToken();Добавление столбца remember_token VARCHAR(100) NULL
$table->smallIncrements('id');Инкрементный ID (первичный ключ), использующий эквивалент "UNSIGNED SMALL INTEGER" (для версии 5.3 и выше)
$table->smallInteger('votes');Эквивалент SMALLINT для базы данных
$table->softDeletes();Добавление столбца deleted_at для мягкого удаления (для версии 5.3 и выше разрешено значение NULL)
$table->string('email');Эквивалент VARCHAR
$table->string('name', 100);Эквивалент VARCHAR с длинной
$table->text('description');Эквивалент TEXT для базы данных
$table->time('sunrise');Эквивалент TIME для базы данных
$table->timeTz('sunrise');Эквивалент TIME (с часовым поясом) для базы данных (для версии 5.2 и выше)
$table->tinyInteger('numbers');Эквивалент TINYINT для базы данных
$table->timestamp('added_on');Эквивалент TIMESTAMP для базы данных
$table->timestampTz('added_on');Эквивалент TIMESTAMP (с часовым поясом) для базы данных (для версии 5.2 и выше)
$table->timestamps();Добавление столбцов created_at и updated_at (для версии 5.3 и выше разрешено значение NULL)
$table->timestampsTz();Добавление столбцов created_at и updated_at (с часовым поясом), для которых разрешено значение NULL (для версии 5.3 и выше)
$table->unsignedBigInteger('votes');Эквивалент Unsigned BIGINT для базы данных (для версии 5.3 и выше)
$table->unsignedInteger('votes');Эквивалент Unsigned INT для базы данных (для версии 5.3 и выше)
$table->unsignedMediumInteger('votes');Эквивалент Unsigned MEDIUMINT для базы данных (для версии 5.3 и выше)
$table->unsignedSmallInteger('votes');Эквивалент Unsigned SMALLINT для базы данных (для версии 5.3 и выше)
$table->unsignedTinyInteger('votes');Эквивалент Unsigned TINYINT для базы данных (для версии 5.3 и выше)
$table->uuid('id');Эквивалент UUID для базы данных

Модификаторы столбцов

Вдобавок к перечисленным типам столбцов существует несколько «модификаторов» столбцов, которые вы можете использовать при добавлении столбцов в таблицу. Например, чтобы сделать столбец «обнуляемым», используйте метод PHPnullable():

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->string('email')->nullable();
});

Ниже перечислены все доступные модификаторы столбцов. В этом списке отсутствуют модификаторы индексов:

Модификатор Описание
->after('column')Помещает столбец "после" указанного столбца (только MySQL)
->comment('my comment')Добавляет комментарий в столбец (для версии 5.2 и выше)
->default($value)Указывает значение "по умолчанию" для столбца
->first()Помещает столбец "первым" в таблице (только MySQL)
->nullable()Разрешает вставлять значения NULL в столбец
->storedAs($expression)Создать генерируемый столбец типа stored (только MySQL) (для версии 5.3 и выше)
->unsigned()Делает столбцы integer беззнаковыми UNSIGNED
->virtualAs($expression)Создать генерируемый столбец типа virtual (только MySQL) (для версии 5.3 и выше)

Изменение столбцов

Требования

Перед изменением столбцов добавьте зависимость doctrine/dbal в свой файл composer.json. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и создания SQL-запросов, необходимых для выполнения указанных преобразований столбца:

shcomposer require doctrine/dbal

Изменение атрибутов столбца

Метод PHPchange() позволяет изменить тип существующего столбца или изменить его атрибуты. Например, если вы захотите увеличить размер строкового столбца name с 25 до 50:

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->string('name'50)->change();
});

Также мы можем изменить столбец, чтобы он стал «обнуляемым»:

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->string('name'50)->nullable()->change();
});
+ 5.3

добавлено в 5.3 ()

Столбы следующих типов нельзя «изменить»: char, double, enum, mediumInteger, timestamp, tinyInteger, ipAddress, json, jsonb, macAddress, mediumIncrements, morphs, nullableMorphs, nullableTimestamps, softDeletes, timeTz, timestampTz, timestamps, timestampsTz, unsignedMediumInteger, unsignedTinyInteger, uuid.

+ 5.2

добавлено в 5.2 ()

Пока не поддерживается изменение любых столбцов в таблице, содержащей столбцы типов enum, json или jsonb.

Переименование столбцов

Для переименования столбца используйте метод PHPrenameColumn() на построителе структур. Перед переименованием столбца добавьте зависимость doctrine/dbal в свой файл composer.json:

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->renameColumn('from''to');
});

Пока не поддерживается переименование любых столбцов в таблице, содержащей столбцы типов enum, а для версий 5.2 и ранее ещё и json или jsonb.

Удаление столбцов

Для удаления столбца используйте метод PHPdropColumn() на построителе структур. Перед удалением столбцов из базы данных SQLite вам необходимо добавить зависимость doctrine/dbal в ваш файл composer.json и выполнить команду shcomposer update для установки библиотеки:

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->dropColumn('votes');
});

Вы можете удалить несколько столбцов таблицы, передав массив их имён в метод PHPdropColumn():

PHP
Schema::table('users', function (Blueprint $table) {
  
$table->dropColumn(['votes''avatar''location']);
});

Удаление и изменение нескольких столбцов одной миграцией не поддерживается для базы данных SQLite.

Индексы

Создание индексов

Построитель структур поддерживает несколько типов индексов. Сначала давайте посмотрим на пример, в котором задаётся, что значения столбца должны быть уникальными. Для создания индекса мы можем просто сцепить метод PHPunique() с определением столбца:

PHP
$table->string('email')->unique();

Другой вариант — создать индекс после определения столбца. Например:

PHP
$table->unique('email');

Вы можете даже передать массив столбцов в метод PHPindex() для создания сложного индекса:

PHP
$table->index(['account_id''created_at']);
+ 5.2

добавлено в 5.2 ()

Laravel автоматически генерирует подходящее имя индекса, но вы можете передать своё значение вторым аргументом метода:

PHP
$table->index('email''my_index_name');

Доступные типы индексов

Команда Описание
$table->primary('id');Добавление первичного ключа
$table->primary(['first', 'last']);Добавление составных ключей
$table->unique('email');Добавление уникального индекса
$table->unique('state', 'my_index_name');Добавление своего имени индекса (для версии 5.2 и выше)
$table->unique(['first', 'last']);Добавление составного уникального индекса (для версии 5.3 и выше)
$table->index('state');Добавление базового индекса

Удаление индексов

Для удаления индекса необходимо указать его имя. По умолчанию Laravel автоматически назначает имена индексам. Просто соедините имя таблицы, имя столбца-индекса и тип индекса. Вот несколько примеров:

Команда Описание
$table->dropPrimary('users_id_primary');Удаление первичного ключа из таблицы "users"
$table->dropUnique('users_email_unique');Удаление уникального индекса из таблицы "users"
$table->dropIndex('geo_state_index');Удаление базового индекса из таблицы "geo"

Если вы передадите массив столбцов в метод для удаления индексов, будет сгенерировано стандартное имя индекса на основе имени таблицы, столбца и типа ключа:

PHP
Schema::table('geo', function (Blueprint $table) {
  
$table->dropIndex(['state']); // Удаление индекса 'geo_state_index'
});

Ограничения внешнего ключа

Laravel также поддерживает создание ограничений для внешнего ключа, которые используются для обеспечения ссылочной целостности на уровне базы данных. Например, давайте определим столбец user_id в таблице posts, который ссылается на столбец id в таблице users:

PHP
Schema::table('posts', function (Blueprint $table) {
    
$table->integer('user_id')->unsigned();

    
$table->foreign('user_id')->references('id')->on('users');
});

Вы также можете указать требуемое действие для свойств "on delete" и "on update" ограничений:

PHP
$table->foreign('user_id')
      ->
references('id')->on('users')
      ->
onDelete('cascade');

Для удаления внешнего ключа используйте метод PHPdropForeign(). Ограничения внешнего ключа используют те же принципы именования, что и индексы. Итак, мы соединим имя таблицы и столбцов из ограничения, а затем добавим суффикс "_foreign":

PHP
$table->dropForeign('posts_user_id_foreign');

Либо вы можете передать значение массива, при этом для удаления будет автоматически использовано стандартное имя ограничения:

PHP
$table->dropForeign(['user_id']);
+ 5.2

добавлено в 5.2 ()

Вы можете включить или выключить ограничения внешнего ключа в своих миграциях с помощью следующих методов:

PHP
Schema::enableForeignKeyConstraints();

Schema::disableForeignKeyConstraints();
+ 5.0

добавлено в 5.0 ()

Загрузка начальных данных в БД

Кроме миграций, описанных выше, Laravel также включает в себя механизм наполнения вашей БД начальными данными (seeding) с помощью специальных классов. Все такие классы хранятся в database/seeds. Они могут иметь любое имя, но вам, вероятно, следует придерживаться какой-то логики в их именовании — например, PHPUserTableSeeder и т.д. По умолчанию для вас уже определён класс PHPDatabaseSeeder. Из этого класса вы можете вызывать метод PHPcall() для подключения других классов с данными, что позволит вам контролировать порядок их выполнения.

Пример класса для загрузки начальных данных

PHP
class DatabaseSeeder extends Seeder {

  public function 
run()
  {
    
$this->call('UserTableSeeder');

    
$this->command->info('Таблица пользователей загружена данными!');
  }

}

class 
UserTableSeeder extends Seeder {

  public function 
run()
  {
    
DB::table('users')->delete();

    
User::create(['email' => 'foo@bar.com']);
  }

}

Для добавления данных в БД используйте Artisan-команду shdb:seed:

shphp artisan db:seed

По умолчанию команда db:seed вызывает класс PHPDatabaseSeeder, который может быть использован для вызова других классов, заполняющих БД данными. Однако, вы можете использовать параметр sh--class для указания конкретного класса для вызова:

shphp artisan db:seed --class=UserTableSeeder

Вы также можете использовать для заполнения БД данными команду %%(sh)migrate:refresh**, которая также откатит и заново применит все ваши миграции:

shphp artisan migrate:refresh --seed

Комментарии (3)

Razzwan

Дык не работает же seeds.

corazon

Вместо User::create(['email' => 'foo@bar.com']);

используйте DB::table('users')->insert(['email' => 'foo@bar.com']);

и всё заработает.

Aztwin
$table->smallInteger('year', 4)->unsigned();

Вылетает ошибка при миграции!

$table->smallInteger('year')->unsigned();

Полёт нормальный...

Ответ нашёл тут:

public function integer($column, $autoIncrement = false, $unsigned = false)
 {
  return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
 }

Итог:

$table->smallInteger('year')->lenght(4)->unsigned();

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.