Как стать автором
Обновить

Комментарии 68

Дежавю. Лет семь назад такое про PHP писали, ну прям один в один.

p.s. Откажитесь от советчиков отказываться. Пишите код.
То чувство, когда ты уже лет пять используешь в своей работе ORM, и за всё это время только больше полюбил его, и вдруг видишь какую-то статью, в которой говорится, что всё это неправильно и не работает. Серьёзно чтоли?) Как я жил-то все эти годы?)

В итоге, автор этого ROM'а всё равно приходит к созданию всяких TasksRelation-классов в своём туториале для получения нужных данных из определённой таблицы в БД. Разница-то совсем небольшая…
Особенно весело такие статьи должно быть читать создателям суперуспешных ORM'ов типа hibernate и SQLAlchemy.
Ох, благодаря этой статье я наконец понял, почему гемы ROM и «DataMapper» такие странные DataMapper'ы…
Что-то ни о чем… Ожидал большего от такого громкого заголовка…
Я совершенно не понял что хотел сказать автор в этой статье. Посмотрел его код. Автор написал еще одну orm, назвал это не-orm, и объявил все остальные orm неправильными.
Не согласен с автором. Использую Django ORM(py) на всех проектах и ужасно доволен. Проектирование бд — несколько минут, все запросы через ООП — не задумываюсь вообще.
first_oleg = Users.objects.filter(name__contains='Олег').sort_by('-date')

ООП — не панацея. Это упрощение/улучшение читабельности/ускорение разработки. По факту в ORM те же Select'ы просто оборачиваются оболочкой и мы передаем в функцию переменные и что с ними делать.

Am i wrong?
>Am i wrong?
Ну чутка да, это далеко не всегда именно ускорение разработки, временами нужно писать всякого сильно больше.
Однако если хотябы частично делать всякое правильно, то это упрощает поддержку кода, уменьшает количество багов и позволяет новым или сторонним разработчикам быстрее включиться в разработку. Ну типа когда дофига разных таблиц и хитрых связей между ними можно это все дело не держать особо в голове. А еще есть хайлоад, а там вообще все не так однозначно.
Только не говорите мне что вы базу генерите из объектов :)
А что в этом такого?
Как вариант в том, что в таком случае классическая реляционная бд как бы не нужна.
Всё хранить в памяти? Или, прости господи, в Монге? )
Я написал «как вариант», суть в том что странно использовать навороченную бд и использовать 1% ее функционала, как обычно бывает в довольно большой части случаев, при этом писать прокладку, которая абстракции разворачивает в классические таблицы.
А что вам так Монга не нравится?)
Использовать навороченные СУБД приходится потому, что по какому-то странному сочетанию обстоятельств, навороченные ещё и примитивные задачи решают лучше, чем ненавороченные.

Неприятный личный опыт.
Выбор СУБД к генерации схемы из объектов никаким образом вообще не относится.
Что вы имеете ввиду? Что пофиг для чего схему генерить для pg или mysql?
Или про то что у вас есть волшебная генерилка схем для любых объектов и для любых хранилищ?
Что пофиг для чего схему генерить для pg или mysql?

Да

есть волшебная генерилка схем для любых объектов и для любых хранилищ

Не для любых хранилищ.
Doctrine умеет в монго и достаточно большой список реляционок.

>>Что пофиг для чего схему генерить для pg или mysql?
>Да
Тут надо было написать «спасибо кэп», но самое смешное, что если писать свою генерилку, то уже не так все однозначно.

>Doctrine умеет в монго и достаточно большой список реляционок.
Есть опыт на доктрине поднимать успешный проект где 500+ различных типов сущностей, между ними пара тысяч связей, при этом чтение/запись 50/50 и запросов к сущностям по десятку тысяч в секунду и более? Поделитесь, думаю будет многим интересно.

что если писать свою генерилку

Что есть «своя генерилка»?

