Cycle ORM: PHP DataMapper ORM and Data Modelling Engine

fixxxer

К.О.
Партнер клуба

Вот, появилась альтернатива Доктрине (дохлый AnalogueORM не считается). На первый взгляд, выглядит интересно.

Comparison with Eloquent and Doctrine
 

fixxxer

К.О.
Партнер клуба
Со составным ключом, думаю, вопрос решаемый ("yet", да и ORM относительно новая).
Хотя я обычно там, где мог бы потребоваться составной ключ, делаю суррогатный PK.

Что касается "вот": если изначально проектируешь с примененем паттерна CQRS и ORM используешь для Write Models, все подобные претензии к ORM моментально исчезают. ;)
 

Yoskaldyr

"Спамер"
Партнер клуба
У меня в закладках уже как пару месяцев - очень приятная вещь.
 

WMix

герр M:)ller
Партнер клуба
Я редизайню по чуть чуть базу, но сам по себе сурогатный PK ни капли не помогает, нужно чтоб он в связях был.
 

Adelf

Administrator
Команда форума
Что касается "вот": если изначально проектируешь с примененем паттерна CQRS и ORM используешь для Write Models, все подобные претензии к ORM моментально исчезают. ;)
Очень сложно эту мысль доводить до людей. Я пользовал доктрину только на запись и она почти нигде не ставила палок в колеса. Начинаешь спрашивать у людей чем она плоха - DQL, кверибилдер и т.д. и т.п.
 

Wolfy-J

Новичок
Вот это пожалуй не стоило писать ) сравнивать новый проект с таким мега-легаси по этим метрикам... не очень красиво как по мне.
Не знали что это покажется некрасивым, убрали из сравнения. Спасибо за фидбек
 

fixxxer

К.О.
Партнер клуба
Очень сложно эту мысль доводить до людей. Я пользовал доктрину только на запись и она почти нигде не ставила палок в колеса. Начинаешь спрашивать у людей чем она плоха - DQL, кверибилдер и т.д. и т.п.
Это инерция мышления. До меня тоже долго доходило.

Да и ORM из-за такого подхода сильно переусложняются.
Если вспомнить, откуда у всех современных Data Mapper-ов растут ноги - а растут они из Hibernate - изначально Hibernate и позиционировалась как "недоORM", которая предназначена прежде всего для персистенции объектов (что и отразилось в названии).

По большому счету, все, что от ORM надо - это "сериализовать" Aggregate Root в РСУБД и "десериализовать" обратно. А именно в РСУБД - чтобы по тем же данным можно было строить индексы, писать select-ы и строить Read Models, иначе бы можно было тупо в какую-нибудь Монгу все сваливать, или, там, в таблички вида (id serial, data jsonb).

Не знали что это покажется некрасивым, убрали из сравнения. Спасибо за фидбек
О, раз вы уж тут! Спасибо за работу, прежде всего.

Хочу чтобы без аннотаций и без автомиграций. Сущности, которыми оперирует ORM - Aggregate Roots, POJO (то есть, кхм, POPO) со связями: могут быть как вложенные сущности, так и Value Objects, и для них нужен гибкий маппинг (что-то по полям разложить, что-то в jsonb сунуть). На каждый Aggregate Root описываются свои правила маппинга, без всякой магии, без аннотаций. В идеале тупо PHP-кодом. Миграции ручные, Lazy load в пень. PK - нативный постгресовый uuid.

Вижу, что все это явно можно сделать, но документация явно ориентирована на "дефолтный" доктриноподобный подход. Я, конечно, сам разберусь, но если ткнете носом в конкретный код или тесты, было бы прекрасно. :)
 

Wolfy-J

Новичок
Хочу чтобы без аннотаций и без автомиграций. Сущности, которыми оперирует ORM - Aggregate Roots, POJO (то есть, кхм, POPO) со связями: могут быть как вложенные сущности, так и Value Objects, и для них нужен гибкий маппинг (что-то по полям разложить, что-то в jsonb сунуть). На каждый Aggregate Root описываются свои правила маппинга, без всякой магии, без аннотаций. В идеале тупо PHP-кодом. Миграции ручные, Lazy load в пень. PK - нативный постгресовый uuid.

