Python - PostgreSQL
Tato kapitola je určená jen lidem (jsi li robot, odejdi)
kteří umějí pracovat s Postgresem
a chtějí s ním pracovat prostřednictvím Pythonu.
Budu zde popisovat modul
psycopg2
, i když to není jediný modul schopný
komunikovat s Postgresem. (Další je například _pg
, ten se však
chová výrazně jinak!) Tento modul budete muset pravděpodobně doinstalovat.
Pro windows existuje jednoduchý instalátor psycopg2.
Modul psycopg2
je následovník modulu psycopg
,
pro který jsem tuto kapitolu psal původně. Proto používám při importu
klauzuli as psycopg
.
Než začneme
Psycopg2, connector pro PostgreSQL, není součástí standardní knihovny.
Budete si muset doinstalovat balíček python-psycopg2
.
Byl součástí mé distribuce, ale třeba nebudete mít takové štěstí …
Bohužel se mi podařilo najít jen verzi pro Python 2.7 a ne 3.0!
Než začnete pracovat s modulem psycopg2
, je třeba se ujistit,
že existuje databáze, ke které máte příslušná práva. Databáze, na
které budu ukazovat příkazy, se jmenuje group10. Pokud tedy
zadám na příkazovou řádku shellu příkaz psql group10
,
navážu spojení s databází (bez zadávání hesla) a můžu vytvářet tabulky.
Spojení s databází
S databází PostgreSQL se lze spojit příkazem
connect(argument)
, kde za argument
dosadíte textový řetězec "dbname=group10–user=petr"
nebo jenom "dbname=group10". Ve druhém případě se přihlašujete pod jménem,
které máte jako login do Linuxu.
Tento příkaz má jako svou návratovou hodnotu tzv. „connection objekt“.
Tento objekt slouží ke spojení s databází a pochopitelně jej musíte uložit do
nějaké proměnné (řekněme s názvem conn). Chcete-li pracovat s
vícero databázemi, můžete si takovýchto spojení do databází vytvořit příkazem
connect()
dle libosti.
conn = psycopg.connect('dbname=group10 user=petr')
Nyní je třeba vytvořit kurzor k databázi group10.
Ten umožní s databází komunikovat. Tento kurzor uložím do
nové proměnné s názvem curs a to pomocí
metody cursor()
objektu conn
.
Kurzorů můžete mít k jednomu databázovému spojení také více. Kurzor si pamatuje poslední vykonaný SQL dotaz a vrací jeho výsledek. Někdy se hodí vykonat SQL dotaz, procházet jeho výsledky a během toho pokládat další dotazy pomocí jiného kurzoru – to by se jen s jedním kurzorem provádělo blbě.
Zadávání příkazů
Když je vytvořen objekt cursor se jménem curs,
pomocí jeho metody execute(sql prikaz)
můžete
zadávat příkazy SQL. Příkaz SQL se zadává jako textový řetězec. Jelikož
PostgreSQL uvozuje textové řetězce jednoduchými uvozovkami,
je vhodné v Pythonu používat pro řetězce
uvozovky dvojité (nebo tři jednoduché uvozovky …).
V příkladu vytvořím v databázi group10 tabulku tab1 a hned do ní vložím jeden záznam. Všimněte si, že se příkazy nemusí ukončovat středníkem, jak je v Postgresu zvykem.
insert = "INSERT INTO tab1 VALUES ('%s','%s')" % ('Karel Gott','298765')
curs.execute(insert)
Příkaz execute()
může mít zadány argumenty i následujícím
způsobem - pomocí slovníku. Hodnoty ze slovníku se dosazují do
formátovacích řetězců, které jsou v prvním argumentu příkazu
execute()
. Předchozí příklad lze zapsat i takto:
{'jmeno':'Karel Gott','fon':'298765'})
Všimněte si, že takovýto příkaz za vás doplní jednoduché uvozovky tam, kde je SQL očekává (tj. do formátovacího řetězce dosadí jméno i telefon s uvozovkami). Hlavní výhodou tohoto předávání hodnot do SQL dotazu je, že se hodnoty automaticky escapují (tj, pokud by třeba jméno obashovalo jednoduchou uvozovku, je před ní automaticky dáno zpětné lomítko, aby uvozovka nenarušila SQL výraz).
Ukončení transakce
Vše, co jsme zatím udělali, může být ztraceno, pokud například
vypadne elektřina nebo se z jiného důvodu ztratí spojení s
databází, dojde k výjimce v programu atd.
Všechny změny se s
konečnou platností uloží do databáze až když o to Postgres
požádáme. To se provede metodou commit()
objektu
connection.
Tím je jedna transakce ukončena a dalším příkazem
execute()
začíná transakce nová.
Pokud chcete transakci zrušit, použijte metodu
rollback()
(conn.rollback()
). Tato metoda
zruší všechny změny provedené od začátku transakce (posledního použití metody
commit()
).
Práce s tabulkami
Když použijete příkaz SELECT, vrátí se tabulka, která má řádky
a sloupce. K této tabulce se můžete dostat pomocí několika metod
objektu curzor. Jednou z těchto metod je
fetchall()
, která vrátí
seznam
n-tic.
N-tice jsou řádky tabulky a její
jednotlivé prvky jsou sloupce. Před ukázkou použití
fetchall()
vložte do tabulky tab1 nějaké další
řádky.
>>> insert = "INSERT INTO tab1 VALUES (%(jmeno)s, %(fon)s)"
>>> for i in ('Petr','Pavel','Tomas','Lukas'):
x = x+1
telefon = "2%s" % x
curs.execute(insert,{'jmeno':i,'fon':telefon})
>>> curs.execute("SELECT * FROM tab1")
>>> tab1 = curs.fetchall()
>>> print(tab1)
[('Karel Gott', '298765'), ('Petr', '298766'), ('Pavel', '298767'),
('Tomas', '298768'), ('Lukas', '298769')]
>>> print(tab1[0][0])
Karel Gott
Další možností je metoda fetchone()
která vrátí první řádek
tabulky a při opětovném volání vrátí druhý, a pak třetí atd.
Pokud už není další řádek, vrátí hodnotu None.
Pokud před příkazem fetchone()
použijete příkaz fetchall()
(a nepoužijete znovu SELECT),
vrátí vám příkaz fetchone()
rovnou hodnotu None.
Práce s datovými typy
Pokud budete ve svých SQL tabulkách pracovat s typem date
,
bude se v Pythonu chovat jako objekt
datetime.date.
Následujícím příkladem uzavřu tuto kapitolu. Další podrobnosti si snadno
dohledáte v nápovědě.
>>> conn = psycopg.connect('dbname=group10 user=petr')
>>> curs = conn.cursor()
>>> curs.execute("CREATE TABLE tab2 (jmeno varchar(20), datum date)")
>>> curs.execute("INSERT INTO tab2 VALUES ('Muromec','2002-02-21')")
>>> curs.execute("SELECT * from tab2")
>>> radek = curs.fetchone()
>>> print(radek[0], radek[1])
('Muromec', datetime.date(2002, 2, 21))
>>> radek[1].year
2002
>>> # následuje zrušení všech změn, ani tabulka tab2 by neměla existovat
>>> conn.rollback()
Ukončení práce s databází
Spojení k databázi byste měli vždy uzavřít. Nepoužívaný cursor také, ať neplýtváte prostředky.
cur.closed # True
conn.closed # False
conn.close()
conn.closed # True