Takip et

Python 3’te sqlite3 Modülünü Kullanma Rehberi

Python 3’te sqlite3 Modülünü Kullanma Rehberi SQLite, sunucusuz, kendi kendine yeten, sıfır yapılandırmalı, işlemsel bir SQL veritabanı m

Python 3’te sqlite3 Modülünü Kullanma Rehberi

SQLite, sunucusuz, kendi kendine yeten, sıfır yapılandırmalı, işlemsel bir SQL veritabanı motorudur. Hafifliği, kolay entegrasyonu ve kurulum gerektirmemesi sayesinde özellikle masaüstü uygulamaları, mobil uygulamalar, web siteleri (düşük trafikli) ve geliştirme/test süreçleri için ideal bir çözümdür. Python’ın standart kütüphanesinde yer alan sqlite3 modülü, Python uygulamalarınızla SQLite veritabanları arasında sorunsuz bir köprü görevi görür. Bu rehberde, sqlite3 modülünün temel ve ileri düzey kullanımlarını, pratik örneklerle birlikte detaylı bir şekilde inceleyeceğiz.

SQLite3 Neden Kullanılmalı?

Python projelerinizde sqlite3 kullanmayı düşünmeniz için birkaç iyi neden vardır:

  • Kolay Kurulum: Harici bir sunucuya veya karmaşık bir yapılandırmaya ihtiyaç duymaz. Sadece bir dosya olarak veritabanınızı oluşturabilirsiniz.
  • Hafif ve Hızlı: Küçük ve orta ölçekli projeler için oldukça hızlı ve kaynak dostudur.
  • Gömülü Yapı: Uygulamanızın bir parçası olarak dağıtılabilir, bu da dağıtım ve yönetim maliyetlerini azaltır.
  • Standart Kütüphane: Ekstra bir paket (pip install) kurmaya gerek yoktur, Python ile birlikte gelir.
  • SQL Desteği: Standart SQL sorgu dilini kullanarak veri manipülasyonu yapmanızı sağlar.

Veritabanına Bağlanma ve Tablo Oluşturma

Bir SQLite veritabanı ile çalışmaya başlamak için öncelikle ona bağlanmanız ve ardından üzerinde işlemler yapacağınız tabloları oluşturmanız gerekir.

Veritabanına Bağlanma

sqlite3.connect() fonksiyonu ile bir veritabanı dosyasına bağlanırsınız. Eğer belirtilen isimde bir dosya yoksa, otomatik olarak oluşturulur.


import sqlite3

veritabani.db adında bir dosyaya bağlan

Eğer dosya yoksa, bu isimde yeni bir veritabanı dosyası oluşturulur.

":memory:" kullanarak bellek içi (geçici) bir veritabanı da oluşturabilirsiniz.

try: conn = sqlite3.connect('ornek_veritabani.db') print("Veritabanına başarıyla bağlanıldı.") except sqlite3.Error as e: print(f"Veritabanına bağlanırken hata oluştu: {e}")

Veritabanı üzerinde işlem yapmak için bir imleç (cursor) nesnesi oluşturulur.

İmleç, SQL komutlarını yürütmek ve sonuçları almak için kullanılır.

cursor = conn.cursor()

Tablo Oluşturma

Bağlantı kurulduktan sonra, SQL CREATE TABLE komutunu kullanarak tablolarınızı oluşturabilirsiniz. cursor.execute() metodu, SQL sorgularını çalıştırmak için kullanılır.


'kullanicilar' adında bir tablo oluşturalım.

id: Otomatik artan birincil anahtar

ad: Metin türünde, boş olamaz

email: Metin türünde, benzersiz ve boş olamaz

yas: Tam sayı türünde

try: cursor.execute(''' CREATE TABLE IF NOT EXISTS kullanicilar ( id INTEGER PRIMARY KEY AUTOINCREMENT, ad TEXT NOT NULL, email TEXT NOT NULL UNIQUE, yas INTEGER ) ''') # Değişiklikleri veritabanına kaydet (commit et) conn.commit() print("Kullanicilar tablosu başarıyla oluşturuldu veya zaten mevcut.") except sqlite3.Error as e: print(f"Tablo oluşturulurken hata oluştu: {e}")

İşlem bittikten sonra bağlantıyı kapatmak önemlidir.

Ancak, şimdilik açık bırakıyoruz ki sonraki işlemleri yapabilelim.

conn.close()

conn.commit() çağrısı, yapılan değişiklikleri kalıcı olarak veritabanına kaydeder. CREATE TABLE gibi DDL (Veri Tanımlama Dili) işlemleri için de commit önemlidir.

CRUD Operasyonları: Veri Ekleme, Okuma, Güncelleme, Silme

