mssql-python’da Context Manager ile Kaynak Yönetimi
Python ile veritabanı işlerinde bağlantıyı açmak, imleç oluşturmak, sorguyu çalıştırmak, commit veya rollback etmek ve sonunda tüm nesneleri kapatmak zamanla tekrarlı bir ritüele dönüşür. Bu adımlardan birinin unutulması ise açık kalan bağlantılardan doğan sızıntılara ya da tutarsız veri durumlarına yol açabilir. Microsoft, mssql-python sürücüsüne eklediği context manager desteğiyle bu sorunu Python’un doğal with deyimine devrediyor ve kod tarafında belirgin bir sadelik sağlıyor.
Neden context manager?
Python’da with deyimi, kaynak yönetimi için tasarlanmış sözdizimsel bir kolaylık. Bloğa girildiğinde kaynak hazırlanır, blok bittiğinde (hata çıksa bile) temizlik otomatik yapılır. mssql-python tarafında bu destek hem bağlantı (connection) hem de imleç (cursor) düzeyinde çalışıyor; böylece elle close() çağırmaya gerek kalmıyor.
Klasik yaklaşımın sıkıntısı
Context manager desteği devreye girmeden önce tipik kullanım şöyleydi:
from mssql_python import connect
conn = connect(connection_string)
cursor = conn.cursor()
try:
cursor.execute("SELECT * FROM users")
for row in cursor:
print(row)
finally:
cursor.close()
conn.close()
Bu blok tek başına sorun çıkarmaz. Ama birden fazla imleç, çok sayıda sorgu ve iç içe geçmiş istisna yönetimi olan bir kodda her kaynağı elle kapatmak hem yorucu hem de hataya açık. Unutulan tek bir close() çağrısı bile kaynak sızıntısı demek.
Bağlantı düzeyinde context manager
Bir bağlantıyı with bloğuna aldığınızda arka planda şu davranışlar devreye giriyor:
- Blok hatasız tamamlanırsa transaction otomatik olarak commit edilir.
- Bir istisna çıkarsa değişiklikler rollback ile geri alınır.
- Her durumda bağlantı bloktan çıkarken kapatılır.
from mssql_python import connect
with connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("INSERT INTO users (name) VALUES ('Alice')")
# Hata yoksa → otomatik commit
# Hata varsa → otomatik rollback
# Bağlantı burada otomatik olarak kapanır
Aynı davranışı klasik yöntemle yazmak istediğinizde try/except/finally yapısına ek olarak autocommit kontrolünü, commit, rollback ve close çağrılarını elle yönetmeniz gerekir. Context manager bu kalıbı ortadan kaldırıyor.
Bloğa girerken ve çıkarken neler oluyor?
Bloğa girildiğinde bağlantı açılır ve blok içindeki tüm işlemler bu bağlantı üzerinden yürütülür. Bloktan çıkarken şu olur:
- İstisna yoksa ve
autocommit=Falseise transaction commit edilir. - İstisna varsa ve
autocommit=Falseise commit edilmemiş değişiklikler rollback yapılır; istisna yakalanmadıysa çağrı zincirine iletilir. - Sonuç ne olursa olsun bağlantı kapatılır.
Bu yapı özellikle insert, update, delete gibi transactional işlemlerde kod güvenliğini belirgin biçimde artırıyor.
İmleç düzeyinde context manager
Cursor nesneleri de artık with deyimini destekliyor. Ama burada bağlam transaction’a değil doğrudan cursor kaynağına bağlı:
with conn.cursor() as cursor:
cursor.execute("SELECT * FROM users")
for row in cursor:
print(row)
# Cursor burada otomatik olarak kapanır
Bloğa girildiğinde yeni bir cursor oluşturulur, tüm SQL ifadeleri bu cursor üzerinden çalışır ve blok bitiminde cursor otomatik olarak kapatılır. Cursor’ın kendisi transaction yönetmez; commit ve rollback davranışı bağlantı seviyesinde belirlenir. autocommit=True durumunda her ifade anında commit edilir, autocommit=False durumunda commit/rollback kararını bağlantıdaki context manager verir.
Bu kullanım özellikle salt okunur sorgularda cursor sızıntısı endişesini ortadan kaldırdığı için pratik.
Pratik kullanım kalıpları
Güvenli SELECT sorguları
with connect(connection_string) as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT * FROM users WHERE age > 25")
for row in cursor:
print(row)
# Cursor kapandı, bağlantı hâlâ açık
# Bağlantı da kapandı
Tek transaction içinde birden fazla işlem
with connect(connection_string) as conn:
with conn.cursor() as cursor:
cursor.execute("INSERT INTO users (name) VALUES ('Bob')")
cursor.execute("UPDATE users SET age = age + 1 WHERE name = 'Alice'")
# İstisna yoksa tüm işlemler otomatik commit edilir
Otomatik istisna yönetimi
try:
with connect(connection_string) as conn:
with conn.cursor() as cursor:
cursor.execute("INSERT INTO users (name) VALUES ('Charlie')")
raise ValueError("Oops, something went wrong")
except ValueError as e:
print("Transaction rolled back due to:", e)
# Rollback yapıldı, bağlantı da kapatıldı
Gerçek hayatta nerelerde işe yarar?
Kaynakta öne çıkarılan senaryolara bakınca context manager desteğinin özellikle şu bağlamlarda değer ürettiği görülüyor:
- Web uygulamaları: Her istek için bağlantı açılıp kapatılan yoğun trafikli servislerde açık kalan bağlantıların birikmesini önler; commit/rollback kararını otomatikleştirir.
- Veri taşıma ve ETL: Bir tablodan diğerine kopyalayıp kaynaktan silme gibi iki aşamalı işlemlerde herhangi bir adım başarısız olursa tamamı geri alındığı için kısmi migrasyon riski ortadan kalkar.
- Otomatik raporlama: Analitik için art arda çalıştırılan sorgularda her
withbloğu kendi cursor’ını kapatır; script modüler ve bakımı kolay hale gelir. - Finansal işlemler: Hesaplar arası transfer gibi tutarlılığın kritik olduğu senaryolarda hata anında otomatik rollback, çift yazma ya da eksik güncelleme riskini azaltır.
- Ad-hoc veri keşfi: Notebook veya kısa scriptlerde unutulan
close()çağrılarını ortadan kaldırır, hızlı sorgular için temiz bir kalıp sunar.
Özet
mssql-python sürücüsündeki context manager desteği, Python’un “sade olan iyidir” felsefesini SQL Server ve Azure SQL etkileşimlerine taşıyor. Elde edilen kazançlar şöyle:
- Daha az boilerplate: Cursor ve bağlantı için try/finally kalıbına gerek kalmıyor.
- Otomatik transaction yönetimi: Başarı ya da başarısızlık durumuna göre commit veya rollback kendiliğinden gerçekleşiyor.
- Güvenli kaynak temizliği: Bağlantı ve cursor’lar her koşulda kapatıldığından sızıntı riski azalıyor.
- Okunabilir ve Pythonic kod: İç içe
withblokları, kaynakların kapsamını görsel olarak da netleştiriyor.
Sürücü pip install mssql-python komutuyla kurulabiliyor; proje kodu ve tartışmalar GitHub üzerinden takip edilebiliyor. Ekip, topluluktan geri bildirim ve katkı beklediğini belirtiyor.
Kaynaklar ve İleri Okuma
- Simplifying Resource Management in mssql-python through Context Manager (orijinal yazı)
- microsoft/mssql-python (GitHub deposu)
- mssql-python paketi (PyPI)
- Sorun bildirimi (GitHub Issues)
- GitHub Discussions
- SQL Server Tech Community
- Ücretsiz Azure SQL Database dağıtımı
- Ücretsiz Azure SQL Managed Instance dağıtımı
- İlgili yazı: mssql-python’a Apache Arrow Desteği







3 comments