Есть опыт на доктрине поднимать успешный проект где 500+ различных типов сущностей, между ними пара тысяч связей, при этом чтение/запись 50/50 и запросов к сущностям по десятку тысяч в секунду и более?

Что есть «успешный проект»?
Нет, такого опыта нет, но не думаю, что это будет большой проблемой при грамотном архитектурном решении (опять же, использовать doctrine orm или нет — это чистая архитектурка, для сферического «успешного проекта» в вакууме я ничего сказать не могу)
У Doctrine ORM, как у каждого инструмента, есть своя область применения. Скорее всего для подобных задач она не очень подходит (тут и PHP в принципе может не очень подходить), особенно, если задача оркестрации кластера (это же не один инстанс РСУБД держит минимум 5000 write RPS?) возложена на приложение, а не на сторонние инструменты, скрывающие мастер-сервера за одной точкой входа.

Тем более следует учитывать, что возможности создания/изменения схемы у Doctrine ORM — это лишь инструмент для ускорения начальных стадий разработки, а не основная ответственность библиотеки. Для большого спектра задач этих возможностей достаточно и для продакшена, так чтобы полностью отдать контроль за схемой (часто хватает даже кроссвендорных возможностей, иногда вводятся вендорные расширения, с которыми Doctrine работает как со строками, передаваемыми в СУБД с минимальным «пониманием» их семантики типа «это какое-то описание типа столбца») Doctrine, но на сложных высоконагруженных проектах максимум можно использовать инструментарий миграций.

С другой стороны, Doctrine легко позволяет как использовать чистый «ручные» sql для выборок объектов, таки маппить как минимум ридонли (то что сам использую в продакшене) объекты домена на такие псевдотаблицы как view, table function и т. п., а ридонли свойства объектов на вычисляемые столбцы.
Это как вы такой вывод сделали?
В чем, по-вашему, принципиальное различие между хранением схемы в виде sql ddl кода и orm нотации?
>Это как вы такой вывод сделали?
Из сугубо практического опыта.
>В чем, по-вашему, принципиальное различие
Странный вопрос, ну банально же, sql это sql а orm нотация такая как захотите :D
И как же использование orm нотации автоматически делает ненужными возможносности классических РСУБД? Какая, по-вашему, связь между способом описания схемы данных и, например, необходимостью иметь транзакции?
Во-первых я написал «как вариант», это сильно отличается от какого либо категоричного заявления.
И как я писал выше, в большинстве случаев там где есть генерация и тд — используется минимум всех возможностей субд, и использование субд выглядит странным и неоправданым, т.к. на данный момент существует огромное множество различных хранилищ на любую вкус цвет и запах.

> Какая, по-вашему, связь между способом описания схемы данных и, например, необходимостью иметь транзакции?
У вас очень странные вопросы, из серии «какая по вашему связь между теплым и зеленым», я не знаю какой вы ответ хотите увидеть.
в большинстве случаев там где есть генерация и тд — используется минимум всех возможностей субд

Это смотря что вкладывать в понятие «минимум всех возможностей субд». С таким же успехом можно заявить, что большинство проектов использующих только raw sql используют минимум возможностей субд. Непонятно как это относится к обсуждаемой теме.

У вас очень странные вопросы, из серии «какая по вашему связь между теплым и зеленым»

Ну собственно изначальный посыл, что если используется генерация ddl, то вам не нужна РСУБД как раз и есть про «теплое и зеленое».
Напоминаю ORM является текущей абстракцией и стоит идти от меньшего к большему, а не наоборот. Да и по хорошему сначала проектируем БД, а уже потом делаем объекты. Иначе можно больно наступить на грабли :)
>Напоминаю ORM является текущей абстракцией и стоит идти от меньшего к большему, а не наоборот.
>Да и по хорошему сначала проектируем БД, а уже потом делаем объекты.
Ну как бы что получается, у нас есть бизнес процессы, мы знаем какие для него нужны абстракции. Но. у нас есть база и у нее есть ограничение, поэтому мы пытаемся создать базу, ориентированную на бизнес, в результате получаем странные абстракции в коде.
С другой стороны можно создать годные абстракции в коде и подумать о их хранении позже, тогда получается некая монструозная прокладка, т.к. в классическую бд их просто так положить не получается.
Вот автор статьи и пишет в целом про то что ОРМ это какая-то хренотень в результате и что не надо парить мозг, все равно идеально не получится.
Ну как бы что получается, у нас есть бизнес процессы, мы знаем какие для него нужны абстракции. Но. у нас есть база и у нее есть ограничение, поэтому мы пытаемся создать базу, ориентированную на бизнес, в результате получаем странные абстракции в коде.