Veritabanı işlemlerinin temelini oluşturan CRUD (Create, Read, Update, Delete) operasyonları, sqlite3 modülü ile kolayca gerçekleştirilebilir.

Veri Ekleme (INSERT)

INSERT INTO komutu ile tabloya yeni kayıtlar ekleyebilirsiniz. SQL enjeksiyon saldırılarını önlemek ve veri tipleriyle ilgili sorunları gidermek için parametreli sorgular kullanmak en iyi uygulamadır.


Tek bir kullanıcı ekleme

try: cursor.execute("INSERT INTO kullanicilar (ad, email, yas) VALUES (?, ?, ?)", ("Ali Can", "ali.can@example.com", 25)) conn.commit() print("Ali Can başarıyla eklendi.") except sqlite3.Error as e: print(f"Veri eklenirken hata oluştu: {e}")

Birden fazla kullanıcı ekleme (executemany)

kullanicilar_listesi = [ ("Ayşe Yılmaz", "ayse.yilmaz@example.com", 30), ("Mehmet Demir", "mehmet.demir@example.com", 22), ("Fatma Kaya", "fatma.kaya@example.com", 28) ] try: cursor.executemany("INSERT INTO kullanicilar (ad, email, yas) VALUES (?, ?, ?)", kullanicilar_listesi) conn.commit() print("Birden fazla kullanıcı başarıyla eklendi.") except sqlite3.Error as e: print(f"Toplu veri eklenirken hata oluştu: {e}")

Veri Okuma (SELECT)

SELECT komutu ile tablodaki verileri sorgulayabilirsiniz. cursor nesnesi, sorgu sonuçlarını almak için çeşitli metodlar sunar:

  • fetchone(): Sorgunun bir sonraki satırını döndürür veya başka satır yoksa None döndürür.
  • fetchall(): Sorgunun tüm kalan satırlarını bir liste olarak döndürür.
  • fetchmany(size): Sorgunun sonraki size kadar satırını döndürür.
  • Doğrudan cursor üzerinde döngü yapmak: Her satırı tek tek işlemek için kullanılabilir.

Tüm kullanıcıları seçme

print("\n--- Tüm Kullanıcılar ---") cursor.execute("SELECT id, ad, email, yas FROM kullanicilar") for row in cursor.fetchall(): print(f"ID: {row[0]}, Ad: {row[1]}, Email: {row[2]}, Yaş: {row[3]}")

Belirli bir koşula göre kullanıcı seçme

print("\n--- Yaşı 25'ten Büyük Kullanıcılar ---") cursor.execute("SELECT ad, email FROM kullanicilar WHERE yas > ?", (25,)) for row in cursor.fetchall(): print(f"Ad: {row[0]}, Email: {row[1]}")

Tek bir sonuç döndürme (fetchone)

print("\n--- İlk Kullanıcı ---") cursor.execute("SELECT ad FROM kullanicilar ORDER BY id LIMIT 1") ilk_kullanici = cursor.fetchone() if ilk_kullanici: print(f"İlk kullanıcı adı: {ilk_kullanici[0]}")

Varsayılan olarak, fetchone() ve fetchall() metodları, satırları tuple olarak döndürür. Sütunlara isimleriyle erişmek isterseniz, conn.row_factory = sqlite3.Row ayarını yapabilirsiniz. Bunu “İleri Seviye Konular” bölümünde ele alacağız.

Veri Güncelleme (UPDATE)

UPDATE komutu ile mevcut bir kaydın verilerini değiştirebilirsiniz. WHERE koşulu, hangi kayıtların güncelleneceğini belirler.


Bir kullanıcının yaşını güncelleme

try: cursor.execute("UPDATE kullanicilar SET yas = ? WHERE ad = ?", (26, "Ali Can")) conn.commit() print("\nAli Can'ın yaşı başarıyla güncellendi.") except sqlite3.Error as e: print(f"Veri güncellenirken hata oluştu: {e}")

Güncellenmiş veriyi kontrol edelim

print("\n--- Güncellenmiş Ali Can ---") cursor.execute("SELECT ad, yas FROM kullanicilar WHERE ad = 'Ali Can'") updated_ali = cursor.fetchone() if updated_ali: print(f"Ad: {updated_ali[0]}, Yeni Yaş: {updated_ali[1]}")

Veri Silme (DELETE)

DELETE FROM komutu ile tablodan kayıtları silebilirsiniz. WHERE koşulu, hangi kayıtların silineceğini belirler. Koşul belirtmezseniz, tablodaki tüm kayıtlar silinir!


Bir kullanıcıyı silme

