- Порядок выполнения миграций
- Поля миграции с часовыми поясами
- Типы столбцов миграции базы данных
- Значения timestamp по умолчанию
- Статус миграций
- Написание имени миграции с пробелами
- Создать столбец после другого столбца
- Создать миграцию для существующей таблицы
- Вывод SQL перед запуском миграций
- Анонимные миграции
- Комментарий для столбца
- Проверка на существования таблицы или столбца
- Проверка на наличие перед добавлением или удалением столбца
- Переименование поля PostgreSQL
Если вы хотите изменить порядок выполнения миграций, то просто поменяйте время в названии файла миграции, например, 2023_08_04_070443_create_posts_table.php
измените на 2023_07_04_070443_create_posts_table.php
(внимательно, меняется дата 2023_08_04
to 2023_07_04
).
Они запускаются в алфавитном порядке.
Знаете ли, что в миграция доступны не только timestamps()
, но и timestampsTz()
, для часовых поясов?
Schema::create('employees', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->timestampsTz();
});
Также есть такие типы для колонок dateTimeTz()
, timeTz()
, timestampTz()
, softDeletesTz()
.
Существует множество любопытных типов полей для создаваемых миграций, приведу парочку в качестве примеров.
$table->geometry('positions');
$table->ipAddress('visitor');
$table->macAddress('device');
$table->point('position');
$table->uuid('id');
Посмотреть все доступные типы можно в официальной документации.
При создании миграции вы можете использовать вместе с timestamp()
следующие параметры useCurrent()
и useCurrentOnUpdate()
,
они помогут установить CURRENT_TIMESTAMP
в качестве значения по умолчанию.
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrentOnUpdate();
Если вы хотите посмотреть статус выполнения миграций, то нет нужды заходить в таблицу миграций, достаточно ввести команду php artisan migrate:status
.
Результат выполнения команды:
Migration name .......................................................................... Batch / Status
2023_12_01_000000_create_users_table ........................................................... [1] Ran
2023_12_02_100000_create_password_resets_table ................................................. [1] Ran
2023_12_03_000000_create_failed_jobs_table ..................................................... [1] Ran
When typing make:migration
command, you don't necessarily have to use underscore _
symbol between parts, like create_transactions_table
. You can put the name into quotes and then use spaces instead of underscores.
// Это работает
php artisan make:migration create_transactions_table
// Но это также будет работать
php artisan make:migration "create transactions table"
Источник: Steve O on Twitter
Внимание: Только для MySQL
Если вы добавляете новый столбец, то не обязательно, чтобы он был последним в списке. Можно указать, после какого столбца он должен быть создан.
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->after('email');
});
Также можно создать новый столбец, чтобы он находился перед указанным столбцом.
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->before('created_at');
});
Если же вы хотите, чтобы новый столбец был первым в таблице, используйте метод first()
.
Schema::table('users', function (Blueprint $table) {
$table->string('uuid')->first();
});
Также метод after()
позволяет использовать добавление нескольких полей, тем самым объединяя их в группу.
Schema::table('users', function (Blueprint $table) {
$table->after('remember_token', function ($table){
$table->string('card_brand')->nullable();
$table->string('card_last_four', 4)->nullable();
});
});
Если вы хотите создать миграцию для существующей таблицы и хотите, чтобы Laravel сгенерировал для вас Schema::table(), то достаточно добавить "_in_xxxxx_table" or "_to_xxxxx_table" в название миграции или использовать параметр "--table", где укажите название вашей таблицы.
По умолчанию php artisan change_fields_products_table
генерирует пустой класс.
class ChangeFieldsProductsTable extends Migration
{
public function up()
{
//
}
}
Но стоит добавить in_xxxxx_table
php artisan make:migration change_fields_in_products_table
и автоматически создастся Schema::table()
с предварительно заполненным именем таблицы.
class ChangeFieldsProductsTable extends Migration
{
public function up()
{
Schema::table('products', function (Blueprint $table) {
//
})
};
}
Also you can specify --table
parameter php artisan make:migration whatever_you_want --table=products
class WhateverYouWant extends Migration
{
public function up()
{
Schema::table('products', function (Blueprint $table) {
//
})
};
}
При написании команды migrate --pretend
, вы можете вывести запрос, который впоследствии будет выполняться.
Это интересный способ для отладки запросов при необходимости.
php artisan migrate --pretend
Совет от @zarpelon
Команда Laravel выпустила Laravel 8.37 с поддержкой анонимной миграции, которая решает проблему GitHub с конфликтами имен классов миграции.
Суть проблемы в том, что если несколько миграций имеют одно и то же имя класса, это вызовет проблемы при попытке воссоздать базу данных с нуля.
Вот пример из pull request:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(
{
Schema::table('people', function (Blueprint $table) {
$table->string('first_name')->nullable();
});
}
public function down()
{
Schema::table('people', function (Blueprint $table) {
$table->dropColumn('first_name');
});
}
};
Совет от @nicksdot
Вы можете добавить «комментарий» о столбце внутри ваших миграций, тем самым предоставите полезную информацию.
Если базой данных управляет кто-то, кроме разработчиков, они могут просматривать комментарии в структуре таблицы перед выполнением каких-либо операций.
$table->unsignedInteger('interval')
->index()
->comment('This column is used for indexing.')
Совет от @nicksdot
Вы можете проверить наличие таблицы или столбца, используя методы hasTable и hasColumn:
if (Schema::hasTable('users')) {
// Таблица "users" существует...
}
if (Schema::hasColumn('users', 'email')) {
// Таблица "users" найдена и имеет поле "email"...
}
Совет от @dipeshsukhia
Теперь вы можете добавить столбец в таблицу базы данных, только если он отсутствует, и можете удалить его, если он присутствует. Для этого вводятся следующие методы:
👉 whenTableDoesntHaveColumn
👉 whenTableHasColumn
Доступно для Laravel 9.6.0
return new class extends Migration {
public function up()
{
Schema::whenTableDoesntHaveColumn('users', 'name', function (Blueprint $table) {
$table->string('name', 30);
});
}
public function down()
{
Schema::whenTableHasColumn('users', 'name', function (Blueprint $table) {
$table->dropColumn('name');
});
}
}
Совет от @iamharis010
Если вам потребуется переименовать поле, то для PostgreSQL работает следующий прием.
return new class extends Migration {
public function up()
{
DB::transaction(function () {
DB::statement('ALTER TABLE settings_workflows RENAME COLUMN after_hiring TO after_date');
});
}
public function down()
{
DB::transaction(function () {
DB::statement('ALTER TABLE settings_workflows RENAME COLUMN after_date TO after_hiring');
});
}
}
Для MySQL поможет такой вариант.
return new class extends Migration {
public function up()
{
Schema::table('settings_workflows', function(Blueprint $table) {
$table->renameColumn('after_hiring', 'after_date');
});
}
public function down()
{
Schema::table('settings_workflows', function(Blueprint $table) {
$table->renameColumn('after_date', 'after_hiring');
});
}
}