Если у вас получаются странные абстракции в коде, то вы явно как-то не так спроектировали БД.

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

Обычно получается не монструозная прокладка, а весьма тормозная схема, которую СУБД прожевывает с трудом. В итоге приложение жрет больше ресурсов чем надо и работает медленно. Так-как не были учтены особенности СУБД. Из-за этого кстати был рост популярности NoSQL решений. Там типа такой проблемы нет
>Если у вас получаются странные абстракции в коде, то вы явно как-то не так спроектировали БД.
Не всегда получается бизнес-процессы ужать в рамки БД, мир он как бы не идеальный. А проекты бывают еще и очень большими с точки зрения типов сущностей данных.

>Обычно получается не монструозная прокладка, а весьма тормозная схема, которую СУБД прожевывает с трудом.
Тормозная схема получается если тупить. Если же все делать учитывая возможности (особенности в целом уже мелочь) СУБД, ну хотя бы банально знать о том что такое индексы и знать что не все запросы одинаковы быстрые, то как раз, через учет этого прокладка в большом проекте может стать монструозной.

>Из-за этого кстати был рост популярности NoSQL решений. Там типа такой проблемы нет.
NoSQL они как бы разные бывают, я бы не стал так категорично решать что рост их популярности связан с этим.
Вот можно взять абстрактную задачу с системой, в которой есть множество документов, с различными наборами полей. Ее реально намного проще и дешевле реализовать, на Монго, чем например на MySql

Не всегда получается бизнес-процессы ужать в рамки БД, мир он как бы не идеальный. А проекты бывают еще и очень большими с точки зрения типов сущностей данных

Честно скажу, если не ужимается, то у вас что-то не так с формализацией.

Тормозная схема получается если тупить. Если же все делать учитывая возможности (особенности в целом уже мелочь) СУБД, ну хотя бы банально знать о том что такое индексы и знать что не все запросы одинаковы быстрые, то как раз, через учет этого прокладка в большом проекте может стать монструозной.

В том то и фишка, что как только все это вы начинаете учитывать, становится проще начать проектирование решения с базы данных :)

NoSQL они как бы разные бывают, я бы не стал так категорично решать что рост их популярности связан с этим.

Это один из факторов. Типа зачем учить эту скучную теорию работы с РСУБД если можно взять и просто положить объект как он есть?

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

Ровно до того момента, как вам потребуется построить аналитику или сделать отчеты. Плюс очень часто встречаются ошибки при проектировании, а ошибиться там весьма просто и внезапно выбор NoSQL перестает вывозить.
>Честно скажу, если не ужимается, то у вас что-то не так с формализацией.
С формализацией чего? бизнес процессов? В том то и дело, что в сложных случаях либо база красивая, но абстракции в коде не очень, либо абстракции годные, но в базе их сложно хранить и если в таких случаях использовать какой-то полу-универсальный ОРМ может начаться треш и угар.

>В том то и фишка, что как только все это вы начинаете учитывать,
>становится проще начать проектирование решения с базы данных :)
И у вас особенности базы данных начинают влиять на архитектуру проекта, далее на его бизнес процессы, а далее как часто бывает манагер слышит «ой блин, это нереально переделать»

>Типа зачем учить эту скучную теорию работы с РСУБД если можно взять и просто положить объект как он есть?
Чего там учить? Основ в виде тонкой книжки, которая читается за вечер хватает на 95%+ задач, давай те уж друг перед другом не будем выпендриваться тем как сложно жить программистам :)

