mssql-python ile bağlantıları yönetin

Çoğu uygulama basit bir desen izler: bir bağlantı açın, sorgular çalıştırın, bağlantıyı kapatın. Aşağıdaki bölümler bağlantıların açılması ve kapatılması, bağlam yöneticilerinin kullanımı, otomatik bağlanmanın yapılandırılması ve bağlantı özellikleriyle çalışmayı ele alır.

Bağlantı açın

Bağlantı kurmak için fonksiyonu connect() kullanın. Sunucunuzu, veritabanınızı ve kimlik doğrulama bilgilerinizi bir bağlantı dizesi ile paylaşın:

import mssql_python

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;Database=<database>;"
    "Authentication=ActiveDirectoryDefault;Encrypt=yes"
)

Fonksiyon connect() şunları kabul eder:

  • İlk konumsal argüman olarak bir bağlantı dizesi veya connection_str anahtar kelimesi.
  • Sürücünün bağlantı dizesine birleştirdiği bireysel anahtar kelimeler.
  • autocommit, timeout ve attrs_before gibi diğer seçenekler.

Her iki yaklaşımı da karıştırabilirsiniz. Anahtar sözcükler, bağlantı dizesindeki değerlerin üzerine yazabilir; bu, yapılandırmada temel bir bağlantı dizesi depolayıp her çağrıda timeout gibi ayarları geçersiz kıldığınızda kullanışlıdır:

# Base connection string from config, with per-call overrides
conn = mssql_python.connect(
    "Server=<server>.database.windows.net;Database=<database>;"
    "Authentication=ActiveDirectoryDefault;Encrypt=yes",
    timeout=30,
    autocommit=True
)

Bağlantıyı kapat

Bağlantılar bittiğinde her zaman kapatıp bağlantı havuzuna geri döndürün ve sunucu kaynaklarını serbest bırakın. Kapatılmamış bağlantılar sunucu tarafı belleği tutar ve sonunda bağlantı havuzunu tükendirebilir, bu da yeni bağlantı girişimlerinin engellenmesine veya başarısız olmasına neden olabilir.

conn = mssql_python.connect(connection_string)
try:
    # Use the connection
    cursor = conn.cursor()
    cursor.execute("SELECT 1")
finally:
    conn.close()

Kapatıldıktan sonra bağlantı kullanılamaz:

conn.close()
print(conn.closed)  # True

# This raises an error
cursor = conn.cursor()  # InterfaceError: Cannot create cursor on closed connection

Birden fazla kez aramak close() güvenlidir (idempotent):

conn.close()
conn.close()  # No error

Bağlam yöneticileri

Çoğu uygulamada bağlantıları yönetmek için bu with ifadeyi kullanın. Bloktan çıkıldığında, bir istisna oluşsa bile sürücünün bağlantıyı kapatmasını garanti eder. Bu yaklaşım, unutulmuş close() çağrılardan kaynaklanan bağlantıların sızdırma riskini ortadan kaldırır:

with mssql_python.connect(connection_string) as conn:
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE #Demo (Name NVARCHAR(50))")
    cursor.execute("INSERT INTO #Demo (Name) VALUES ('Widget')")
    conn.commit()  # Must commit explicitly when autocommit=False
# Connection automatically closed

Bağlam yöneticisi çıkışta bağlantıyı kapatıyor. İşlemleri otomatik olarak kabul etmez veya geri alamaz:

  • Her zaman: Çıkışta, bir özel durum oluşsa da oluşmasa da close() çağrılır.
  • close() davranış: autocommit=False ise, kaydedilmemiş değişiklikler bağlantı kapandığında geri alınır.
  • Değişiklikleri kalıcı olarak kaydetmek için conn.commit() çağrısını açıkça yapmalısınız.

Bu tasarım, PEP 249 davranışını takip eder ve kazara kısmi taahhütleri önler. Kodunuz commit() öğesine ulaşmadan önce bir özel durum oluşursa, sürmekte olan işlem güvenli bir şekilde geri alınır:

# Equivalent manual code:
conn = mssql_python.connect(connection_string)
try:
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE #Demo (Name NVARCHAR(50))")
    cursor.execute("INSERT INTO #Demo (Name) VALUES ('Widget')")
    conn.commit()  # Must commit explicitly
finally:
    conn.close()  # Rolls back uncommitted changes if autocommit=False

