MySQLdb, czyli MySQL w Pythonie

Coldpeer

W Pythonie mamy kilka bibliotek do obsługi bazy MySQL - najpopularniejszą i najlepszą z nich jest MySQLdb i to o niej traktuje ten tekst. Ciekawostkę może stanowić fakt, iż jest używana w takich projektach jak Django, Zope czy SQLAlchemy.

     1 Instalacja MySQLdb
     2 Połączenie z bazą
     3 Pobieranie rekordów z bazy
     4 Wstawianie/modyfikacja danych do bazy

Instalacja MySQLdb

Bibliotekę można ściągnąć z tej strony. W Windowsie można wziąć paczkę dla Win32 z graficznym instalatorem, ja jednak skupię się na instalacji "ze źródeł". Pobieramy archiwum tar.gz i następnie:
$ tar zxvf MySQL-python-*
$ cd MySQL-python-*
$ python setup.py build
$ python setup.py install

Odpalamy Pythona i sprawdzamy czy wszystko jest ok:

>>> import MySQLdb
>>>

Połączenie z bazą

Służy do tego metoda `connect`. Można ją zainicjować na kilka sposobów:
conn = MySQLdb.connect("host", "user", "haslo", "baza")
conn = MySQLdb.connect(host="host", user="user", passwd="haslo", db="baza")
conn = MySQLdb.connect(read_default_file="/etc/mysql/myapp.cnf")

Dodatkowo istnieją dodatkowe opcje, m.in. compress=1 - włącza kompresję gzip; use_unicode=1 - zwraca dane jako obiekty unicode. Po więcej odsyłam do dokumentacji.

Pobieranie rekordów z bazy

Stwórzmy pierw testową tabelkę w bazie danych:
create table users (
  id int not null primary key auto_increment,
  nick varchar(150),
  pass varchar(150)
);
insert into users values('', 'coldpeer', 'tajne');
insert into users values('', 'bohun', 'xxx');

I przykładowy kod:

import MySQLdb

conn = MySQLdb.connect("localhost", "user", "haslo", "testy")

c = conn.cursor()
c.execute("SELECT nick FROM users")
print c.fetchall()

Wynik będzie następujący:

(('coldpeer',), ('bohun',))

Aby odwołać się do wartości pierwszego rekordu, czyli coldpeer:

print c.fetchall()[0][0]
# lub
print c.fetchone()[0]

Do drugiego zaś (bohun):

c = conn.cursor()
c.execute("SELECT nick FROM users")
print c.fetchall()[1][0]

Aby pobrać wybraną ilość pól:

print c.fetchmany(ile)

Pobierzmy teraz wszystkie pola. Kilka przykładów:

print c.fetchall()

Wynik:

((1L, 'coldpeer', 'tajne'), (2L, 'bohun', 'xxx'))

Liczba pobranych wierszy:

print c.rowcount

A teraz parę przykładów iteracji:

c = conn.cursor()
c.execute("SELECT * FROM users")
for rec in c.fetchall():
    print "ID: %d\nNick: %s\nHaslo: %s\n----" % (
        rec[0], rec[1], rec[2])

# druga wersja        
for id, nick, haslo in c.fetchall():
    print "ID: %d\nNick: %s\nHaslo: %s\n----" % (
        id, nick, haslo)

# trzecia wersja
for i in range(c.rowcount):
    rec = c.fetchone()
    print "ID: %d\nNick: %s\nHaslo: %s\n----" % (
        rec[0], rec[1], rec[2])

Wynik:

ID: 1
Nick: coldpeer
Haslo: tajne

ID: 2
Nick: bohun
Haslo: xxx
----</kbd>

Aby wprowadzić do zapytania jakąś wartość np. podaną przez użytkownika:

c.execute("SELECT nick FROM users WHERE pass = %s", ("xxx"))

# inny przyklad, gratis jak robic wielolinijkowe zapytania
c.execute("""
SELECT
  nick
FROM
  users
WHERE
    id = %s
  AND
    pass = %s
""",(2, "xxx"))

Zalecane jest, aby ze nie używać tutaj operatora %, tj. c.execute(sql%wartosci). Zapytanie oczywiście pobierze użytkownika o nicku bohun:

(('bohun',),)

Wstawianie/modyfikacja danych do bazy

Naturalnie, używamy tutaj zapytań INSERT, UPDATE, ALTER itd. odzianych w metodzie execute:
c = conn.cursor()
c.execute("INSERT INTO users VALUES('', 'albin', 'yyy')")

Czasem zachodzi potrzeba użycia np. kilku INSERT-ów. Jeśli różnią się one tylko wstawianymi danymi, to zamiast pisać:

c.execute("INSERT INTO users VALUES('',%s,%s)", ('user1', 'haslo1'))
c.execute("INSERT INTO users VALUES('',%s,%s)", ('user2', 'haslo2'))

Można skorzystać z metody executemany:

c.executemany("INSERT INTO users VALUES('',%s,%s)",
    ( ('user1', 'haslo1'), ('user2', 'haslo2') ))

Dostępne są też transakcje, tj. conn.begin(), conn.commit() i conn.rollback().

Więcej na temat biblioteki MySQLdb można znaleźć m.in. w dokumentacji API.

0 komentarzy