>Это один из факторов.
ну так да, однако сначала вы сказали что «Из-за этого кстати был рост», слишком категорично вообщем

>Ровно до того момента, как вам потребуется построить аналитику или сделать отчеты.
Аналитика отчеты это статистика? Ну ее как бы и хранить нужно в каких-нить колоночных субд.
>Плюс очень часто встречаются ошибки при проектировании,
>а ошибиться там весьма просто и внезапно выбор NoSQL перестает вывозить.
Пример хоть приведите, а то както получается по вашим словам что в noSQL все так круто и нет ошибок которые потом оборачиваются принудительной эпиляцией разных частей тела. А вообще я не за noSQL, не надо меня убеждать что оно не очень, мне пофигу, юзаю когда считаю что подходит больше чем всякое другое.
В том то и дело, что в сложных случаях либо база красивая, но абстракции в коде не очень, либо абстракции годные, но в базе их сложно хранить и если в таких случаях использовать какой-то полу-универсальный ОРМ может начаться треш и угар.

А тут уже выбираем что нам шашечки или ехать.

И у вас особенности базы данных начинают влиять на архитектуру проекта, далее на его бизнес процессы, а далее как часто бывает манагер слышит «ой блин, это нереально переделать»

Вот ни разу не было. И обычно если хотят что-то такое что вот в базу ложится только со скрипом, то что-то в запросе не так и часто можно предложить как сделать лучше.

Чего там учить? Основ в виде тонкой книжки, которая читается за вечер хватает на 95%+ задач, давай те уж друг перед другом не будем выпендриваться тем как сложно жить программистам :)

Окей что такое третья нормальная форма Бойса-Кодда? :)

Аналитика отчеты это статистика? Ну ее как бы и хранить нужно в каких-нить колоночных субд.

Это все прекрасно. Но данные то вы откуда выгружать будете?

Пример хоть приведите, а то както получается по вашим словам что в noSQL все так круто и нет ошибок которые потом оборачиваются принудительной эпиляцией разных частей тела.

Да легко habrahabr.ru/post/231213

А что в этом такого?
Золотой молоток detected — Функциональное программирование
Не хватает примеров. А то, что я представил сам, на революцию не тянет и вообще выглядит как костыль.
>>Откажитесь от ORM.
Откажитесь от тех, кто призывает вас отказываться от чего-либо, потому что не смог понять это.
Если что, автор разработчик одной из популярных ОРМ — он не смог понять, что разработал?
Если некто, возможно умный и популярный в некоторых кругах, написал хрень она от его умности и популярности менее хренью не станет.
Впрочем хрень тут вообщем-то в деталях и если некоторые термины заменить несколько другими, то смысл и эмоциональная составляющая поменяются.
Возможно не правильное понимание автора из-за перевода, похорошему надо бы почитать оригинал, ну тем кому еще не надоело решать надуманные проблемы.
А можно узнать, какой именно?

Для ruby, насколько я помню, ORM уровня Doctrine ещё не запилили (хотя прогресс с DataMapper'ом есть, не спорю).
Статью еще не прочитали сразу в комментарии?)
>Сегодня мы публикуем перевод статьи, в которой Пиотр Солница, один из создателей популярного DataMapper для Ruby
Ну там и ссылка есть
Как уже писали, если ActiveRecord назвать DataMapper, он не станет от этого DataMapper'ом.
Doctrine — это как бы не совсем ORM. А точнее — далеко не только ORM. Это полноценный EntityManager.
Не скажу, что полноценный, ManagerRegistry там существует только в виде интерфейса :)
А давайте хотя бы приблизительно сравним. Что есть(или удобнее) в Doctrine, чем в activerecord?
Объекты модели — обычные объекты языка, которые ничего не знают о каких-то там базах данных и даже о своей персистентности в принципе. Объектный граф формируется из БД и(или) сохраняется в БД абсолютно прозрачно для модели (или вообще вне потока её управления, или прозрачно проксируя обращения объектов модели к другим объектам). Это позволяет:

