Работа с миграциями в проектах Laravel
Основы миграций базы данных в Laravel
Как применить все новые миграции в базе данных?
Команда php artisan migrate запускает все миграции, которые ещё не были выполнены. Миграции находятся в директории database/migrations. Каждая миграция содержит методы up() (применение) и down() (откат). После выполнения создается таблица migrations, отслеживающая уже примененные миграции.
php artisan migratePhp 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 содержит текст вывода. Используется в автоматизированных скриптах.