Миграции и фикстуры

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

  • 00:00:46 Автовалидация маппинга сущностей и схемы базы данных
  • 00:02:55 Создание и изменение таблиц командами schema-tool
  • 00:08:07 Управление схемой через миграции
  • 00:13:33 Обзор пакета миграций Phinx от Cake PHP
  • 00:15:53 Подключение Doctrine Migrations
  • 00:17:25 Обзор консольных команд
  • 00:19:18 Настройки параметров миграций
  • 00:21:22 Транзакции для схемы в PostgreSQL
  • 00:23:39 Кастомное подключение команд
  • 00:24:43 Автогенерация миграции
  • 00:25:52 Подсказки для кастомных типов данных
  • 00:29:41 Проблема CREATE SCHEMA public
  • 00:31:26 Применение изменений
  • 00:32:47 Исправление SCHEMA public
  • 00:36:15 Добавление команд в Makefile
  • 00:37:24 Ожидание работы БД через wait-for-it в Docker
  • 00:42:30 Запуск миграций в Production
  • 00:47:04 Необходимость ручного исправления миграций
  • 00:49:20 Заполнение таблиц демонстрационными данными
  • 00:50:30 Подключение Doctrine Data Fixtures
  • 00:55:17 Загрузка фикстур в БД в консоли
  • 00:57:14 Консольная команда загрузки
  • 01:00:53 Обзор результата
  • 01:02:40 Удобство фикстур для команды программистов
Скрытый контент (код, слайды, ...) для подписчиков. Открыть →
Дмитрий Елисеев
elisdn.ru
Комментарии (36)
Arunas

Спасибо, отличный урок.

Ответить
Igor

Дмитрий, не задумывались ли вы над созданием мастер класса по Java/Spring?

Ответить
Дмитрий Елисеев

Пока не задумывались.

Ответить
Sergei

У меня коллега по работе прокомметировал ваш конфиг доктрины, говорит: я первый раз вижу, чтобы на симфони кто то конфиг доктрины описывал в php, а не в yml :)

Ответить
Дмитрий Елисеев

В Symfony 2 и 3 это было популярно, но сейчас в документации больше склоняются к аннотациям.

Ответить
Дмитрий Елисеев

А, вы про сам конфиг подключения в Yaml, а не про конфиги мэппинга в аннотациях или Yaml.

Тогда да, в Symfony все конфиги по умолчанию в Yaml, включая доктриновские. И их там разбирает сам DoctrineBundle. Но мы используем Doctrine напрямую без Symfony-бандла, поэтому всё объекты в контейнере собираем сами.

Ответить
Руслан

Дмитрий, здравствуйте, вопрос немного не по теме - если на симфони какие-либо готовые системы Single Sign On Authentication? Если нет, подскажите в какую сторону смотреть, спасибо

Ответить
Igor

А почему вы используете run - - rm, а не exec, как раньше? Есть какое-то преимущество?

Ответить
Дмитрий Елисеев

Работу run --rm удобнее отслеживать и он более соответствует философии запуска процесса.

Ответить
Дмитрий Ориховский

Привет. У себя делаю команду migrations:migrate выдает ошибку:

WARNING! You are about to execute a database migration that could result in schema changes and data loss. Are you sure you wish to continue? (y/n)

Aborted.

Пробую migrations:migrate --no-interaction тоже ошибка, команда не воспринимает аргументы

Ответить
Arunas

здравствуйте, сегодня при make init, (при docker-compose run --rm api-php-cli composer update, а не install) все библиотеки обновились успешно, тесты также прошли, но миграции застряли: ошибка: WARNING! You are about to execute a database migration that could result in schema changes and data loss. Are you sure you wish to continue? (y/n) Aborted. http://www.arvidija.lt/Galerija/290.jpg

Ответить
Дмитрий Ориховский

У меня тоже самое. (:

Ответить
Дмитрий Ориховский

Смог запустить через bin/app.php. Вот команда:

docker-compose run --rm api-php-cli php bin/app.php --ansi migrations:migrate --no-interaction

Я погуглил немного и нашол что это может быть баг в php7.4. Но это неточно :)

Ответить
Дмитрий Елисеев

В Symfony 5.0.5 они убрали неявную неинтерактивность. Добавьте пока флаг явно:

... composer app migrations:migrate -- --no-interaction
Ответить
Arunas

в Makefile с composer app migrations:migrate -- --no-interaction все равно не работает, а docker-compose run --rm api-php-cli php bin/app.php --ansi migrations:migrate --no-interaction - миграций действует и фикстуры проходит (здесь насчет composer update)

Ответить
Дмитрий Елисеев

Обсуждаем в issues. Уже есть Pull Request с фиксом.

Откатитесь пока назад на 5.0.4.

Ответить
Arunas

спасибо, понял

Ответить
Олег