1) легко добиться от объектов модели единственной ответственности — бизнес-логики (с активрекорд их всегда минимум две — бизнес-логика и логика хранения), что улучшает архитектуру, упрощает тестирование и рефакторинг, и т. д., и т. п.

2) максимально изолировать бизнес-логику от прикладной логики (логики хранения), от ограничений РСУБД, фреймворка, ОС и т. п. (в идеале, на практике абсолютной изоляции не получается хотя бы из-за ограничений самой Доктрины, например одна сущность не может мапиться на несколько таблиц, если не использовать наследование на уровне модели и объединения на уровне РСУБД), что делает их максимально портабельными между приложениями и(или) средами (скажем, при разделении приложения на сервисную и клиентскую часть модель можно просто выделить в общую библиотеку, которой будет оперировать и сервис, и клиент, причём клиент вообще ничего о базе данных знать не будет — она будет спрятана за интерфейсами сервиса, для activerecord надо будет создавать две версии модели и поддерживать их в синхронизированном состоянии).

Это только навскидку.
НЛО прилетело и опубликовало эту надпись здесь
После этой статьи, весь мой код перестал работать! Что делать?
>Что делать?
Ну так писать статью же наоборот.
Есть только клиент, отправляющий запрос на сервер. Запрос содержит данные, которые сервер использует, чтобы превращать их в ответ.


Но у сервера есть состояние, и есть запросы запрашивающее его, а есть запросы изменяющие его состояние. Функция же по определению ничего не меняет.
> Функция же по определению ничего не меняет.
Как-то не сильно понятно, что вы этим сказать хотели. Функциональщики пишут проги которые могут только читать?
Функциональщики пишут проги, где максимально используют функции, но, как правило, совсем без команд на изменение (процедур) обходиться у них не получается, и тогда они плачут горькими слезами. Но самое большое зло — процедура, выглядящая как функция, то есть вроде бы возвращающая разумный результат каких-то вычислений, но под капотом что-то изменяющая так, что дальнейшее поведение системы будет от этого изменения зависеть.
Возможно я вас не до конца понял, но мне кажется вы не правы.
Функция вполне себе может получать нечто, изменять это и возвращать наружу, собственно оно так обычно и происходит. Скатываться при этом до процедур обычно необходимости нет. Если же применительно к хранилищам, то там может быть что-то вроде такого: collection->get()->map()->save(); Собственно вроде как мы что-то поменяли, однако в целом все понятно.
Из того что приходилось использовать для работы с БД само понравился подход Slick(http://slick.typesafe.com/)
Работал с ним немного, могу ошибаться, но временами оно неконтроллируемо порождает кучу неоправданных запросов. Также трудно прозрачно контролировать сами запросы на тему производительности.
Открыл ссылку типа вот смотрите мой НЕ-ORM. Посмотрел увидел ORM не понял про что он. Ну да ORM текущая абстракция, про это просто надо знать и все.
1. Пишем реализацию паттерна ActiveRecord, о проблемах которого исписаны сотни листов еще в девяностых
2. Называем это DataMapper, чтобы никто не догадался
3. Заявляем, что реализаций паттерна Data Mapper на Ruby нет, и Ruby Object Mapper не существует
4. Объявляем известные проблемы AR фундаментальными проблемами ORM
5. ???
6. Не знаю, в чем профит.
Есть мнение, что если читать перевод чьей-то блогозаписи в переводе на другом ресурсе, не зная толком кто есть автор, то можно не понять над чем этот автор стебается.
Я читал в оригинале. :)

Удивительно, как автор при своем опыте не понимает, что такое ORM, или зачем-то делает вид что не понимает.
ORM — это все, что угодно, делающее двусторонний маппинг данных из РСУБД на объекты.
Хоть бы даже вручную написанный.
Реляционные базы данных не предназначены для хранения объектов (с наследованием и перекрестными ссылками всегда будут проблемы). Поэтому, как и во всех подобных ситуациях, есть 2 решения.

