Próbka kodu, z jakim się zmagałem przez dłuższy czas:
[mysz@urzenia ~/p/python/mtalog]% python2.5
Python 2.5.1 (r251:54863, May 2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> db = sqlite3.connect(':memory:')
>>> cur = db.cursor()
>>> cur.execute('BEGIN')
<sqlite3.Cursor object at 0x40201f80>
>>> cur.execute('CREATE TABLE `test` (`id` INTEGER PRIMARY KEY, data TEXT)')
<sqlite3.Cursor object at 0x40201f80>
>>> cur.execute('COMMIT')
<sqlite3.Cursor object at 0x40201f80>
>>> cur.execute('BEGIN')
<sqlite3.Cursor object at 0x40201f80>
>>> cur.execute('INSERT INTO `test` (`data`) VALUES ("asd")')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
sqlite3.OperationalError: SQL logic error or missing database
>>>
Co bym nie zrobił, wysypywało się albo z powyższym wiele mówiącym błędem, albo też chodziło czysto, a po zakmnięciu połączenia (oczywiście nie mówię tutaj o bazie testowej założonej w ramie, jak w przykładzie) baza była pusta. Nawalczyłem się z tym nieco… a rozwiązanie, jak to w życiu, jest banalne.
pysqlite działa natywnie w takim pseudo-trybie autocommita. Nieco próba automatyzacji. Generalnie polega to mniej więcej na tym, że sam zaczyna transakcję jeśli trafi na polecenie INSERT/UPDATE/DELETE/REPLACE, ale w sumie nie doczytałem kiedy ją kończy. Mało mnie to interesuje, bo ja chcę ręcznie zaczynać i kończyć transakcje, a automatyzacja w/w zawiodła (jak pisałem: po zakończeniu połączenia danych w bazie niet :/ ).
Aby kontrolować tryb w jakim pysqlite rozpoczyna i kończy transakcje, potrzeba zmienić wartość właściwości isolation_level naszego połączenia z bazą. W moim przypadku najbardziej pasująca wartość to None, w związku z czym nawiązanie połączenia z bazą będzie wyglądało w ten sposób:
[...]
self.db.connect ( '/path/to/db.sqlite3' )
self.db.isolation_level = None
[...]
Od tego momentu sqlite czyna tańczyć jak mu każemy, czyli możemy ręcznie rozpoczynać transakcję, wybierać jej rodzaj, kończyć transakcję czy też ją ROLLBACKnąć etc. W końcu…
A niniejszy wpis dedykuję wszystkim którzy podobnie jak ja walczyli przez kilka/kilkanaście godzin nad taką głupotą :/
Taka prawda życiowa, że małe problemy często zaskakują trywialnym rozwiązaniem ale i ogromem czasu poświeconemu znalezieniu tego jednego małego kłopotu. Jak w pracy, tak i w zyciu ;)
Adres bezpośredni: http://urzenia.net/342/python-sqlite3-i-transakcje/#comment-31968
Heheh, ano :) Ważne jednak, aby raz, znaleźć roziwązanie problemu, a dwa, miec jeszcze z tego satysfakcję :)
Adres bezpośredni: http://urzenia.net/342/python-sqlite3-i-transakcje/#comment-32087