try: cursor.execute("DELETE FROM kullanicilar WHERE ad = ?", ("Mehmet Demir",)) conn.commit() print("\nMehmet Demir başarıyla silindi.") except sqlite3.Error as e: print(f"Veri silinirken hata oluştu: {e}")

Silme sonrası kalan kullanıcıları kontrol edelim

print("\n--- Silme Sonrası Kalan Kullanıcılar ---") cursor.execute("SELECT ad FROM kullanicilar") for row in cursor.fetchall(): print(f"Kalan Kullanıcı: {row[0]}")

İleri Seviye Konular ve En İyi Uygulamalar

Daha sağlam ve güvenilir veritabanı etkileşimleri için bazı ileri seviye konuları ve en iyi uygulamaları bilmek önemlidir.

Hata Yönetimi ve İşlemler (Transactions)

Veritabanı işlemleri sırasında hatalar meydana gelebilir. Bu gibi durumlarda, veritabanının tutarlılığını sağlamak için işlemleri geri almak (rollback) önemlidir. Python’da try...except...finally blokları bu amaçla kullanılabilir. sqlite3 modülü, varsayılan olarak her execute() çağrısını bir işlem (transaction) içinde başlatır. commit() ile işlem onaylanır, rollback() ile geri alınır.


try:
    # Hatalı bir sorgu çalıştırmaya çalışalım (örneğin, olmayan bir sütuna veri ekleme)
    cursor.execute("INSERT INTO kullanicilar (ad, olmayan_sutun) VALUES (?, ?)",
                   ("Deneme", "deger"))
    conn.commit()
    print("Hatalı ekleme başarılı oldu (beklenmedik).")
except sqlite3.Error as e:
    print(f"\nHata yakalandı: {e}")
    conn.rollback() # Hata durumunda değişiklikleri geri al
    print("Değişiklikler geri alındı (rollback).")
finally:
    # Bağlantıyı her zaman kapatmak için 'finally' bloğu kullanılır.
    # Ancak, 'with' ifadesi daha güvenli bir yöntemdir.
    # conn.close() # Şimdilik kapatmıyoruz, 'with' örneğine geçeceğiz.
    pass

with İfadesi ile Kaynak Yönetimi (Context Manager)

sqlite3 bağlantı nesnesi, bir bağlam yöneticisi (context manager) olarak kullanılabilir. Bu, with ifadesi ile bağlantıyı açıp kapatmayı ve commit/rollback işlemlerini otomatik olarak yönetmeyi sağlar. Bu, en çok önerilen yaklaşımdır.


'with' ifadesi ile bağlantı yönetimi

try: with sqlite3.connect('ornek_veritabani.db') as conn_with: cursor_with = conn_with.cursor() # Yeni bir tablo oluşturalım cursor_with.execute(''' CREATE TABLE IF NOT EXISTS urunler ( id INTEGER PRIMARY KEY AUTOINCREMENT, ad TEXT NOT NULL, fiyat REAL NOT NULL ) ''') print("\nUrunler tablosu 'with' ile oluşturuldu.") # Veri ekleme cursor_with.execute("INSERT INTO urunler (ad, fiyat) VALUES (?, ?)", ("Laptop", 1200.50)) cursor_with.execute("INSERT INTO urunler (ad, fiyat) VALUES (?, ?)", ("Mouse", 25.00)) print("Ürünler eklendi.") # Bu noktada, 'with' bloğundan normal çıkışta otomatik olarak conn_with.commit() çağrılır. # Eğer blok içinde bir hata oluşursa, otomatik olarak conn_with.rollback() çağrılır. except sqlite3.Error as e: print(f"Hata oluştu: {e}. Değişiklikler geri alındı.")

'with' bloğu dışında bağlantı otomatik olarak kapatılmış olur.

Şimdi verileri okuyabiliriz (yeni bir bağlantı açarak)

try: with sqlite3.connect('ornek_veritabani.db') as conn_read: cursor_read = conn_read.cursor() print("\n--- 'with' ile eklenen Ürünler ---") cursor_read.execute("SELECT ad, fiyat FROM urunler") for row in cursor_read.fetchall(): print(f"Ürün: {row[0]}, Fiyat: {row[1]}") except sqlite3.Error as e: print(f"Veri okunurken hata oluştu: {e}")

row_factory Kullanımı

Varsayılan olarak, sqlite3 sorgu sonuçlarını tuple olarak döndürür. Sütunlara isimleriyle erişmek, kodun okunabilirliğini artırır. Bunu sağlamak için conn.row_factory = sqlite3.Row ayarını yapabilirsiniz. sqlite3.Row nesneleri, hem indeks hem de sütun ismi ile erişimi destekleyen tuple benzeri yapılardır.