Otomatik onay modu

Varsayılan olarak, autocommit=False, bu da her ifadenin örtük bir işlem içinde çalıştığı anlamına gelir. Değişiklikleri kaydetmek için conn.commit() veya bunlardan vazgeçmek için conn.rollback() çağırmalısınız. İmplicit işlemler, veri değişiklikleri için en güvenli seçimdir çünkü birden fazla ifadeyi tek bir atomik işlemde gruplamanıza olanak tanır.

Her ifadenin hemen işlenmesini istiyorsanız otomatik işlemeyi etkinleştirin. Otomatik taahhüt, işlem gruplamasına gerek olmayan DDL işlemleri (CREATE TABLE, ALTER INDEX), yalnızca okunan iş yükleri veya yönetici betikler için faydalıdır:

conn = mssql_python.connect(connection_string)
print(conn.autocommit)  # False

cursor = conn.cursor()
cursor.execute("CREATE TABLE #Demo (Name NVARCHAR(50))")
cursor.execute("INSERT INTO #Demo (Name) VALUES ('Widget')")
conn.commit()  # Required to persist changes

Her komutun anında commit edilmesi için autocommit'i etkinleştirin. autocommit=True öğesini bağlantı sırasında kullanın veya bağlandıktan sonra setautocommit() ile ya da özelliği doğrudan atayarak bunu değiştirin:

# At connection time
conn = mssql_python.connect(connection_string, autocommit=True)

# Or after connection (both forms work)
conn.setautocommit(True)
conn.autocommit = True
print(conn.autocommit)  # True

# Now changes are committed automatically
cursor = conn.cursor()
cursor.execute("SELECT TOP 1 Name FROM Production.Product")
print(cursor.fetchone().Name)
# No commit() needed

Bağlantı zaman aşımına uğradı

Sürücünün hata vermeden önce bağlantı kurmak için ne kadar süre bekleyeceğini belirlemek amacıyla bağlantı zaman aşımını ayarlayın. Makul bir bağlantı zaman aşımı, güvenilmez ağlara sahip ortamlarda dağıtılan uygulamalar veya bir sunucuya ulaşılamadığında hızlı arızalananlar için önemlidir:

# At connection time (in seconds)
conn = mssql_python.connect(connection_string, timeout=30)

# Or after connection
conn.timeout = 60
print(conn.timeout)  # 60

0 zaman aşımı, zaman aşımı olmadığı anlamına gelir (süresiz beklenir). Üretimde makul zaman aşımları tanımlayın; zaman aşımı tanımlanmamış takılı kalan bir bağlantı girişimi, çağıran iş parçacığını kalıcı olarak engeller.

Bağlantı öznitelikleri

Bağlantı davranışını çalışma zamanında değiştirmek için kullanılır set_attr() . Bağlantı özellikleri, erişim modu, işlem izolasyonu ve paket boyutu gibi düşük seviyeli sürücü ayarlarını kontrol eder. Çoğu uygulama bu özellikleri değiştirmek zorunda değildir, ancak belirli durumlar için faydalıdır:

  • Yalnızca okuma modu: Raporlama sorgularında yanlışlıkla yazımı önler.
  • İşlem yalıtımı: Eşzamanlı işlemlerin nasıl etkileşime girdiğini denetler (sıkı tutarlılık için SERIALIZABLE, genel kullanım için READ_COMMITTED kullanın).
  • Paket boyutu: Yüksek gecikmeli veya yüksek aktarım kapasiteli ağlar için ayarlayın.
import mssql_python

conn = mssql_python.connect(connection_string)

# Set read-only mode
conn.set_attr(mssql_python.SQL_ATTR_ACCESS_MODE, mssql_python.SQL_MODE_READ_ONLY)

# Set transaction isolation level
conn.set_attr(mssql_python.SQL_ATTR_TXN_ISOLATION, mssql_python.SQL_TXN_SERIALIZABLE)

Mevcut özellikler:

Sabit Açıklama
SQL_ATTR_CONNECTION_TIMEOUT Bağlantı zaman aşımı, saniye cinsinden.
SQL_ATTR_LOGIN_TIMEOUT Saniye cinsinden oturum açma zaman aşımı.
SQL_ATTR_PACKET_SIZE Ağ paketi boyutu.
SQL_ATTR_ACCESS_MODE Sadece okunma veya okuma-yazma modu.
SQL_ATTR_TXN_ISOLATION İşlem izolasyon seviyesi.
SQL_ATTR_CURRENT_CATALOG Güncel veritabanı adı.

