[python] Podivné: MySQLdb pod Windows 7 nezapisuje do ta bulky

Hynek Fabian hynek.fabian na firma.seznam.cz
Pondělí Prosinec 10 16:54:58 CET 2012


> Kdyz jsem kontroloval nastaveni: SELECT @@AUTOCOMMIT;
> tak daval sice 1, ale nefungovalo to.
> Teprve kdyz jsem po INSERT INTO a UPDATE pouzil COMMIT;
> zacalo to fungovat spravne. Nevim kde je chyba.
To neni chyba ale vlastnost. Viz PEP 249:

"Closing a connection without committing the changes first will cause an
implicit rollback to be performed."

Logika je takova, ze metody commit() i rollback() ihned  zacnou dalsi
transakci, takze vzdy jde rollbackovat. Tim padem v dobre napsany
aplikaci kdyz nekde vystreli vyjimka, destruktor spojeni po sobe uklidi
a data zustanou konzistentni. Jako bonus nemusis psat "begin" :-)
BTW resit to pres execute("COMMIT") taky neni nejlepsi napad.
Na to je metoda commit(), ktera zaroven doplnuje nejakou dalsi logiku
(zacne dalsi transakci). U MySQL je to mozna jedno, ale pythoni DB API
je takhle vymysleny proto aby slo snadno portovat mezi ruzny databaze,
ktery uz nemusi byt tak benevolentni (a tupy) jako MySQL.
(A IMO ti budou padat porad warningy ze rollbackujes mimo transakci)

Navic MySQLdb na to ma udelanej contexmanager, takze se da napsat neco jako:

with conn as cur:
    cur.execute("DELETE FROM world")
    cur.execute("INSERT …")

pokud v takovym bloku vystreli vyjimka, udela se rollback hned a ne az
pri destrukci objektu spojeni. (Vyjimka se propaguje dal jako obvykle)
Kdyz zadna vyjimka nenastane udela se automaticky commit na konci bloku.


Další informace o konferenci Python