Создание БД и установка Doctrine ORM

Подключение базы данных в Docker. Конфигурирование через переменными окружения. Плюсы и минусы подходов DB-First и Code-First. Обзор Doctrine ORM. Установка библиотеки и регистрация EntityManager в DI-контейнере.

  • 00:00:06 Обзор архитектуры
  • 00:02:33 Подходы DB First и Code First
  • 00:05:35 Готовые ORM
  • 00:06:40 Выбор СУБД
  • 00:08:16 Поднятие PostgreSQL в Docker
  • 00:11:03 Подключение к БД из PhpStorm
  • 00:12:24 Установка pdo_pgsql для PHP
  • 00:14:09 Установка Doctrine ORM
  • 00:15:35 Создание подключения
  • 00:17:08 Конфигурирование сущностей
  • 00:20:06 Работа с EntityManager и UnitOfWork
  • 00:23:45 Подключение Doctrine ORM
  • 00:27:25 Стратегия именования полей
  • 00:28:53 Параметры подключения
  • 00:30:59 Настройки для разных окружений
  • 00:32:15 Конфликт доступа к папке var
  • 00:35:12 Подключение готовых консольных команд
  • 00:39:17 Индивидуальное подключение команд
  • 00:41:59 Проблема склейки конфигураций
  • 00:43:12 Конфигурация с Laminas Config Aggregator
  • 00:46:01 Обзор результата
Скрытый контент (код, слайды, ...) для подписчиков. Открыть →
Дмитрий Елисеев
elisdn.ru
Комментарии (31)
Arunas
2020-02-20 16:41

Спасибо.

Ответить
Роман
2020-02-20 19:31

Смотрю на это все и не понимаю, как один человек столько может знать не только в теории но и на практике.

Ответить
Александр
2024-07-04 13:28

и не говори )) я все еще пытаюсь все это дело с бд , запустить второй день

Ответить
Arunas
2020-02-20 20:02

Какой connection string url будет, если БД устроинна с наруже, не в докере? Если можете, напишите, пожалуйста (надо как то корегировать api/config/common/doctrine.php или нет).

Ответить
Дмитрий Елисеев
2020-02-21 10:54

Тогда вместо хоста api-postgres указывают IP-адрес сервера с БД.

Ответить
Arunas
2020-02-21 11:37

спасибо.

Ответить
Arunas
2020-02-24 12:47

Как правильно делаются backup БД при работе в докерском окружении? Можно этот backup БД делать с кроном, какая практика с backup БД? (если можете, пакажите пример) Влиялить или нет на производительност сайта или надёжность данных backup БД?

Ответить
Дмитрий Елисеев
2020-02-25 09:11

Можно обычным вызовом pgdump внутри контейнера:

docker-compose exec api-postgres pgdump ...
Ответить
Роман
2020-05-21 10:02

Добрай день Дмитрий,спасибо за качественный материал, вопрос не по теме, но будет ли в курсе рассмотрена тема поднятие нескольких бд master-slaves (в частности для продакта), и работа с ними, а также разные типы блокировки postgresql ? Заранее блогадарю

Ответить
Дмитрий Елисеев
2020-05-22 06:35

Репликации не будет. Но для этого можно взять образ bitnami/postgresql и настроить как в примере Setting up a streaming replication.

При работе с Doctrine рассмотрим оптимистическую блокировку. Во многих случаях её будет достаточно.

Ответить
Олег
2020-06-02 20:14

не очень понятно, почему на 39:25 в консоль не вылетает ошибка, ведь array_merge_recursive сформирует вот такое значение под ключем cache_dir => array('DIR из common', 'null из dev'), а потом передаст это значение в createAnnotationMetadataConfiguration, и упадет в фаталом, что ждет строку, а не массив Как так?

Ответить
Олег
2020-06-02 20:23

array_replace_recursive - не усмотрел

Ответить
Андрей
2020-06-24 21:49

Вопрос о правах записи в одну и ту же папку кешу между контейнерами php-cli и php-fpm. Почему мы сделали запись в разные папки только для dev окружения, а для продакшена оставили без изменений? Ведь на продакшене такая же проблема будет...

Ответить
Дмитрий Елисеев
2020-06-28 16:58

На продакшене не будет. Там контейнеры php-cli и php-fpm пишут каждый в свою внутреннюю папку, а не как в dev в одну общую, примонтированную через volume.

Ответить
Олег
2020-07-01 11:17

Дмитрий, поясните пжл, что это за volumes:

 api-postgres:

Что это значит и где по факту хранятся данные?

Ответить
Дмитрий Елисеев
2020-07-03 19:35

Значит, что создаётся вольюм с настройками по умолчанию.

В случае docker-compose хранятся в папке /var/lib/docker/volumes/auction_api-postgres

Ответить
elmut
2020-10-24 17:35
<?php

use Shared\Domain\ValueObjects\UserId;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="auth_users")
 */
class AuthUser
{
    /**
     * @ORM\Column(type="user_id")
     * @ORM\Id
     */
    private UserId $id;

