Internet Technologies & News

MySQL i mod_python

W tym How To opiszę sposób używania baz MySQL w Pythonie.

I. Czego potrzebujemy

  1. Poprawnie skonfigurowany mod_python.
  2. Skonfigurowany moduł MySQLdb dla Pythona.
  3. Znajomość Pythona jak na poziomie how to nr1 ( tutaj )
  4. Podstawowa znajomość MySQL

II. Problemy już na samym początku

Może zdarzyć się ze MySQLdb jest skonfigurowany w taki sposób, że pliki tymczasowe domyślnie odnoszone są do /tmp/egg. Wtedy nasza aplikacja web zwróci błąd o braku praw dostępu do ww. katalogu.
Trzeba zmienną PYTHONEGGCACHE wskazać na katalog do którego mamy pełny dostęp ( na przykład ~/tmp ).
W tym celu najprościej w naszej aplikacji web w pierwszych linijkach ustawić należy tą zmienną:

1
2
from os import environ
environ['PYTHON_EGG_CACHE']='/pelna/sciezka/do/katalogu/'

III. Podłączanie się do bazy

1
2
3
4
5
6
import MySQLdb
from MySQLdb import cursors
db=MySQLdb.connect(host=host,user=user,
    passwd=haslo,db=nazwa_bazy, use_unicode=False,
    charset='latin1',
    cursorclass=MySQLdb.cursors.DictCursor)

Linie 1 - 2: bez komentarza.
Linie 3 - 6: Jest to jedno polecenie rozbite w linie na potrzeby formatowania tekstu w how to. Ustalamy parametry naszego połączenia z bazą danych. Oprócz 3 ostatnich parametrów powinno być wszystko jasne.

  1. use_unicode - parametr informujący MySQL czy chcemy używać unicode.
  2. charset - parametr ustawiający kodowanie znaków w MySQL nie zważając na poszczególne kodowania w tabelach bazy danych ( nie stosować jeśli use_unicode=True )
  3. cursorclass - w tym przypadku ustawiam kursor bazy danych który w wyniku zwraca tuplę dwuelementową: słownik z wartościami wynikowymi, oraz ilość pasujących wyników ( jak len())

IV. Wykonanie zapytania

1
2
3
c=db.cursor()
c.execute("""komenda MySQL""", 
    (wartosci, do, przypisania))

Linia 1 : zainicjowanie kursora
Linia 2 : wykonanie zapytania do MySQL.

V. Przykład zapytania

Poprawnie:

1
2
3
4
5
6
c=db.cursor()
c.execute("""SELECT autor,tresc 
    FROM post WHERE 
    id=%s AND typ=%s""", (2, norm))
wart=c.fetchall()[0]
c.close()

Nie poprawnie:

1
2
3
4
5
6
c=db.cursor()
c.execute("""SELECT autor,tresc 
    FROM post WHERE id=%s 
    AND typ=%s"""%(2, norm))
wart=c.fetchall()[0]
c.close()

Różnice ?:
Na pierwszy rzut oka żadne oprócz znaku po “”". Otóż używając powodujemy, że argumenty pobierane z tupli wartości ( w naszym przypadku (2, norm) ) pobierane są jako string, więc ktoś w łatwy sposób może wykonać praktycznie dowolną komendę ( SQL injection ), po prostu NIE UŻYWAĆ znaku % w wypadku wykonywania zapytań SQL.
Składnia “poprawna” automatycznie “zabezpiecza” niebezpieczne znaki, między innymi poprzez dodawanie znaku \, powoduje ona, że znaki te traktowane są bez żadnych specjalnych, przypisanych im własności w składni MySQL.

Dzięki wart=c.fetchall()[0] pobieramy wszystkie wyniki jakie zwróciło zapytanie. wart jest słownikiem ( wart[0][’tresc’] zwraca nam treść pierwszej pobranej pary autor, tresc, wart[1][’autor’] - autora drugiej itd)

Dlaczego c.fetchall()[0] ?: Samo c.fetchall() zwraca tuplę 2 elementową, pożądane przez nas wartości oraz ilość par wartości które zostały pobrane ( ilość można pobrać też na przykład poprzez: len=c.execute(”"”komenda MySQL”"”) )

Dostępne jest też przydatne:

1
c.fetchone()

Które pobiera tylko jeden wynik.
Ale NIE zastępuje opcji LIMIT 1 w SQL.

Koniec

To by było na tyle.
W razie wątpliwości proszę pisać.

Kolejne How To niedługo.

Napisz komentarz

Musisz być zalogowany aby napisać komentarz.