ORM sau SQL? De ce unul sau altul?

N-am înţeles niciodată de ce multă lume preferă ORM-uri în loc să scrie direct SQL. Care-i faza?

Exemplu, in SQLAlchemy a trebuit să scriu o balamuceală totală pentru o chestie absolut banală:

Comanda.query.with_entities(func.year(Comanda.data_comanda).label("d")).distinct().filter(Comanda.status==2).order_by("d")

ca să rezulte un simplu şi uşor de citit SQL:

SELECT DISTINCT year(data_comanda) AS d FROM comenzi WHERE status=2 ORDER BY d

PS E cam enervant că trebuie ca titlul unei postări să aibă o lungime random de 15 caractere :slight_smile:

2 Likes

Vrei performanta, dar pierzi type safety plus greseli in query → sql
Vrei sa lucrezi in maniera obeict orientat → orm

Unele orm-uri iti ofera si ceva asemanator sql-ului, sintaxa gen select, where etc. In Java de exemplu exista JOOQ care seamana cu SQL. Si cumva este best of both worlds.

Eu lucrez cu Hibernate in Java, dar cand am nevoie de query performant si optim, prefer sa il scriu de mana si sa ma ocup eu de toate cele.

Pt ca un ORM are si magie in spate, magie prin care sa scoti si performanta, apelez la Vlad Mihalcea

Aici o alta discutie

PS: Sa ai grija cu treaba N + 1 query-uri. Am patit, dar s-a rezolvat.
Si toate orm-urile au metode prin care iti permit sa trimiti tu raw query-ul la baza de date. Dar esti raspunzator cum vin datele la acel query.

1 Like

Depinde de ce bază de date folosești. Cu SQLite nu ai problema asta :wink:

On topic: Poți începe cu ORM și cînd ai nevoie de performanță, folosești SQL

Poti avea n+1 la nivel de aplicatie din cauza orm/lazy loading

1 Like

la nivel de aplicatie ma refer
ce zice @IceRidder


https://www.sqlite.org/np1queryprob.html

1 Like

am impresia ca depinde foarte mult si de cat de promovat este un ORM pe un limbaj anume: Exemplu, daca lucrezi cu .NET Core, majoritatea au auzit si de Entity Framework. Altceva ar fi faptul ca fara un ORM, ai avea mai mult sql de invatat (ceea ce ormul face automat, va trebui sa scrii tu manual). Am vazut proiecte in care se folosesc 2 orm-uri, pentru performanta: EF pentru write, Dapper pentru read. Pe langa astea, faptul ca dezvoltarea unei aplicatii dureaza mai putin folosindu-te de un ORM (observat in cazul meu, altii s-ar putea sa nu simta diferenta).

Scala de ex, incepusem sa lucrez cu Slick orm, parca mai rau ma incurca (plus ceva incompatibilitati), am renuntat, jdbc + queryuri mult mai simplu.

1 Like

Eu sunt fan Sql dar totusi folosesc ORM in proiecte. Cand trebuie sa fac un query mai complicat scriu in sql si il execut ca rawSql.
O chestie faina mai e ca la orm ii spui tipul de conexiune (mysql/oracle/postgres/…) si il poti schimba ulterior fara sa mai stai umblii sa schimbi “queryul”

1 Like

Acum cativa ani ajunsesem sa laud Doctrine in toate conversatiile de genul. Ajunsesem sa il si invat. Desi, majoritatea query-urilor de complexitate peste medie de la vremea respectiva le faceam fara Doctrine. Chiar nu le puteam face cu doctrine. Si chiar nu ne pasa de performanta pentru un reporting module pentru 100 de useri.

Astazi insa nu as mai folosi ORM pe nicaieri. Sunt si puternic influentat de comunitatea Go care prefera magie mai putina in proiecte. Dar chiar nu simt ca ma ajuta cu ceva. Rapiditate in dezvoltare? Da si nu. Poate parea ca esti mai productiv la inceput pe un proiect care foloseste ORM. Insa dupa cateva luni si celalat proiect(care nu foloseste ORM), va ajunge sa aibe un soi de “internal framework” daca vreti…si ajungi la productivitate similara.

INSA…cand dai de o problema mai nasoala si folosesti ORM-ul…gen optimizari, n+1 queries, etc…se cam duce pe apa dambovitei toata productivitatea castigata anterior.

P.S. Cele mai challanging proiecte la care am lucrat nu folosesc ORM. Ori au folosit initial si l-au scos(emag - partea de site) ori nu au folosit niciodata si nici nu intentioneaza sa o faca(po**hub).
Bine, asta asa ca fapt divers. Nu am personal nimic impotriva ORM-urilor si nici impotriva celor care decid ca e ok in proiectul lor. Fara flames :blush:

3 Likes

Limitând comparația la Query Building, SQL e mult mai ușor. Dacă un ORM e mai rapid în dezvoltare, depinde de cât de bine îl știi. De SQL injection, te poți ocupa și fără ORM. N-am întâlnit încă cazul în care s-a schimbat tipul de bază de date într-un proiect.

