Работа с миграциями в проектах Laravel

Раздел: Разработка на Laravel -> Команды консоли Laravel

Основы миграций базы данных в Laravel

Как применить все новые миграции в базе данных?

Команда php artisan migrate запускает все миграции, которые ещё не были выполнены. Миграции находятся в директории database/migrations. Каждая миграция содержит методы up() (применение) и down() (откат). После выполнения создается таблица migrations, отслеживающая уже примененные миграции.

php artisan migrate

Php artisan migrate (миграция базы данных в laravel)

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

Проблема: Ошибка подключения "SQLSTATE[HY000] [1045] Access denied for user". Решение: проверить учетные данные в .env (DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD). Также убедиться, что сервер БД запущен.

Как выполнить миграцию в production без запроса подтверждения?

В production окружении команда запрашивает подтверждение. Флаг --force отключает этот запрос:

php artisan migrate --force

Это удобно для автоматических деплоев и CI/CD. Важно: убедиться, что миграции протестированы на копии БД.

Проблема: случайное выполнение опасных изменений в продакшне. Решение: использовать защитные проверки в скриптах деплоя (например, разрешать --force только из определенной ветки).

Как просмотреть предполагаемые SQL-запросы без их выполнения?

Флаг --pretend выводит SQL-запросы, которые будут выполнены, но не применяет их:

php artisan migrate --pretend

Полезно для проверки миграций перед применением, особенно если используется сложная логика. Вывод содержит типы операций (create, alter) и имена таблиц.

Проблема: вывод не показывает значения привязок параметров. Решение: использовать логирование запросов в миграции или пакет barryvdh/laravel-debugbar.

Как выполнить миграцию вместе с наполнением тестовыми данными?

Флаг --seed запускает сидеры после миграции:

php artisan migrate --seed

Команда выполнит все миграции, затем вызовет php artisan db:seed. Можно указать конкретный сидер через --class:

php artisan migrate --seed --class=UserSeeder

Это ускоряет подготовку локального окружения.

Проблема: ошибка при выполнении сидера из-за зависимостей. Решение: проверять порядок миграций и сидеров, использовать DatabaseSeeder для вызова всех сидеров.

Как откатить последнюю миграцию?

Команда php artisan migrate:rollback откатывает последнюю группу миграций (обычно один batch). Опция --step позволяет откатить несколько шагов:

php artisan migrate:rollback --step=2

Откатит две последние группы. Количество шагов можно задать любым числом. Метод down() в каждой миграции должен корректно удалять созданные таблицы или столбцы.

Проблема: метод down() не полностью откатывает изменения (например, не удаляет индексы). Решение: тщательно прописывать down() для каждой миграции, используя методы типа dropIfExists(), dropColumn().

Как перезапустить все миграции?

Команда php artisan migrate:refresh откатывает все миграции и затем запускает их заново. Флаг --seed добавляет наполнение данными:

php artisan migrate:refresh --seed

Полезно при разработке, когда структура БД часто меняется. Опция --force работает и в этой команде.

Проблема: потеря данных при откате. Решение: использовать migrate:fresh (удаляет все таблицы) или создавать резервные копии. В production refresh не рекомендуется.

Как сбросить базу данных и выполнить все миграции заново?

Команда php artisan migrate:fresh удаляет все таблицы (через DROP IF EXISTS) и запускает миграции с нуля:

php artisan migrate:fresh --seed

Быстрее, чем refresh, так как не вызывает down(). Подходит для локальной разработки. Внимание: все данные в БД будут безвозвратно удалены.

Проблема: удаление системных таблиц (например, migrations) приводит к ошибкам. Решение: fresh корректно обрабатывает это, но если БД используется другими приложениями, нужно быть осторожным.

Как выполнить только определенную миграцию?

Флаг --path задает путь к файлу или директории с миграциями:

php artisan migrate --path=database/migrations/2023_01_01_000000_create_users_table.php

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

Проблема: конфликт пакетов, если несколько миграций с одинаковым именем. Решение: добавлять префиксы (например, название пакета) в имя файла миграции.

Как указать другое подключение к базе данных для миграции?

Флаг --database выбирает соединение, указанное в config/database.php:

php artisan migrate --database=mysql_secondary

Полезно для работы с несколькими базами данных (например, чтение/запись, шардинг). Соединение должно быть настроено.

