2. diel - SQLAlchemy - Session a základné práce s dátami
V minulej lekcii, SQLAlchemy - Úvod a inštalácia , sme prebrali základné informácie a inštaláciu SQLAlchemy.
Ako sme si sľúbili, vrátime sa k deklaratívnemu mapovaniu a našej triede
Base
Fyzická databáza
Spustite databázový stroj, ktorý vykoná potrebné akcie. Stvorí databázu av nej tabuľky:# Vytvorenie databázy a tabuliek v nich
Base.metadata.create_all(db)
Po spustení dostaneme výstup podobný tomuto:
Konzolová aplikácia
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine PRAGMA main.table_info("vat")
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info("vat")
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine [raw sql] ()
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine
CREATE TABLE vat (
vat_id INTEGER NOT NULL,
rate FLOAT,
PRIMARY KEY (vat_id)
)
2022-03-03 17:28:34,390 INFO sqlalchemy.engine.Engine [no key 0.00006s] ()
2022-03-03 17:28:34,474 INFO sqlalchemy.engine.Engine COMMIT
Pri vytváraní databázy je dobrým zvykom presvedčiť sa, že databáza skutočne existuje a obsahuje všetko, čo obsahovať má. V našom prípade jednu prázdnu tabuľku.
Nové dáta, inštancie triedy a Session
TriedaVat
je bežná trieda, ktorá obsahuje navyše niekoľko
magických informácií a ako s takou s ňou môžeme pracovať. Ďalšia
zaujímavosť by mohla byť skutočnosť, že odvodením od Base
je
už vybavená inicializačnou metódou __init__()
a môžeme jej
odovzdávať pomenované argumenty. Pokiaľ nejaký atribút vynecháme, bude
nastavený na None
:
vat_none = Vat(rate=0.0) print(vat_none.vat_id, vat_none.rate)
Výstup:
Konzolová aplikácia
>>> None 0.0
Zatiaľ však nemá nič spoločné s databázou, je to jednoducho iba
obyčajná trieda. Aby sme mohli pracovať s dátami na úrovni databázy,
musíme vytvoriť session
, teda lepšie povedané najprv akúsi
továreň na ne a potom aktuálnu reláciu:
from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=db)
Pokiaľ zatiaľ nemáme databáz definovanú (je napríklad v inom module), postačí to takto:
Session = sessionmaker()
Až to bude skutočne nutné, v mieste pripojenia použijeme:
Session.configure(bind=db)
Továreň máme, môžeme začať vkladať dáta. Z továrne urobíme menšiu pobočku pre aktuálne použitie:
session = Session()
session.add(vat_none)
print(session.new)
Atribút session.new
obsahuje novinky v sedení a vracia
identifikačnú mapu dát:
Konzolová aplikácia
IdentitySet([<DPH : id=None; sazba=0.0>])
Od tejto chvíle máme dáta prichystané na perzistenciu. Prichystaná je
podstatný pojem, pretože uložené nie sú. Čakajú na
príkaz flush
, či lepšie na commit
. Na druhej strane
už s nimi môžeme pracovať. No, vlastne ešte nemôžeme. V tabuľke máme
totiž primárny kľúč, ktorý bude do chvíle uloženia nastavený na hodnotu
None
, čo sa nebude Alchemy páčiť. Nutne potrebuje
legálnu hodnotu:
vat_none.vat_id = 0
Teraz už je to v poriadku, ale reálne do prvého dotazu na získanie dát
neprebehol žiadny príkaz INSERT
.
Otázky na dáta
Pre otázky na dáta nám slúži metódafilter_by()
, ktorá
zastupuje klasické WHERE
:
my_vat = session.query(Vat).filter_by(rate='0').first() print(my_vat) print(type(my_vat)) print(my_vat is vat_none) my_vat.rate = 21.0 print(session.dirty) vat_none.rate = 10.0 print(session.dirty)
Výsledok sme si uložili do ďalšej premennej a budeme hľadať údaj s
hodnotou sadzby 0
. Potom si zobrazíme získané dáta, typ dát, a
ešte malú ukážku, keď je v session položka so zhodnými dátami. Totožná
referencie na objekt. Atribút session.dirty
obsahuje vykonané
zmeny, podobne ako session.new
novinky:
Konzolová aplikácia
2022-03-04 11:49:50,281 INFO sqlalchemy.engine.Engine INSERT INTO vat (vat_id, rate) VALUES (?, ?)
2022-03-04 11:49:50,281 INFO sqlalchemy.engine.Engine [generated in 0.00010s] (0, 0.0)
2022-03-04 11:49:50,283 INFO sqlalchemy.engine.Engine SELECT vat.vat_id AS vat_vat_id, vat.rate AS vat_rate
FROM vat
WHERE vat.rate = ?
LIMIT ? OFFSET ?
2022-03-04 11:49:50,283 INFO sqlalchemy.engine.Engine [generated in 0.00014s] ('0', 1, 0)
<DPH : id=0; sazba=0.0>
<class '__main__.Vat'>
True
IdentitySet([<DPH : id=0; sazba=21.0>])
IdentitySet([<DPH : id=0; sazba=10.0>])
Dotazovacie techniky si preberieme v ďalšej lekcii, teraz si ešte musíme dáta fyzicky uložiť:
vat_none.rate = 0 vat_low = Vat(vat_id=1, rate=10.0) # ID musíme zadať ručne. Tabuľka nemá autoincrement!!! vat_high = Vat(vat_id=2, rate=21.0) session.add_all([ vat_low, vat_high ]) print(session.dirty) print(session.new)
Radšej vrátime položku bez dane späť na hodnotu 0
a
pridáme ďalšie dve sadzby. Metóda session.add_all()
ukladá do
session viacero objektov vo forme poľa. Zobrazíme si chystané zmeny:
Konzolová aplikácia
IdentitySet([<DPH : id=0; sazba=0>])
IdentitySet([<DPH : id=1; sazba=10.0>, <DPH : id=2; sazba=21.0>])
a skutočne fyzicky vložíme do tabuľky v súbore:
session.commit()
Výstup:
Konzolová aplikácia
2022-03-04 12:10:54,773 INFO sqlalchemy.engine.Engine INSERT INTO vat (vat_id, rate) VALUES (?, ?)
2022-03-04 12:10:54,773 INFO sqlalchemy.engine.Engine [generated in 0.00008s] ((1, 10.0), (2, 21.0))
2022-03-04 12:10:54,773 INFO sqlalchemy.engine.Engine COMMIT
Máme za sebou tvorbu našej prvej tabuľky vrátane vloženia dát 😎 Verím, že ste všetko zvládli bez problémov. Pokiaľ sa predsa len nejaké nejasnosti či komplikácie vyskytli, pozrite sa do priloženého súboru a porovnajte vzorový kód s vlastným. Prípadné otázky môžete písať do diskusie pod článkom.
V sérii sa budeme ešte venovať ošetrovaniu chýb, viac možností
SELECT
, aktualizácia, mazanie... skrátka celý
CRUD 🙂
Týmto by som sa s vami rozlúčil.
V budúcej lekcii, SQLAlchemy - Relácia , si ukážeme vzťahy medzi dátami v tabuľkách (relácie), vytvoríme si jednoduchý sklad a uvedieme si evidenciu tovaru.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 25x (2.42 kB)
Aplikácia je vrátane zdrojových kódov v jazyku SQLAlchemy