Bir uygulama geliştirirken verileri sadece saklamak yetmez; onları güvenli, tutarlı ve performanslı bir şekilde yönetmek gerekir. Birçok geliştirici SQLite’ı sadece basit bir dosya depolama aracı olarak görse de, doğru mimariyle kullanıldığında kurumsal düzeyde güvenli CRUD (Create, Read, Update, Delete) işlemleri gerçekleştirebilirsiniz. Peki, veritabanı bağlantılarını nasıl yönetmelisiniz? SQL Injection saldırılarını nasıl engellersiniz? İşlemler (transactions) sırasında bir hata oluşursa verilerin bozulmasını nasıl önlersiniz?
Veri Yönetiminde Profesyonel Yaklaşım
Veritabanı işlemleri söz konusu olduğunda en büyük riskler, açık kalan bağlantılar ve hatalı sorgulardır. Geliştirdiğimiz bu projede, SQLite’ın gücünü Python’ın modern yetenekleriyle birleştirerek “güvenli bir veri yönetim motoru” inşa ettik.
Sistemimiz, bir envanter yönetim senaryosu üzerinden çalışıyor. Ürün ekleme, stok güncelleme ve silme gibi temel işlemleri gerçekleştirirken, arka planda otomatik işlem yönetimi (transaction management) ve sıkı parametreleştirme kuralları uyguluyor. Böylece, bir işlem sırasında elektrik kesintisi veya yazılımsal bir hata olsa bile, veritabanı ya tamamen güncelleniyor ya da eski güvenli haline geri dönüyor (rollback).
Kodun Anatomisi
Bu projenin merkezinde, veritabanı yaşam döngüsünü yöneten DatabaseManager sınıfı ve Python’ın contextlib modülü yer alıyor.
1. Bağlam Yöneticileri ile Otomatik İşlemler (Context Managers)
Veritabanı bağlantılarını manuel olarak açıp kapatmak, bağlantı sızıntılarına (connection leaks) yol açabilir. @contextmanager dekoratörünü kullanarak kendi connection() metodumuzu yazdık. Bu yapı sayesinde:
- Bağlantı otomatik olarak açılır.
- İşlem başarıyla tamamlanırsa
conn.commit()ile kaydedilir. - Herhangi bir hata oluşursa
conn.rollback()ile tüm değişiklikler geri alınır ve veritabanı tutarlılığı korunur.
2. SQL Injection Engelleme (Parameterized Queries)
Asla ama asla SQL sorgularının içine kullanıcıdan gelen verileri f-string veya .format() ile yerleştirmeyin! Bu, SQL Injection saldırılarına kapı açar. Projemizde ? yer tutucularını (placeholder) kullandık. Python’ın sqlite3 modülü, bu değerleri güvenli bir şekilde temizleyerek sorguya ekler, böylece kötü niyetli kodların çalışması imkansız hale gelir.
3. Sözlük Benzeri Satırlar (sqlite3.Row)
Varsayılan olarak SQLite satırları tuple (demet) olarak döner (örneğin: (1, 'SKU01', 'Klavye', ...)). Hangi sütunun ne olduğu karıştığında kod okunabilirliği düşer. conn.row_factory = sqlite3.Row ayarı ile satırları sözlük gibi kullanabiliyoruz. Artık row[0] yerine row['name'] diyerek verilere çok daha okunaklı bir şekilde erişebiliyoruz.
import sqlite3
from contextlib import contextmanager
class DatabaseManager:
def __init__(self, db_name="inventory.db"):
self.db_name = db_name
@contextmanager
def connection(self):
conn = sqlite3.connect(self.db_name)
conn.row_factory = sqlite3.Row # Satırları sözlük gibi kullanma
try:
yield conn
conn.commit()
except Exception as e:
conn.rollback() # Hata anında geri al
raise e
finally:
conn.close()
# Güvenli veri ekleme örneği
def create_item(db, sku, name, qty, price):
query = "INSERT INTO inventory_items (sku, name, quantity, price) VALUES (?, ?, ?, ?);"
with db.connection() as conn:
conn.execute(query, (sku, name, qty, price))
Nasıl Çalıştırılır?
Bu proje ek bir kütüphane gerektirmez; Python’ın standart kütüphanesindeki sqlite3 modülü yeterlidir.
- Proje dizinine girin:
cd 29_sqlite_advanced - Uygulamayı çalıştırın:
python main.py
Çalıştırdığınızda, sistem önce şemayı oluşturacak, ardından güvenli bir şekilde ürünler ekleyecek ve stok güncellemeleri yapacaktır. Ayrıca, mükerrer (duplicate) SKU ekleme denemesiyle veritabanı kısıtlamalarının (constraints) nasıl çalıştığını gözlemleyebilirsiniz.
Ne Öğrendik?
Bu proje ile modern veritabanı yönetiminin temel taşlarını uyguladık:
- Atomik İşlemler: İşlemlerin “ya hep ya hiç” prensibiyle (Atomicity) çalışması gerektiğini ve
rollbackmekanizmasının önemini gördük. - Güvenlik: Parametreleştirilmiş sorguların, siber saldırılara karşı en etkili savunma hattı olduğunu öğrendik.
- Okunabilirlik:
sqlite3.Rowkullanarak veritabanı çıktılarını daha yönetilebilir ve anlaşılır kıldık. - Yaşam Döngüsü Yönetimi: Context manager kullanarak kaynak yönetimini otomatize ettik.
Kaynaklar ve Sonraki Adımlar
SQLite, başlangıç için harikadır ancak projeniz büyüdüğünde PostgreSQL veya MySQL gibi istemci-sunucu tabanlı sistemlere geçmek isteyebilirsiniz. SQL dilinin temelleri her yerde aynıdır; bu yüzden burada öğrendiğiniz parametreleştirme ve işlem yönetimi mantığı tüm profesyonel veritabanlarında geçerlidir. Daha fazla detay için SQLite resmi dökümanlarını inceleyebilirsiniz.
Ahmet Aksoy
Not: Bu yazıda incelediğimiz kodu ve benzer projelerin kaynak kodlarını https://github.com/ahmetax/practical-python-examples adresinde bulabilirsiniz.
python, sqlite, veritabanı, sql injection, crud, veritabanı yönetimi, orta seviye, yazılım geliştirme