Totuși, dacă folosești DDD cu MVC, în special în cazul unui controller slim, caz în care logica merge fie în model fie în view, ORM-ul face exact ceea ce spune în denumire (Object-Relational Mapping); poți construi modele cu logică complexă sau adauga variabile care n-au legătura cu câmpurile din baza de date și ORM-ul îți dă exact obiectele de care ai nevoie.

Eu personal prefer un ORM. Query-uri complicate le scriu în SQL, dar le execut tot în ORM.

Lasand alte aspecte la o parte, eu as da un raspuns foarte simplu: pentru readability, prin urmare, maintanence.
Query-urile scrise de mana iti mai mult timp sa le intelegi/interpretezi, prin urmare sa le modifici. Urasc sa vad query-uri complicate cu nu stiu cateva varaibile in el si sa stau sa ma dezmeticesc ce se intampla acolo.
Iar problema asta de readability nu o rezolva toate ORM-urile. Doar unele.
Spre exemplu Doctrine, TypeORM nu le rezolva. Trebuie sa scrii tu chestii precum .leftJoin(), pentru fiecare chestie. Pai, in conditiile astea, zic si eu ca nu mai e nevoie de ORM. Pot sa scriu la fel de bine LEFT JOIN, si singur.
Pe de alta parte, ORM-urile care dispun de un query language, precum e Eloquent sau Prisma ORM cred ca sunt cele cu adevarat utile si placute de lucrat.

Exemplu. Cat de usor e de inteles ce se intampla aici, versus un raw SQL query cu de 7 linii, sau cat or fi avand. Si asta inca e un exemplu destul de simplut.

  const users = await prisma.user.findMany({
    where: {
      email: {
        endsWith: "prisma.io"
      },
      posts: {
        some: {
          published: false
        }
      }
    },
  }
1 Like

Personal prefer sa imi scriu Query-urile de mana. Am avut experiente nefaste cu ORM-uri de-alungul timpul incat sa nu imi doresc sa le mai folosesc.

1 Like

Nu pot sa zic ca prefer SQLAlchemy fata de SQL, dar recent am ales sa folosesc SQLAlchemy totusi la un proiect nou, pentru ca stiam ca la inceput voi folosi sqlite, pentru proof of concept, dar apoi urma sa migrez pe ceva DB mai serios (care nu era neaparat decis de mine, deci nu stiam ce va fi). Ca sa nu rescriu apoi queryurile datorita diferentelor subtile intre diferitele db-uri, am mers pe SQLAlchemy care emite apoi queryuri potrivite pt fiecare DB.

O alta problema ar mai fi ca SQL ca limbaj e prost gandit.

Unul dintre avantajele unui ORM este că-ți decuplează codul de baza de date. Balamuceala aia te scutește de bătăi de cap dacă, de exemplu, ai nevoie de Postgres sau Mongo în loc de Mysql.

Ce-i drept, de cele mai multe ori nu vei avea nevoie de acest feature…

1 Like

Teoretic si daca folosesti sql ar trebui sa faci acelasi lucru, diferenta este ca un ORM iti face maparea si hidratarea automat(automagic) iar cu SQL o faci tu singur.

Ehhh, teoretic.

Dar practic, fiecare implementare este un dialect, nu neapărat compatibil cu celelalte.

Cu cât crește în complexitate unui proiect, cu atât ai șanse mai mici să faci migrarea un „proiect de weekend” și să umpli codul de if engine = mysql elseif engine = postgres elseif engine = * :slight_smile:

Welcome to the real world. Lumea aia cu “eu stiu jQuery dar nu stiu Javascript”.

2 Likes

Codul nu il decuplezi folosind exclusiv ORM pentru ca vei depinde de driverele pe care acel ORM le are. Ma indoiesc ca Doctrine are drivere si pentru Postgres, si pentru Redis, si pentru Cassandra.

Ca sa obtii o decuplare in adevaratul sens al cuvantului, cel mai bine folosesti un Repository pattern cu Dependency Inversion. Si atunci iti e indiferent daca folosesti SQL raw sau ORM sau un api de retreive pentru redis.

4 Likes

si pentru chestia asta se aplica fix ce a zis @tacheshun DI FTW

un ORM folosit cum trebuie e mult mai bun, sa scrii queries boilerplate de mana e error prone, sa faci maparile de fiecare data etc…

Imi aduc aminte cu placere de zilele cand scriam SQL pur si mergea struna. Dar e un pic ca si la programarea structurala vs obiectuala: tendintele si evolutia te imping sa le adopti.

Am insa si amintiri de groaza cu patch-uri prin cod ca sa securizez SQL-ul, cod suplimentar pentru acomodarea cu configurati de pe diferite servere in ceea ce priveste tratarea ghilimelelor, problemele de migrare de la o versiune la alta a platformei (ma refer la coloane noi prin baza de date), etc.