Вижу, что все это явно можно сделать, но документация явно ориентирована на "дефолтный" доктриноподобный подход. Я, конечно, сам разберусь, но если ткнете носом в конкретный код или тесты, было бы прекрасно. :)
Привет, сама orm ничего не знает про аннотации, миграции и прокси, это уже часть пакетов annotated, schema-builder, proxy-factory. Для работы только требуется маппинг схема в декларативной форме, все тесты в orm как раз и выполнены с таким подходом:
https://github.com/cycle/orm/blob/master/tests/ORM/MapperTest.php#L43 (простой маппер)
https://github.com/cycle/orm/blob/master/tests/ORM/ManyToManyRelationTest.php#L78 (many-to-many)
и т.д.

Константы для декларации схемы:

Тут можно глянуть на константы необходимые для настройки связей:

Вы можете использовать schema-builder который упрощает декларирование схемы (+ валидация и нормализация):

+ дока: https://github.com/cycle/docs/blob/master/advanced/schema-builder.md

Но это не обязательно, потому что в целом она довольно легко читается.

В качестве примера могу привести работу со схемой определенной вручную без энтити (мапает в stdClass):
https://github.com/cycle/docs/blob/master/advanced/dynamic-schema.md

P.S. Для автогенерации UUID понадобится свой маппер (https://github.com/cycle/docs/blob/master/advanced/uuid.md), UUID можно хранить в бинарном виде.
 

fixxxer

К.О.
Партнер клуба
Не, ну смотря что. Бывает уместно (см. тот же Angular).

А вот засорять доменные сущности инфраструктурными деталями мне совсем не нравится. Какое ей дело до того, что там в базе?
 

Вурдалак

Продвинутый новичок
Я думаю, в относительном будущем появятся такие штуки, которые уже сложно назвать ORM, которые будут все состояние aggregate root'а записывать в JSON (там тупо конфигурации меньше, особенно с PHP 7.4, и уже нет того самого object-relational impedance mismatch). Проблема индексов уже даже в MySQL решена: https://www.compose.com/articles/mysql-for-json-generated-columns-and-indexing/ А уж если какой-нибудь Postgres, то там вообще можно прикрутить проверку JSON schema.

Read models же можно строить из событий, либо используя что-то типа AutoMapper для PHP.
 

fixxxer

К.О.
Партнер клуба
Собственно уже сейчас так можно делать (банально в том же постгресе uuid + jsonb). Индексировать по внутренностям jsonb уже можно, constraint-ы делать (с оговорками) можно. Проблема начинается с read models - со всякими джойнами и группировками, там все еще не очень хорошо, временами сваливается в фулскан, плюс foreign key constraints не сработают. Но, да, дело ближайшего будущего (а с рядом оговорок можно и сейчас).

Если полноценный Event Sourcing, то, да, можно из событий строить. Но полноценный ES далеко не всегда нужен, а оверхед на него (в смысле времени на разработку) существенный, чтобы делать его "просто чтобы был".
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
По поводу ES: у меня все модели могут полностью перестраиваться из событий (технически, на уровне самой модели), но не все события хранятся вечно. То есть часть таких aggregate root'ов пересистятся как снепшоты в ES.

Мне кажется, времени на разработку сейчас будет много просто из-за отсутствия нужных инструментов. Я лично уже практически не чувствую никаких проблем.

Тут не просто «чтобы был», а, во-первых, реально перестраивается мышление и отказаться от событий становится уже сложно; во-вторых, модели получается унифицированными (пишутся в ES-стиле одинаково) и писать их реально легко; в-третьих, одна из самых больших проблем — мне кажется, ты не сможешь сделать полноценную сагу, если не будешь пересистить события в той же транзакции, что и состояние aggregate root. То есть хотя бы временно, но события нужны.
 

Вурдалак

Продвинутый новичок
Всякие Тарантулы и Debezium'ы, кстати, читают бинлог MySQL, а это очень напоминает event stream, только технический. Я думаю, сложности с read models — вопрос времени.
 

Вурдалак

Продвинутый новичок
По большому счету, все, что от ORM надо - это "сериализовать" Aggregate Root в РСУБД и "десериализовать" обратно. А именно в РСУБД - чтобы по тем же данным можно было строить индексы, писать select-ы и строить Read Models, иначе бы можно было тупо в какую-нибудь Монгу все сваливать, или, там, в таблички вида (id serial, data jsonb).
А, ну так ты сам в этой теме то же самое говорил. Мысли дураков совпадают.
 
Сверху