Na navigaci | Klávesové zkratky

Translate to English… Ins Deutsche übersetzen…

„dibi vs. Nette Database“ story

Je nejvyšší čas rozseknout FUD a nejasnosti kolem databázových vrstev.

Databázovou vrstvu dibi jsem začal psát cca před devíti lety se záměrem shrnutým v tomto historickém článku. Šlo mi především o to sjednotit API různorodých klientů, ošetřovat chybové stavy, přidat uživatelsky pohodlné bindování parametrů a také dynamické generování základních konstrukcí SQL, jako jsou například podmínky, řazení a INSERT & UPDATE:

$db = new DibiConnection(...); // or via monostate dibi::connect(...)

$pairs = $db->fetchPairs('SELECT id, name FROM countries');

$arr = array(
    'name' => 'John',
    'modified%d'  => time(),
);
$db->query('UPDATE users SET ', $arr, ' WHERE `id`=%i', $id);
// UPDATE users SET `name`='John', `modified`= '2005-10-12' WHERE `id` = 123

Časem se v PHP objevila nativní knihovna PDO, která v podstatě řešila polovinu věcí, co dibi, nicméně její API pro bindování parametrů bylo těžkopádné, neporadilo si s datumy a skládání základních konstrukcí SQL chybělo úplně. Takže dibi nenahradilo.

V dibi jsem si hrál i s experimenty, jako DibiTable, DibiFluent nebo DibiDataSource, ale sám jsem je nikdy nepoužíval. Jsou tam pochopitelně i věci, které bych dnes udělal lépe, ale z hlediska zpětné kompatibility je takřka nemožné do nich zasahovat. Třeba mám zmatek v tom, co který modifikátor znamená – je jich příliš mnoho. (Moc se to neví, ale místo přemýšlení, který modifikátor použít, můžete obvykle použít otazník.)

Protože téměř v každém demu pro Nette bylo potřeba pracovat s databází, vyžadovalo to nainstalovat dibi nebo Doctrine (jiné vrstvy se v podstatě nepoužívají). Dnes je to díky Composeru otázka pár úderů do klávesnice, ale tehdy neexistoval. Přemýšlel jsem proto, že bych si v příkladech vystačil jen s čistým PDO. Jenže pokud jste rozmlsaní z dibi, není návratu zpět. Chybí vám nejen přívětivé API, ale i pohodlí Tracy (tj. Laděnky) pro monitorování dotazů či chyb.

Tehdy mě napadlo, že by nebylo od věci udělat „dibi model 2010“, nově, bez historických zátěží, založené čistě nad PDO. Vyhodit hromadu driverů, všechny modifikátory nahradit jedním otazníkem a implementovat jen vlastnosti, které budou skutečně potřeba.

Nette Database

Takhle vzniklo Nette Database (NDB). Moderní ekvivalent dibi:

$db = new Nette\Database\Connection(...);

$pairs = $db->fetchPairs('SELECT id, name FROM countries');

$arr = array(
    'name' => 'John',
    'modified'  => new DateTime,
);
$db->query('UPDATE users SET ', $arr, ' WHERE `id`= ?', $id);

Brzy jsem narazil na hromadu nedostatků PDO, nareportoval a obešel mraky chyb a když bylo Nette Database odladěné, vyšlo v únoru 2012 jako součást finálního Nette Framework 2.0.

Tady musím zdůraznit, že navzdory šiřitelům FUD v Nette Database skutečně takřka žádné chyby nebyly a jediným větším problém se ukázal bug v PDO způsobující memory leaky, kvůli němuž musely být třídy NDB přepsány a v Nette 2.1 již Connection není potomkem PDO (dědit od PDO byla z dnešního pohledu stejně blbost.)

Dnes nevidím důvod, proč pro nový projekt použít staré dibi namísto NDB. Chybí asi jen:

  • bohatší možnosti skládání v klauzuli WHERE (zatím se nezdá, že by byla potřeba)
  • statická obálka dibi:: (tu v Nette nahrazuje DI Container)
  • samostatnost (vyřeší Nette 2.2)
  • fetchAssoc (tu v Nette nahrazuje NDBT, eventuálně by ji šlo doplnit je v 2.2-dev)

A tím se dostáváme k Nette Database Table (NDBT), prapříčině mnoha zmatků.

Nette Database Table

V prosinci 2010 jsem do tehdy beta verze Nette 2.0 začlenil knihovnu Jakuba Vrány NotORM, ve kterém jsem viděl úžasný nástroj pro dolování dat z databáze:

$pairs = $db->table('countries')->fetchPairs('id', 'name');
// SELECT `id`, `name` FROM `countries`

