Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - SQLAlchemy - Session a základní práce s daty

V minulé lekci, SQLAlchemy - Úvod a instalace, jsme probrali základní informace a instalaci SQLAlchemy.

Jak jsme si slíbili, vrátíme se k deklarativnímu mapování a naší třídě Base

Fyzická databáze

Spusťme databázový stroj, který provede potřebné akce. Stvoří databázi a v ní tabulky:

# Vytvoření databáze a tabulek v nich
Base.metadata.create_all(db)

Po spuštění dostaneme výstup podobný tomuto:

Konzolová aplikace
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

Při vytváření databáze je dobrým zvykem se přesvědčit, že databáze skutečně existuje a obsahuje vše, co obsahovat má. V našem případě jednu prázdnou tabulku.

Nová data, instance třídy a Session

Třída Vat je běžná třída, která obsahuje navíc několik magických informací a jako s takovou s ní můžeme pracovat. Další zajímavostí by mohla být skutečnost, že odvozením od Base je již vybavena inicializační metodou __init__() a můžeme jí předávat pojmenované argumenty. Pokud nějaký atribut vynecháme, bude nastaven na None:

vat_none = Vat(rate=0.0)
print(vat_none.vat_id, vat_none.rate)

Výstup:

Konzolová aplikace
>>> None 0.0

Prozatím však nemá nic společného s databází, je to jen obyčejná třída. Abychom mohli pracovat s daty na úrovni databáze, musíme vytvořit session, tedy lépe řečeno nejprve jakousi továrnu na ně a poté aktuální relaci:

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=db)

Pokud zatím nemáme databází definovanou (je například v jiném modulu), postačí to takto:

Session = sessionmaker()

Až to bude skutečně nutné, v místě připojení použijeme:

Session.configure(bind=db)

Továrnu máme, můžeme začít vkládat data. Z továrny uděláme menší pobočku pro aktuální použití:

session = Session()
session.add(vat_none)

print(session.new)

Atribut session.new obsahuje novinky v sezení a vrací identifikační mapu dat:

Konzolová aplikace
IdentitySet([<DPH : id=None; sazba=0.0>])

Od této chvíle máme data přichystaná k persistenci. Přichystaná je podstatný pojem, protože uložena nejsou. Čekají na příkaz flush, či lépe na commit. Na druhou stranu už s nimi můžeme pracovat. No, vlastně ještě nemůžeme. V tabulce máme totiž primární klíč, který bude do chvíle uložení nastaven na hodnotu None, což se nebude Alchemy líbit. Nutně potřebuje legální hodnotu:

vat_none.vat_id = 0

Nyní už je to v pořádku, ale reálně do prvního dotazu na získání dat neproběhl žádný příkaz INSERT.

Dotazy na data

Pro dotazy na data nám slouží metoda filter_by(), která 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ýsledek jsme si uložili do další proměnné a budeme hledat údaj s hodnotou sazby 0. Poté si zobrazíme získaná data, typ dat, a ještě malou ukázku, když je v session položka se shodnými daty. Totožná reference na objekt. Atribut session.dirty obsahuje provedené změny, podobně jako session.new novinky:

Konzolová aplikace
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>])

Dotazovací techniky si probereme v další lekci, teď si ještě musíme data fyzicky uložit:

vat_none.rate = 0
vat_low = Vat(vat_id=1, rate=10.0) # ID musíme zadat ručně. Tabulka 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ěji vrátíme položku bez daně zpět na hodnotu 0 a přidáme další dvě sazby. Metoda session.add_all() ukládá do session více objektů ve formě pole. Zobrazíme si chystané změny:

Konzolová aplikace
IdentitySet([<DPH : id=0; sazba=0>])
IdentitySet([<DPH : id=1; sazba=10.0>, <DPH : id=2; sazba=21.0>])

a skutečně fyzicky vložíme do tabulky v souboru:

session.commit()

Výstup:

Konzolová aplikace
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ší první tabulky včetně vložení dat 😎 Věřím, že jste vše zvládli bez problémů. Pokud se přeci jen nějaké nejasnosti či komplikace vyskytly, podívejte se do přiloženého souboru a porovnejte vzorový kód s vlastním. Případné dotazy můžete psát do diskuse pod článkem.

V sérii se budeme ještě věnovat ošetřování chyb, více možností SELECT, aktualizace, mazání... zkrátka celý CRUD 🙂

Tímto bych se s vámi rozloučil.

V příští lekci, SQLAlchemy - Relace, si ukážeme vztahy mezi daty v tabulkách (relace), vytvoříme si jednoduchý sklad a uvedeme si evidenci zboží.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 23x (2.42 kB)
Aplikace je včetně zdrojových kódů v jazyce SQLAlchemy

 

Předchozí článek
SQLAlchemy - Úvod a instalace
Všechny články v sekci
SQLAlchemy pro databáze v Pythonu
Přeskočit článek
(nedoporučujeme)
SQLAlchemy - Relace
Článek pro vás napsal Virlupus
Avatar
Uživatelské hodnocení:
13 hlasů
Autor se věnuje webovým aplikacím, skladově-účetnímu softwaru, 3D grafice, lexiální analýze a parserování. Studuje fyziku na MFF UK. Učil IT na střední škole.
Aktivity