Dün, veri toplama botumu yazıyordum. Her şey mükemmel çalışıyordu. SQLite veritabanına, Selenium ile topladığım verileri düzenli olarak yazıyordu. Saatlerce çalıştı, binlerce satır... Akşam "İşte bu kadar!" deyip script'i kapatıp mutlu mesut bilgisayarı kapattım.
Sabah kontrol etmek için veritabanını açtığımda, gördüğüm manzara karşısında küçük dilimi yutacaktım. Tablo bomboştu! Sanki hiç çalışmamıştım gibi. Kafayı yiyecektim, "Kesin bir yerlerde bir DELETE FROM yazdım da fark etmedim" diye kendi kodumu saatlerce didik didik ettim. StackOverflow'da bile böyle saçma bir sorun görmemiştim.
Meğerse sorun şuradaymış: Veritabanı bağlantısını açıp, işlemleri bir transaction içinde yapıyordum. Her şeyi doğru yazmışım, INSERT'ler sorunsuz çalışıyor. Ama o ne? Script sonlanırken .commit() metodunu çağırmayı UNUTMUŞUM!
Python:
import sqlite3
conn = sqlite3.connect('verilerim.db')
cursor = conn.cursor()
# Transaction otomatik başladı...
try:
for veri in dev_veri_kumesi:
cursor.execute("INSERT INTO tablom VALUES (?, ?)", veri)
# conn.commit() # <--- İŞTE LANET OLAY BU SATIR! YORUM SATIRINDA KALMIŞ!
except Exception as e:
conn.rollback()
finally:
conn.close() # Commit yok, tüm işlemler geri alınıyor!
Script normal sonlandığında, açık kalan transaction otomatik olarak ROLLBACK oluyormuş! Yani tüm gün boyunca yazdığım her şey, connection kapanırken silinip gitmiş. Şaka gibi ama gerçek.
Artık with statement kullanıyorum veya commit satırını yazmadan asla kodumu çalıştırmıyorum. Autocommit modunu da düşünebilirsiniz ama büyük işlemlerde transaction'ın gücünden vazgeçmek istemezsiniz.
Siz de böyle "commit" unutkanlığı yaşadınız mı? Ya da SQLite'da bu durumu otomatik yakalamanın temiz bir yolu var mı? "Ben şöyle yapıyorum" diyen varsa lütfen yazsın, bir daha aynı hatayı yapmayalım!