Дмитрий, добрый день! Вопрос не по уроку Подскажите пжл, как в psalm описать stdClass, как мы описывали массив с динамическими значениями? Всю документацию и issue на github перерыл, так и не понял как это сделать. Если вы в курсе, подскажите пжл

Ответить
Дмитрий Елисеев
@psalm-var object{foo:string}
Ответить
Влад

Здравствуйте Дмитрий! Помогите пожалуйста разобраться со след проблемой: С целью немного разобраться с Doctrine и миграциями пробовал дописывать нотации и генерировать новые миграции по разнице в коде. И когда я запускаю просто docker-compose run --rm api-php-cli composer app migrations:migrate не примененные миграции находятся и все применяется без проблем. Но если попробовать запустить например docker-compose run --rm api-php-cli composer app migrations:execute -- --dry-run Version20201106201722 или -- --down Version20201106201722 - вылетает ошибка что файл миграции не найден. Я перепробовал массу вариантов - указывал полный путь /app/src/Data/Migration/Version20201106201722 и пути из migrations:status из пространства имен, в том числе и из контейнера запустив docker-compose run --rm api-php-cli bash - результат один и тот же - файл миграции не найден! Собственно вопрос - как в случае применения миграций в ручную через migrations:execute правильно указать путь в файлу миграции? Спасибо!

Ответить
Влад

Возможно кому пригодиться - указывать путь необходимо как строку с пространством имен: например для --down это: docker-compose run --rm api-php-cli composer app migrations:execute -- --down 'App\Data\Migration\Version20201106201722'

Ответить
Дмитрий Елисеев

Указывайте просто номер:

app migrations:execute 20201106201722
Ответить
Сергей

Добрый день!
Застрял с фикстурами. не принимает тип mixed

PHP Fatal error:  Uncaught TypeError: Return value of App\Auth\Entity\User\IdType::convertToDatabaseValue() must be an instance of App\Auth\Entity\User\mixed, string returned in /app/src/Auth/Entity/User/IdType.php:16

Не пойму, где напортачил.
Сверял код с исходным кодом все ок.
Подскажите плиз, где косяк?

Ответить
Дмитрий Елисеев

Псевдотип mixed появился только в PHP 8.0

Ответить
Сергей

Спасибо

Ответить
Sam

Подскажите плиз!
Mapping проходит успешно. но при запуске любой команды типа

$ docker-compose run --rm api-php-cli composer app orm:validate-schema

In AbstractPostgreSQLDriver.php line 88:

An exception occurred in driver: SQLSTATE[08006] [7] FATAL:  password authentication failed for user "root"  

не могу найти, где изменить юзера, в yml объявлен POSTGRES_USER: app, в PHPStorm всё работает.

Ответить
Дмитрий Елисеев

Укажите DB_USER в environments самого api-php-cli

Ответить
Sam

Дмитрий, это как раз указано в docker-compose.yml

    api-php-cli:
        build:
            context: api/docker
            dockerfile: development/php-cli/Dockerfile
        environment:
            APP_ENV: dev
            APP_DEBUG: 1
            DB_HOST: api-postgres
            DB_USER: app
            DB_PASSWORD: secret
            DB_NAME: app

Через PHPStorm доступ к базе данных нормальный, могу работать с ней и запускать SQL, а через командную строку нет.

Ответить
Sam

UPDATE: проблема решилась добавлением DB_URL в api-php-cli environment

Ответить
Дмитрий Елисеев

Мы от общего DB_URL в итоге перешли к указанию отдельных параметров DB_HOST, DB_USER и т.п.

Не используйте оба подхода одновременно.

Ответить
slo_nik

Добрый вечер, Дмитрий.

Можно ли как-то исключить из команды migration:diff некоторые таблицы, которые создавались до подключения doctrine и наследуются от ActiveRecord?

Нужные таблицы, в которых надо отследить изменения начинаются с amqp_

Пробовал использовать фильтр, но результата не дало.

mi:diff --filter-expression='~^(?!amqp_)~' -n
Ответить
slo_nik

Проблема решилась.

Первая причина была в том, что при вызове консольной команды надо указывать два дефиса, тогда команда будет правильно воспринимать --filter-expression

composer app -- mi:diff --filter-expression='~^(?!amqp_)~' -n

Вторая была в pattern-е, необходимо изменить на такой

'~^(?=amqp_)~'
Ответить
Дмитрий Елисеев

Чтобы не прописывать это каждый раз флагами можно настроить игнорирование глобально:

$config->setSchemaAssetsFilter(static function (string|AbstractAsset $assetName): bool {
    if ($assetName instanceof AbstractAsset) {
        $assetName = $assetName->getName();
    }

    return (bool) preg_match('~^(?=amqp_)~', $assetName);
});
Ответить
slo_nik

Именно так и сделал, спасибо.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий

Или войти через:

Yandex
MailRu
GitHub
Google