Автоінкремент зайшов добре — давайте і по ОРМам пройдемося? 😝
Нащо вони нам? ОРМи існують для розв'язання двох проблем: композиції та того, що реляційні дані формою відрізняються від об‘єктів. З другим наче інтуітивно зрозуміло, а з композицією історія в тому, що SQL сам по собі компонується погано, а у більшості мов це ще й просто рядочки тексту – то взагалі гаплик.
Якби дизайнери SQL'ю думали не тільки за читаємість, а ще й за компонування кусочків без змін, куди б менше проблем ми зараз мали... З іншої сторони маємо Elasticsearch, там думали за композицію і не думали за читаємість — не так щоб результат критично кращим був. 😁
Повернемося до наших баранів! Здалеку ця ідея здається розумною. Скомпонував знач з кількох частин запит, отримав на виході свої об'єкти, фантастіка ж! Чи погано? ДуЖе пОгАнО! 😡
- Кожен ORM вирішує N+1 по-своєму, і треба бути дуже обережним пупсіком, щоби не налажати. Якщо ваші руки тягнуться написати "а я от навіть не напружуюсь", то у вас стокгольмский синдром, як у мене з динамічною типізацією. 💯
- Мало не всі ОРМи дають легкий спосіб добратися від даних в пам'яті до даних в базі.
book.author
— і маємо ще один запит в базу. Програміст щасливий, бо коду не писав, замовник щасливий, бо автор показується, база щаслива, бо про неї не забувають. В поганих випадках не забувають по 300-400 раз на сторінку. - Реляційні дані дійсно не дуже лягають на об'єктні моделі, особливо їх динамічність. Попри те, що всякі Пайтони — динамічні, ормівські моделі доволі-таки статичні. Тому звичайний програміст уникає агрегацій і підрахунків в базі. Є кльова відмазка — це ж не web-scale, краще ми заведемо собі кілька реплік і розмажемо по них навантаження. Нічого, що сетап складніше став, комп'ютери залізні, не плачуться.
- Не концептуальна проблема, але зазвичай ORM — це дуже багато коду. HoneySQL — це 3 тисячі рядків, django.db — 32k, sqlalchemy.orm — 36k (увесь sqla — 137k!), і так далі. Можете подивитися на свій. Так от, для відносно простих сторінок ОРМи можуть займати 30-60% часу виконання. Я колись пришвидшив сайт в два рази тим, що апгрейднув алхімію з 0.8 до 1.0.
Підсумовуючи, я маю дві претензії до ОРМів:
- Погані практики на них реалізовувати дуже легко і програмісти до того тяжіють (читай: пишуть погано), а будь-яке покращення запитів ускладнюється: всякі
.select_related
чи.prefetch_related
(знаєте в чому різниця, га?) в Джанзі,.options(...)
в sqla. Я не хочу навіть знати, що там на Джаві. - Реляційна модель заходить програмістам на ОРМах дуже так непевно і потім їх треба перевчати. Замість того дати розібратися у базових принципах і дати ними користуватися, ОРМи закривають їх собою, як Франкейнштейн з дахом^W абстрацією, що протікає.
То що робити біднесенькому програмісту? По-перше, змиритися, що найкращий спосіб робити запити в БД це що? Авжеж, це HoneySQL на Clojure, а що ви очікували. :-) Це гарний спосіб отримати композицію, якої нема, коли використовуєш строки, але не відриватися від базового SQL занадто сильно — і всі можливості SQL на місці, і болі в сідницях від конкатенації нема.
У SQLAlchemy є базова алгебра функціями, а не тільки ORM, наприклад, але воно не ергономічно. Не знаю, як покращити, щоб ним приємно було користуватися — може в когось є корисні думки?
Ну а по-друге, коли всі покрови зірвані, треба думати й експериментувати. Я впевнений що всюди можна зробити краще, ніж статус-кво (except you know where, ha-ha).
P.S. Тільки не згадуйте монги в коментах, будь ласка.