$name = $db->table('book')->get($id)->author->name;
// SELECT `id`, `author_id` FROM `book` WHERE `id` = 123
// SELECT `id`, `name` FROM `author` WHERE (`author`.`id` IN (456))

$arr = array(
    'name' => 'John',
    'modified'  => new DateTime,
);
$db->table('users')->where('id', $id)->update($arr);
// UPDATE users SET `name`='John', `modified`= '2005-10-12' WHERE `id` = 123

Kód i API jsem upravil tak, aby zapadlo do koncepce Nette, v podstatě z myšlenky využít NotORM v Latte pochází i nápad na tzv. předbíhání budoucnosti, neboli načítání jen těch sloupců, které budou později potřeba, taktéž s Latte může skvěle fungovat koncept NotORM 2.

A právě NotORM v NDB nese označení NDBT. Přičemž její použití je volitelné.

Zapojení do Nette vyvolalo o NDBT resp. NotORM velký zájem a ukázalo se, že byť byla knihovna pro potřeby Jakuba odladěná, pro různorodější požadavky bylo třeba odvést ještě hodně práce. Té se od poloviny roku 2011 ujal Hrach a z velké části původní NDBT přepsal a pečlivě doplnil testy. Knihovna procházela mnohem rychlejším vývojovým cyklem než zbytek frameworku, nicméně nebýt jeho součástí, nevyvíjí se asi vůbec.

Nette tedy má

  • NDB, obdobu dibi, stabilní od verze 2.0.0
  • NDBT, obdobu NotORM, vhodnou pro produkční nasazení až od verze 2.1

Dibi nadále udržuji, koneckonců běží mi na něm většina webů, ale žádné novinky nechystám. V podstatě ani do NDB ne. Naopak s NDBT, jenž pohání mimo jiné i tento blog, má Hrach ambiciózní plány.