with sqlite3.connect('ornek_veritabani.db') as conn_factory:
    conn_factory.row_factory = sqlite3.Row # Bu satır çok önemli!
    cursor_factory = conn_factory.cursor()

    print("\n--- row_factory ile Kullanıcılar ---")
    cursor_factory.execute("SELECT id, ad, email, yas FROM kullanicilar")
    for row in cursor_factory.fetchall():
        print(f"ID: {row['id']}, Ad: {row['ad']}, Email: {row['email']}, Yaş: {row['yas']}")
        # Ayrıca indeks ile de erişebilirsiniz: print(f"Ad: {row[1]}")

Parametreli Sorguların Önemi

Daha önce de belirttiğimiz gibi, parametreli sorgular SQL enjeksiyon saldırılarını önlemek ve veri tiplerini otomatik olarak dönüştürmek için kritik öneme sahiptir. Kullanıcıdan gelen girdileri doğrudan SQL sorgusu içine birleştirmek yerine, her zaman ? (question mark) veya :param_adı (named parameter) gibi yer tutucular kullanın.


Güvenli (Parametreli) Sorgu

kullanici_adi = "Deneme" kullanici_yasi = 40 cursor.execute("INSERT INTO kullanicilar (ad, email, yas) VALUES (?, ?, ?)", (kullanici_adi, f"{kullanici_adi.lower()}@example.com", kullanici_yasi)) conn.commit()

Güvenli değil (SQL Injection riski var!)

kullanici_input = "Birisi'); DROP TABLE kullanicilar; --"

cursor.execute(f"INSERT INTO kullanicilar (ad) VALUES ('{kullanici_input}')")

ASLA BÖYLE KULLANMAYIN!

Sonuç ve Sıkça Sorulan Sorular (SSS)

sqlite3 modülü, Python uygulamalarınıza hafif ve güçlü bir veritabanı yeteneği eklemek için mükemmel bir araçtır. Bağlantı kurma, tablo oluşturma, CRUD operasyonları ve ileri düzey özellikler sayesinde, birçok senaryoda ihtiyaçlarınızı karşılayabilir. with ifadesini kullanarak kaynakları doğru yönetmek ve parametreli sorgularla güvenliği sağlamak, iyi bir uygulama geliştirmenin temelidir.

Sıkça Sorulan Sorular (SSS)

SQLite nedir?
SQLite, sunucusuz, kendi kendine yeten, sıfır yapılandırmalı, işlemsel bir SQL veritabanı motorudur. Bir dosya olarak depolanır ve harici bir sunucuya ihtiyaç duymaz.
Neden Python’da sqlite3 kullanmalıyım?
Hafif, kurulum gerektirmeyen, Python’ın standart kütüphanesinin bir parçası olan ve küçük/orta ölçekli projeler, masaüstü uygulamaları veya testler için ideal bir veritabanı çözümüdür.
Veritabanı dosyası nerede oluşur?
sqlite3.connect('veritabani.db') kullandığınızda, veritabani.db dosyası, Python betiğinizin çalıştığı dizinde oluşur.
SQL injection saldırılarından nasıl korunurum?
Her zaman parametreli sorgular kullanın. Kullanıcıdan gelen verileri doğrudan SQL sorgu dizelerine birleştirmek yerine, ? veya :param_adı gibi yer tutucular kullanarak verileri ayrı bir tuple veya dictionary olarak geçirin. sqlite3 modülü bu verileri güvenli bir şekilde işleyecektir.
Yaptığım değişiklikler neden kaydedilmiyor?
Veri manipülasyonu (INSERT, UPDATE, DELETE) veya tablo yapısı değişiklikleri (CREATE TABLE, ALTER TABLE) yaptıktan sonra conn.commit() çağrısını yapmanız gerekir. Aksi takdirde, değişiklikler bellekte kalır ve bağlantı kapatıldığında kaybolur. with ifadesini kullanmak, bu işlemi otomatik olarak yönetir.
Aynı anda birden fazla kullanıcı bir SQLite veritabanına erişebilir mi?
Evet, ancak yüksek eşzamanlı yazma işlemleri için tasarlanmamıştır. Birden fazla okuyucu aynı anda erişebilirken, yazma işlemleri genellikle kilitlenir ve tek seferde sadece bir yazma işlemi gerçekleşebilir. Yüksek eşzamanlılık gerektiren uygulamalar için PostgreSQL veya MySQL gibi sunucu tabanlı veritabanları daha uygundur.
Bellek içi veritabanı (:memory:) ne işe yarar?
sqlite3.connect(':memory:') ile oluşturulan veritabanları, sadece uygulamanızın çalıştığı süre boyunca bellekte tutulur ve bağlantı kapatıldığında tüm veriler kaybolur. Bu, özellikle testler veya geçici veri depolama için kullanışlıdır.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.