    /**
     * @ORM\OneToOne(targetEntity="UserPassword", cascade={"persist", "remove"}, mappedBy="userId")
     */
    protected ?UserPassword $joinPassword = null;
}

/**
 * @ORM\Entity()
 * @ORM\Table(name="auth_user_password")
 * @ORM\HasLifecycleCallbacks()
 */
class UserPassword
{
    /**
     * @ORM\Column(type="user_id")
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="AuthUser", inversedBy="joinPassword")
     */
    private UserId $userId;

    /**
     * @ORM\Column(type="string")
     */
    private string $login;
}

Дмитрий, а как сделать так что бы AuthUser и UserPassword у них был один id?

Ответить
Дмитрий Елисеев
2020-10-24 21:06

Со связью @ORM\OneToOne никак. Только вручную без неё.

Ответить
Алексей
2020-12-20 15:59

Дмитрий, а есть планы в одном из будущих учебных проектов использовать Cycle ORM? Было бы любопытно.

Ответить
Дмитрий Елисеев
2020-12-22 06:42

Может будет если будем что-то запускать в RoadRunner.

Ответить
Николай
2021-07-04 07:09

Дмитрий, добрый день! Команда

docker-compose run --rm api-php-cli composer app

выдает ошибку

PHP Fatal error:  Uncaught Error: Class "Doctrine\Common\Cache\ArrayCache" not found in /app/config/common/doctrine.php:33

ArrayCache и FilesystemCache в doctrine/orm 2.9 больше не доступны?

Ответить
Николай
2021-07-04 11:24

Проблема решена. Нашел коммит от 12 мая "Migrated to PSR cache". Все заработало.

Ответить
bogdan
2021-08-19 19:04

спасибо) как раз таже проблема

Ответить
maxbrown1
2021-12-27 19:36

спасибо, помогло)

Ответить
Sam
2021-09-21 16:07

Дмитрий, при запуске make init получаю слудущую ошибку:

ERROR: for api-postgres  Get "//registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

Подскажите. что это может быть?

Update: в файле /etc/resolv.conf добавить вначале

nameserver 8.8.8.8

nameserver 8.8.4.4

nameserver 127.0.0.53

Ответить
Дмитрий Елисеев
2021-09-28 17:06

Да, это может быть проблема подключения к реестру докерхаба. Свежие DNS могут помочь.

Ответить
Максим (@myks92)
2021-11-12 10:26

Доброго дня! Возник вопрос по оптимистической блокировке в DDD при использовании Doctrine.

Суть. Мы имеем корень агрегата с полем $version и аннотацией @ORM\Version(), которое нужно для оптимистической блокировки. При изменении сущности корня агрегата поле version увеличивается на 1, а вот при изменении вложенных сущностей вроде @ORM\ManyToMany(targetEntity="Role") поле версии у агрегата не увеличивается на 1. Из-за чего оптимистическая блокировка работает не правильно.

Почитав документацию на этот счёт сама доктрина нам предлагает пойти путём добавления собственного поля агрегации

В Java видел такое решение, как принудительное изменение версии OPTIMISTIC_FORCE_INCREMENT. В доктрине такого не нашёл в текущих версиях, однако в 2015 году в доктрине присутствовала такая блокировка, затем её убрали

Подскажите, пожалуйста, как решается данная проблема с doctrine при изменении вложенных сущностей?

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

Ответить
Максим (@myks92)
2021-11-20 20:46

В продолжении комментария… Описал проблему и её решение на Хабр.

Так же решил пойти дальше — внёс вклад в DoctrineExtensions написал issue и добавил своё решение в виде pull-request. Надеюсь, что решение окажется удачным и его одобрят.

Если будет желание и время — присоединяйтесь. Не судите строго)

Ответить
Дмитрий Елисеев
2021-11-26 07:48

Да, проблема есть. Обычно решал именно через обновление своего поля $updatedAt.

Ответить
slo_nik
2024-01-31 00:28

Доброй ночи, Дмитрий.

Возникла непонятная для меня проблема.

В Dockerfile для fpm, cli устанавливаю pgsql, всё по Вашим примерам сделано.

RUN apk add --no-cache postgresql-dev bash coreutils \
&& docker-php-ext-configure pgsql --with-pgsql=/usr/local/pgsql \
&& docker-php-ext-install pdo_pgsql

Проблема заключается в том, что в зависимости от версии alpine существенно меняется размер итогового образа. Например, при версии php:8.1-fpm-alpine3.19 размер prod образа fpm будет 795MB, а при версии php:8.1-fpm-alpine3.16 размер будет составлять 594MB. При этом директория app весит 197MB, всё остальное приходится в на /usr/lib, что тоже много. Получается, что мои итоговые prod образы весят от 700 до 900 MB при версии alpine 3.19

Я пробовал заменять postgresql-dev на libpg-dev, тогда размер образов при смене версии alpine остаётся без изменений +-5MB

Скажите, при использовании postgresql-dev такой большой разбег по размерам образов нормальное поведение или нет?

Ответить
Дмитрий Елисеев
2024-07-29 16:44

Да, можно теперь поменять на libpq-dev. Так будет экономнее.

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

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

Yandex
MailRu
GitHub
Google