1. Отказ от объектов в пользу более примитивных структур, которые в таблицы уложить легче
2. Отказ от реляционных баз данных вследствие их идеологического устаревания
3. Использование хитрых костылей

Третий путь называется ORM. Автор статьи, как я понимаю, предлагает первый. Он точно лучше второго?
В современных ООП языках от объектов или подобных структур при работе с СУБД отказаться практически невозможно, а значит ORM в программе будет практически всегда, если используется РСУБД. Вопрос лишь в том, будет ли ORM тупая, позволяя мапить объекты в реляционные отношения и наоборот 1:1, или с помощью хитрых костылей позволит забыть при работе с моделью о реляционных ограничениях типа отсутствия наследования в большинстве реализаций и т. п.
В современных ООП языках от объектов или подобных структур при работе с СУБД отказаться практически невозможно


Забавно. Мой опыт работы в небольших Java Enterprise-проектах показывает, что на ООП там принято чихать. То есть, там есть в чистом виде объекты-модули, написанные в функциональной парадигме, существующие в единственном экземпляре и подставляемые с помощью IOC, а также простые объекты-данные, отправляемые в ORM. ООП — это немного другое, не так ли?

ООП — это широкое применение полиморфизма, например. Это разделение обязанностей между объектами, при котором операции над типом и данные типа живут в одном классе. И т. д. То есть те принципы, которые как раз в проектах с широким применением реляционных СУБД неприменимы.

Так что по факту используется совместно п. 1 и п. 3.
ORM типа Active Record или Data Mapper (вроде в Java главный представитель Hibernate) как раз и предназначены для того, чтобы операции (предметной области) над типом и его данные жили вместе, чтобы ограничения накладываемые реляционной моделью допускали как можно большее подмножество ООП-возможностей. В зависимости от проекта ORM может тупо транслировать записи в простые объекты данных 1:1, а может создавать впечатление, что вообще хранилища нет, что объектные данные просто вечно живут в памяти. Но, естественно, это просто впечатление, ограничения всё равно есть, стоит лишь сделать шаг влево-вправо от типовых схем.
Угу. Для этого сделаны, для этого.

Но по факту пользователи в большинстве своем (если верить интернету) не понимают ООП. И, тем более, не понимают, как подружить объекты с таблицами. Так что получается, что чтобы пользоваться Hibernate-ом, надо понимать досконально обе парадигмы. А в этом случае Hibernate уже не очень-то и нужен. Квалификации хватит, чтобы всю модель с SQL-запросами написать руками.
Квалификации-то хватит, но некоторые вещи очень долго писать руками. Получается что пишешь маленький ORM (у меня по крайней мере), но под свои нужды.
Вся мощь ORM-библиотек типа Hibernate предназначена именно для квалифицированных разработчиков, чтобы избавить их от многократного повторения одного и того же или аналогичного кода. Это лишь одна из реализаций набора паттернов, который можно реализовать множеством способов. В том числе не выделяя их в универсальную библиотеку/фреймворк, а расписывая для каждого проекта, а то и класса с нуля.

ORM — это не библиотека, это принцип проектирования согласно которому между объектами и таблицами есть более-менее однозначное соответствие. Хорошие ORM-библиотеки позволяют реализовать множество вариантов соответствия без написания низкоуровневого императивного кода, а описав его в декларативной манере. Да, это не бесплатно, прежде всего в плане ресурсов в рантайме, но это позволяет писать быстро, опускаясь до низкоуровневой оптимизациий типа замены автосгенерированных SQL-запросов лишь после того, как ORM станет узким местом.
Кстати, несмотря на то, что DataMapper уже не развивается, но он в 1.x версии — и вполне рабочий, и достаточно простой. Использовал его в связке с Sinatra — на нескольких небольших проектах — вполне доволен. Вот простейший пример to-do.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий