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 iki bağımsız mola çıkışı var. Birini ayarlamak diğerini etkilemez.

Setting Neyi sınırlar Varsayılan
timeout argüman connect() Kimlik doğrulama girişimi, ağ bağlantısı dahil. Ayarlar SQL_ATTR_LOGIN_TIMEOUT. 0, bu da sürücü varsayılan özelliğini kullanır
Connection.timeout özellik Her bir ifade, bağlantının çalıştığı anlamına gelir. 0, bu da sorgu zamanlamasını devre dışı bırakır
# Bound the authentication attempt (in seconds)
conn = mssql_python.connect(connection_string, timeout=30)

# Bound each statement that this connection runs
conn.timeout = 60

SQL_ATTR_LOGIN_TIMEOUT içinde attrs_before ayarlarsanız, bu değer timeout bağımsız değişkenine göre öncelikli olur.

Note

Microsoft Entra ID token edinimi, sürücü bağlanmadan önce gerçekleşir, bu yüzden kimlik doğrulama zaman aşımı bunu sınırlamıyor.

Hedef, otomatik duraklatma etkinleştirilmiş sunucusuz Azure SQL Veritabanı ise, en az 60 kullanın. Otomatik olarak duraklatılan bir veritabanı, ilk bağlantı denemesinde yeniden etkinleşir ve bu yeniden etkinleşme tamamlanmadan önce daha kısa bir zaman aşımı süresi dolar. Deneme veritabanı devam ederken 40613 hatasıyla da başarısız olabilir, bu yüzden uygulama tekrar denemek zorundadır. Daha fazla bilgi için bkz. Otomatik duraklatma ve otomatik devam.

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, % desenlerinde joker karakterlerden (_ ve LIKE) 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

Sürücü her zaman sunucuya Transact-SQL (T-SQL) ifadesi ve str parametreleri UTF-16LE olarak gönderir ve metin parametrelerini SQL_C_WCHAR olarak bağlar. Giden kodlamayı değiştiremezsiniz. Yöntem, setencoding() istediğiniz değerleri kaydeder ancak sürücünün gönderdiği şeyi değiştirmez:

  • setencoding() öğesini bağımsız değişken olmadan çağırmak varsayılan ayarları geri getirir.
  • SQL_WCHAR ile UTF-16LE'den farklı olan geçerli bir istek, örneğin encoding='utf-8' veya ctype=mssql_python.SQL_CHAR, UserWarning üretir ve hiçbir etkisi olmaz. SQL_WCHAR ile UTF-16LE'yi açıkça belirten bir istek uyarı vermez. Yöntem getencoding() yine de istenen değerleri bildirir.
import warnings

with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    conn.setencoding(encoding="utf-8")
print(caught[0].category.__name__)  # UserWarning

conn.setencoding()  # Restore the defaults
print(conn.getencoding())  # {'encoding': 'utf-16le', 'ctype': -8}

Sunucunun döndürdüğü metin için kod çözmeyi ayarlar. Varsayılan olarak, sürücü char ve varchar verilerini UTF-16LE olarak SQL_WCHAR ile ister, böylece değerler sütun harmanlaması ve kod sayfası ne olursa olsun doğru şekilde çözülür. Çoğu uygulamanın kod çözme ayarlarını değiştirmesi gerekmez. setdecoding() yöntemini yalnızca SQL türüyle çağırmak varsayılan durumu geri getirir:

# Decode char and varchar data as UTF-8 instead of the default
conn.setdecoding(mssql_python.SQL_CHAR, encoding='utf-8')

# Restore the default
conn.setdecoding(mssql_python.SQL_CHAR)

# Get current decoding settings
settings = conn.getdecoding(mssql_python.SQL_CHAR)
print(settings)  # {'encoding': 'utf-16le', 'ctype': -8}

Varsayılan kodlamalar:

Yön SQL türü Varsayılan kodlama Değiştir ile
Giden (str) SQL_WCHAR utf-16le Değiştirilemez
Gelen Ürünler SQL_CHAR utf-16le setdecoding()
Gelen Ürünler SQL_WCHAR utf-16le setdecoding()
Gelen Ürünler SQL_WMETADATA utf-16le setdecoding()

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. Otomatik duraklatma etkinleştirilmiş Azure SQL Veritabanı serverless için en az 60 kullanın, çünkü otomatik olarak duraklatılan bir veritabanı ilk bağlantı denemesinde yeniden etkinleştirilir.
  • Hedef Azure SQL Veritabanı, Azure SQL Yönetilen Örneği, Microsoft Fabric'teki SQL veritabanı, kullanılabilirlik grubu dinleyicisi veya yük devretme kümesi örneği olduğunda, MultiSubnetFailover=yes değerini bağlantı dizesinde ayarlayın. Tek IP hedeflerinde güvenlidir, bu yüzden tüm Microsoft SQL ailesi TCP uç noktalarında açık bırakı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).