Komentáře

  1. Tharos #1

    avatar

    Image zabugované knihovny IMHO vznikla tak, že zpočátku si pod pojmem „Nette Database“ myslím nikdo nepředstavil NDB, nýbrž rovnou celé NDB+NDBT. Myslím, že nikoho ani nenapadlo vnímat to jako dvě oddělené knihovny, tuplem pak při nalezení bugu přemýšlet o tom, jestli je to chyba v NDB nebo NDBT. Uznávám, že Ty jsi to prezentoval jako dvě „komponenty“ od samého začátku: https://forum.nette.org/…-predstaveni#…, ale hned navazující diskuze je téměř celá o NDBT.

    Já projektu od začátku velmi fandím. Věřím, že už konečně jde o stabilní knihovnu a že důvody, proč jsem ji přestal po pár pokusech používat, už jsou pasé. Odvedli jste na kódu s Hrachem velký kus práce!

    před 3 lety | odpovědět
  2. Taco #2

    avatar

    Tak já jsem přesně ten případ, který díky dojmu, že NDB a NDBT jedno jsou, celou Nette Database zavrhl, a dále používal Dibi. Díky, mrknu na to.

    před 3 lety | odpovědět | reagoval [5] Vojtěch Semecký
  3. Jan juzna Doleček http://juzna.cz #3

    avatar

    Nette používám už dlouho a v jeho použití se považuji za pomněrně zkušeného. Používám i zabudovanou funkcionalitu pro přístup k databázi, dokonce jsem se snažil angažovat i v jejím vyvoji. O tom, že jde o dvě různé „komponenty“ jsem se bohužel ale dozvěděl až teď.

    Docela škoda, že toto rozdělení nebylo jasně prezentováno od začátku. A nebo jsem to jen nepostřehl?

    před 3 lety | odpovědět
  4. Honza T #4

    NDB pořád považuji za takové osekané dibi, ve kterém nelze rozumně skládat složité dotazy. A nad NDBT neumím postavit pořádný model.

    před 3 lety | odpovědět
  5. Vojtěch Semecký http://www.varlog.cz #5

    avatar

    #2 Taco, Já jsem celou Nette Database sice nezavrhl, ale že existují 2 samostatné komponenty my nějak ušlo. Fandím té NDB. NDBT asi používat nebudu. Přemýšlím v SQL a NDBT mě od něj příliš odstiňuje.

    před 3 lety | odpovědět
  6. Prixa #6

    Tohle jsem měl vědět dřív. A i mnozí další. Totiž i Nette guru šířili kolem sebe bludy, např. https://forum.nette.org/…stable-verzi#… (cituji: „mluvím hlavně o chybách Nette\Database.....přes jeho obrovskou snahu ta knihovna prostě není ani zdaleka tak stabilní jako dibi“)

    před 3 lety | odpovědět | reagoval [8] Honza T
  7. Caine #7

    avatar

    Řekl bych, že jsou dva důvody, proč jsme všichni měli za to, že ndb = ndbt..

    1. vytváření Selection je přímo v Connection
    2. což bude to hlavní, absence samostatného sql builderu (imho všichni považují za sql builder právě onen Selection), protože spoustu lidí nechce psát čistě textové sql dotazy, které se špatně parametrizují.
    před 3 lety | odpovědět
  8. Honza T #8

    #6 Prixo, Proč bludy? Tharos si pod pojmem Nette\Database představoval to, čemu dnes David říká NDBT (v té době to označení IMHO vůbec neexistovalo, protože ho poprvé použil Hrach před 5 měsící a odkázaný příspěvek je starý 9 měsíců), reagoval jsem tedy na dotaz ohledně NDBT. Nehledě na to, že pokud chci psát SQL dotazy ručně, tak místo NDB použiji stejně dibi, protože v NDB prostě chybí některé dost zásadní funkce.

    před 3 lety | odpovědět | reagoval [9] Prixa
  9. Prixa #9

    #8 Honzo Te, Nějak jsem se ztratil a jako začátečník mě to dost mate. Ty použiješ dibi, protože v NDB chybí zásadní funkce? Přitom přímo v tomto článku se píše, že v NDB nic zásadního nechybí („…nevidím důvod, proč pro nový projekt použít staré dibi namísto NDB“)!

    Jak to tedy je?

    před 3 lety | odpovědět | reagoval [10] Honza T
  10. Honza T #10

    #9 Prixo, Vždyť hned v další větě David zmiňuje některé z věcí, který chybí (je jich víc, pochopitelně). Buď je potřebuješ, nebo ne.

    před 3 lety | odpovědět
  11. enumag http://m33.cz/ #11

    avatar

    NDBT (a mimochodem tu zkratku vidím dnes poprvé) jsem používal poměrně dlouho, ale stejně jako Honzovi se mi nad tím nikdy nepodařilo napsat model se kterým bych byl spokojen, Možná to napraví Nextras/ORM i když mně už na tom po přechodu na Doctrine nesejde.

    před 3 lety | odpovědět
  12. bckp #12

    avatar

    Mě osobně u NBD chybí právě fetchAssoc, což považuji za killer feature od Dibi a důvod, proč do dnešního dne používám právě Dibi. Bohužel mi celý koncept NotORM nesedí, rád si píšu čisté dotazy.

    Možná by mohl David vydat ještě jednu verzi Dibi, kde by odebral deprecated věci, sám jsem to zkoušel ale nepovedlo se mi ji pak minimalizovat tak pěkně jako to umí právě David :(

    před 3 lety | odpovědět | reagoval [15] David Grudl
  13. Peggy #13

    avatar

    Mě docela mrzí že NDB nemá to co poskytrovalo DibiFluent .. prostě psát si vlastní SQL dotazy, ale skládat je fluentně … Přechod na Nette Database sem tudíž ještě furt nějak uplně nepřekousl :D

    před 3 lety | odpovědět | reagoval [15] David Grudl
  14. OnGe http://www.onge.cz #14

    avatar

    Když bude NDB samostatná v Nette 3, v jak daleké budoucnosti Nette 3 vlastně leží?

    před 3 lety | odpovědět | reagoval [15] David Grudl
  15. David Grudl http://davidgrudl.com #15

    avatar

    #12 bckpe, fetchAssoc je ve 2.2-dev verzi Nette (syntax je mírně jiná než u dibi)

    #13 Peggy, fluentním zápisem disponuje právě NDBT, takže by asi nemělo moc opodstatnění nějaké ND Fluent přidávat

    #14 OnGe, doufám, že to bude otázka několika měsíců

    před 3 lety | odpovědět
  16. Martin http://www.zeminem.cz/ #16

    avatar

    Pochopení rozdílu nenahrává asi ani to, že v české dokumentaci je NDB přeložen jako „Databáze & ORM“, NDBT jako „Databáze & ORM“ a Table\Selection jako „Databáze & ORM“…

    před 3 lety | odpovědět
  17. Pechy #17

    avatar

    Já jsem si na NDBT tak rychle zvykl a zakousl se do něj, že se mi absolutně příčí dělat na čemkoliv, kde není. Takže ho cpu do každého staršího projektu, na kterém dělám. Fakt super práce.

    před 3 lety | odpovědět
  18. Felix http://jfx.cz #18

    avatar

    Na rychlé prototypování je to super. I nějaký základní model lze postavit. ORM to není, tak bych ho s tim ani nesrovnával.

    před rokem | odpovědět

Zanechat komentář

Text komentáře
Kontakt

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--