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.

import psycopg2 as psycopg
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.

curs = conn.cursor()

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.

curs.execute("CREATE TABLE tab1 (jmeno varchar(20),telefon varchar(20))")
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:

curs.execute("INSERT INTO tab1 VALUES (%(jmeno)s,%(fon)s)",
    {'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á.

conn.commit()

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.

>>> x = 98765
>>> 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ě.

>>> import psycopg2 as psycopg
>>> 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.

curs.close()
cur.closed    # True
conn.closed   # False
conn.close()
conn.closed   # True
Komentář Hlášení chyby
Created: 11.9.2005
Last updated: 2.9.2015
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..