Ön bağlantı özellikleri

Sürücü bağlantıyı kurmadan önce bazı nitelikler ayarlanmalıdır (örneğin, giriş zamanlamı). Bunları attrs_before içinden geçirin:

conn = mssql_python.connect(
    connection_string,
    attrs_before={
        mssql_python.SQL_ATTR_LOGIN_TIMEOUT: 30,
        mssql_python.SQL_ATTR_CONNECTION_TIMEOUT: 60,
    }
)

Bağlantı bilgilerini alma

Sunucu yeteneklerine göre kayıt tutma, tanılama veya davranış uyarlaması için sürücü ve sunucu meta verilerini almak için kullanılır getinfo() :

conn = mssql_python.connect(connection_string)

# Server information
print(f"Server name: {conn.getinfo(mssql_python.SQL_SERVER_NAME)}")
print(f"Database name: {conn.getinfo(mssql_python.SQL_DATABASE_NAME)}")

# Driver information
print(f"Driver name: {conn.getinfo(mssql_python.SQL_DRIVER_NAME)}")
print(f"Driver version: {conn.getinfo(mssql_python.SQL_DRIVER_VER)}")

Mevcut bilgi sabitlerinin listesini alın:

constants = mssql_python.get_info_constants()
for name, value in constants.items():
    print(f"{name}: {value}")

Kaçış karakteri arama

searchescape özelliği, LIKE desenlerinde joker karakterlerden (% ve _) kaçmak için kullanılan karakteri döndürür. Bunu, kullanıcı girdisindeki gerçek joker karakterlerini güvenli bir şekilde aramak için kullanın:

escape = conn.searchescape

# Use in queries with wildcard characters
cursor.execute(
    f"SELECT Name FROM Production.Product WHERE Name LIKE '%{escape}%%' ESCAPE '{escape}'"
)
# Matches names containing literal '%' character

Kodlama ve kod çözme

SQL ifadeleri ve sonuçları için metin kodlamasını yapılandırın. Varsayılan ayarlar çoğu uygulama için çalışır. Bunları yalnızca sütunlar için UTF-8 olmayan bir kodlama char/varchar kullanan bir sunucuya bağlandığınızda değiştirin. Bir sunucunun kullandığı kodlama, sütun derlemesine bağlıdır:

# Set encoding for outbound text
conn.setencoding(encoding='utf-8')

# Get current encoding settings
settings = conn.getencoding()
print(settings)  # {'encoding': 'utf-8', 'ctype': ...}

# Set decoding for inbound text from specific SQL types
conn.setdecoding(mssql_python.SQL_CHAR, encoding='utf-8')

# Get current decoding settings
settings = conn.getdecoding(mssql_python.SQL_CHAR)
print(settings)

Varsayılan kodlamalar:

Yön SQL türü Varsayılan kodlama
Giden (str) SQL_WCHAR utf-16le
Gelen Ürünler SQL_CHAR utf-8
Gelen Ürünler SQL_WCHAR utf-16le
Gelen Ürünler SQL_WMETADATA utf-16le

En iyi uygulamalar

  • Uygulama kodundaki tüm bağlantılar için bağlam yöneticileri (withbloklar) kullanın. İstisnalar olsa bile temizliği garanti ederler.
  • Daha iyi performans için bağlantı havuzunu kullanın (varsayılan olarak etkinleştirilmiştir). Bkz. Bağlantı havuzlama.
  • Ağ ortamınız için uygun zaman aşımları ayarlayın. 30 saniyelik bir zaman aşımı çoğu bulut dağıtımına uygundur; Bölgeler arası veya VPN bağlantıları için bunu artırın.
  • autocommit=False 'i, işlemsel atomikliğe ihtiyaç duyduğunuz veri değiştirme senaryolarında (varsayılan olarak) kullanın.
  • DDL işlemleri, salt okunur sorgular ve yönetici betikleri için autocommit=True kullanın.
  • Bağlantıları iş başlıkları arasında paylaşmayın. Sürücünün iş parçacığı güvenliği seviyesi 1'dir (iş parçacıkları modülü paylaşabilir ancak bağlantıları paylaşamaz).