Проблема: ошибка, если соединение не существует. Решение: проверить конфигурацию и убедиться, что драйвер установлен.

Как задать окружение для выполнения миграции?

Флаг --env переопределяет окружение (APP_ENV):

php artisan migrate --env=staging

Команда загрузит соответствующий .env.staging файл. Используется при деплое на разные стейджи.

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

Как создать файл миграции?

Создается через команду make:migration:

php artisan make:migration create_flights_table

Создаст файл с шаблоном. Можно указать таблицу и флаги --create или --table для автоматического заполнения:

php artisan make:migration add_votes_to_users_table --table=users

Проблема: конфликт имен (если миграция уже существует). Решение: использовать уникальные временные метки, которые добавляются автоматически.

Расширенные примеры миграций

Ниже приведены подробные примеры программного кода с пояснениями и результатами выполнения.

Пример 1. Миграция с внешним ключом

Пример
// create_posts_table.php
<?

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

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title', 255);
            $table->text('body');
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}
Выполнение: php artisan migrate
Результат: Создана таблица posts. В ней столбец user_id с внешним ключом на таблицу users. При удалении пользователя все его посты удаляются (cascade).

Проблема: ошибка "Cannot add foreign key constraint". Решение: проверить, что таблица users создана раньше (порядок миграций), и типы столбцов совпадают (bigInteger).

Пример 2. Изменение существующей таблицы (добавление столбца)

Пример
// add_excerpt_to_posts_table.php
<?

class AddExcerptToPostsTable extends Migration
{
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->string('excerpt', 100)->nullable()->after('body');
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropColumn('excerpt');
        });
    }
}
Выполнение: php artisan migrate
Результат: В таблицу posts добавлен столбец excerpt (nullable, после body). При откате столбец удаляется.

Проблема: использование after() требует MySQL. В PostgreSQL этот метод игнорируется. Решение: не использовать after() для кросс-драйверных проектов.

Пример 3. Миграция с использованием raw SQL

Пример
// create_views_count_view.php
<?

use Illuminate\Support\Facades\DB;

class CreateViewsCountView extends Migration
{
    public function up()
    {
        DB::statement("CREATE VIEW post_views AS SELECT post_id, COUNT(*) as views FROM post_views_table GROUP BY post_id");
    }

    public function down()
    {
        DB::statement("DROP VIEW IF EXISTS post_views");
    }
}
Выполнение: php artisan migrate
Результат: Создано представление post_views. Откат удаляет его.

Пример 4. Миграция с сидированием (одновременный запуск)

Пример
// Использование --seed с классом
php artisan migrate --seed --class=PostSeeder
Команда выполнит все ожидающие миграции, затем запустит PostSeeder. Вывод:
Migrating: 2023_01_01_000001_create_posts_table
Migrated:  2023_01_01_000001_create_posts_table (0.02 seconds)
Seeding: PostSeeder
Seeded:  PostSeeder (0.5 seconds)

Пример 5. Откат на определенное количество шагов

Пример
php artisan migrate:rollback --step=3
Откатываются 3 последних батча (группы) миграций. Вывод покажет каждую откатываемую миграцию.
Rolling back: 2023_01_01_000003_add_views_to_posts
Rolled back:  2023_01_01_000003_add_views_to_posts (0.01 seconds)
...

Пример 6. Запуск миграций из пользовательского каталога

Пример
php artisan migrate --path=/app/Modules/Admin/Database/Migrations
Будут применены миграции из указанной директории. Это удобно для модульных структур. Путь должен быть абсолютным или относительно корня проекта.

Пример 7. Имитация миграции (pretend) с выводом SQL

Пример
php artisan migrate --pretend
Пример вывода:
- Create table: posts (id, title, body, user_id, created_at, updated_at)
- Add foreign key: posts.user_id -> users.id

Команда не изменяет базу данных, только показывает планируемые операции.

Пример 8. Программный вызов миграции из кода

Пример
// В любом классе (например, команде Artisan)
\Illuminate\Support\Facades\Artisan::call('migrate', [
    '--force' => true,
    '--seed' => true,
    '--database' => 'mysql_secondary',
]);
$output = \Illuminate\Support\Facades\Artisan::output();
Результат: миграция выполняется программно. Переменная $output содержит текст вывода. Используется в автоматизированных скриптах.

Миграция базы данных в Laravel - comments

En
Php artisan migrate (php)