Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
mssql-python sürücüsü, Microsoft'un Microsoft SQL için birinci taraf Python sürücüsüdür. Microsoft tarafından desteklenen bir sürücü seçeneği tercih ederseniz, şunları sunar:
- Harici ODBC sürücü bağımlılığı yok.
- Yerleşik bağlantı havuzlaması.
- Modern Python 3.10+ desteği.
- Yerel Microsoft Entra kimlik doğrulaması.
Önemli farklar
| Özellik | pyodbc | mssql-python |
|---|---|---|
| Parametre stili |
qmark (?) |
qmark (?) ve pyformat (%(name)s) |
| ODBC sürücüsü gerekli | Evet | Hayır |
| Bağlantı havuzlama | Harici | Yerleşik |
| Minimum Python sürümü | 3.6 | 3.10 |
callproc() |
Destekleniyor | Uygulanmadı |
| Varsayılan Otomatik İşleme | Off | Off |
Temel göç adımları
Aşağıdaki adımlar, pyodbc uygulamasını mssql-python'a taşımak için yapılan temel değişiklikleri kapsar.
1. İç aktarmaları güncelle
pyodbc içe aktarmasını mssql_python ile değiştirin:
Öncesi (pyodbc):
import pyodbc
(mssql-python)'den sonra:
import mssql_python
2. Bağlantı dizilerini güncelle
Anahtar kelimeyi DRIVER= kaldırın ve kimlik doğrulama yöntemini güncelleyin:
Önce (pyodbc, ODBC sürücüsü gerektirir):
conn = pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=localhost;"
"DATABASE=AdventureWorks2022;"
"Trusted_Connection=yes;"
)
Sonrasında (mssql-python, sürücü gerekmiyor, Microsoft Entra kimlik doğrulaması kullanılarak):
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
)
3. Sorgularınızı olduğu gibi tutun
mssql-python sürücüsü hem ? (qmark) hem de %(name)s (pyformat) parametre stillerini destekler. Mevcut ? sorgularınız değişmeden çalışıyor:
Öncesi (pyodbc):
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Color = ?", (1, "Red"))
(mssql-python, aynı sorgu) sonra:
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Color = ?", (1, "Red"))
4. executemany'i olduğu gibi bırakın
Mevcut executemany çağrılar, demetler ve ? işaretleyicilerle herhangi bir değişiklik yapılmadan çalışır:
Öncesi (pyodbc):
cursor.execute("CREATE TABLE #MigrateDemo (ID INT, Name NVARCHAR(50))")
data = [(1, "Alice"), (2, "Bob"), (3, "Carol")]
cursor.executemany("INSERT INTO #MigrateDemo (ID, Name) VALUES (?, ?)", data)
Sonra (mssql-python, aynı kod):
cursor.execute("DROP TABLE IF EXISTS #MigrateDemo")
cursor.execute("CREATE TABLE #MigrateDemo (ID INT, Name NVARCHAR(50))")
data = [(1, "Alice"), (2, "Bob"), (3, "Carol")]
cursor.executemany("INSERT INTO #MigrateDemo (ID, Name) VALUES (?, ?)", data)
Depolanmış prosedür göçü
mssql-python sürücüsü callproc() uygulamaz. Aşağıdaki bölümler bunun yerine nasıl kullanılacağını EXECUTE gösterir.
Depolanmış prosedürler için EXECUTE kullanın
pyodbc sürücüsü callproc() öğesini destekliyor, ancak mssql-python sürücüsü desteklemiyor. Bunun yerine şunu kullanın EXECUTE :
Öncesi (pyodbc):
cursor.callproc("dbo.uspGetEmployeeManagers", (5,))
results = cursor.fetchall()
(mssql-python)'den sonra:
cursor.execute(
"EXECUTE dbo.uspGetEmployeeManagers @BusinessEntityID = %(id)s",
{"id": 5}
)
results = cursor.fetchall()
print(f"Got {len(results)} rows")
Çıkış parametreleri
Çıktı parametrelerine güvenmek yerine callproc() çıktı değerlerini yakalamak için T-SQL değişkenleri kullanın:
Önce (pyodbc, callproc kullanılarak):
params = (category_id, pyodbc.SQL_INTEGER)
cursor.callproc("dbo.GetProductCount", params)
count = params[1].value
Sonra (mssql-python, T-SQL değişkenleri kullanılarak):
cursor.execute(
"""
DECLARE @count INT;
SELECT @count = COUNT(*) FROM Production.Product
WHERE ProductSubcategoryID = %(cat_id)s;
SELECT @count AS ProductCount;
""",
{"cat_id": 1}
)
product_count = cursor.fetchval()
print(f"Product count: {product_count}")
Özelliğe özgü geçişler
Aşağıdaki bölümler, belirli pyodbc özelliklerini ve bunların mssql-python karşıtlıklarını kaplar.
Bağlantı stringleri
| pyodbc anahtar kelimesi | mssql-python anahtar kelimesi | Notlar |
|---|---|---|
DRIVER={...} |
Gerekli değil | ODBC sürücüsü dahili olarak paketlenmiştir. |
SERVER= |
Server= |
Davranış değişikliği yok. |
DATABASE= |
Database= |
Davranış değişikliği yok. |
Trusted_Connection= |
Trusted_Connection= |
Davranış değişikliği yok. |
UID= / PWD= |
UID= / PWD= |
Davranış değişikliği yok. |
Authentication= |
Authentication= |
Aynı değerleri kabul ediyor. |
Otomatik Onaylama
Otomatik commit davranışı her iki sürücüde de aynıdır:
pyodbc:
conn.autocommit = True
pyodbc.connect(connection_string, autocommit=True)
MSSQL-Python:
conn.autocommit = True
Toplu eklemeler
Büyük INSERT toplu işlemlerini hızlandırmak için pyodbc kullanıcıları fast_executemany = True kullanır. mssql-python sürücüsü, parametreli toplu işlemler için executemany öğesini zaten optimize eder, bu nedenle orta ölçekli ekleme işlemleri için özel bir bayrak gerekmez. Büyük veri yükleri için, satırları toplu kopyalama protokolü üzerinden akıtan ve tek tek INSERT deyimleri çalıştırmaktan çok daha hızlı olan bulkcopy() tercih edin. Tam iş akışı için bkz. Toplu kopya kullan.
pyodbc:
cursor.fast_executemany = True
cursor.executemany(query, data)
(mssql-python)’dan sonra, executemany ile orta ölçekli toplu işlemler:
cursor.execute("DROP TABLE IF EXISTS #BulkTarget")
cursor.execute("CREATE TABLE #BulkTarget (ID INT, Name NVARCHAR(50))")
data = [(i, f"Item {i}") for i in range(100)]
cursor.executemany("INSERT INTO #BulkTarget (ID, Name) VALUES (?, ?)", data)
conn.commit()
(mssql-python)’dan sonra, bulkcopy ile büyük yükler (tercih edilir):
cursor.execute("IF OBJECT_ID('##BulkTarget') IS NOT NULL DROP TABLE ##BulkTarget")
cursor.execute("CREATE TABLE ##BulkTarget (ID INT, Name NVARCHAR(50))")
conn.commit() # Commit DDL before bulkcopy
data = [(i, f"Item {i}") for i in range(100)]
result = cursor.bulkcopy("##BulkTarget", data)
print(f"Bulk copied {result['rows_copied']} rows")
cursor.execute("DROP TABLE ##BulkTarget")
conn.commit()
Sıra fabrikası
mssql-python sürücüsü, özel bir row factory gerektirmeden, varsayılan olarak öznitelik erişimini destekleyen Row nesneleri döndürür:
PyoDBC (özel sıra fabrikası):
def namedtuple_row_factory(cursor):
from collections import namedtuple
columns = [col[0] for col in cursor.description]
Row = namedtuple("Row", columns)
return Row
MSSQL-python (varsayılan olarak öznitelik erişimi):
cursor.execute("SELECT Name, ListPrice FROM Production.Product")
row = cursor.fetchone()
print(row.Name) # Attribute access works directly
print(row[0]) # Index access also works
Hata yönetimi
mssql-python sürücüsü, pyodbc ile aynı istisna hiyerarşisini kullanır, bu nedenle çoğu istisna işleyicisi yalnızca modül adı değişikliği gerektirir.
Özel durum hiyerarşisi
İstisna sınıf isimleri doğrudan sürücüler arasında eşleşir:
pyodbc:
try:
cursor.execute(query)
except pyodbc.Error as e:
pass
except pyodbc.DatabaseError as e:
pass
except pyodbc.OperationalError as e:
pass
MSSQL-Python:
try:
cursor.execute("SELECT TOP 1 * FROM Production.Product")
print(cursor.fetchone())
except mssql_python.Error as e:
pass
except mssql_python.DatabaseError as e:
pass
except mssql_python.OperationalError as e:
pass
Hata ayrıntıları
Her iki sürücü de hata detaylarını istisna argümanları aracılığıyla ortaya çıkarır:
pyodbc:
try:
cursor.execute(query)
except pyodbc.Error as e:
sqlstate = e.args[0]
message = e.args[1]
MSSQL-Python:
try:
cursor.execute("SELECT TOP 1 * FROM NonExistentTable_XYZ")
except mssql_python.Error as e:
# Error message contains SQLSTATE and details
print(str(e))
Bağlantı havuzlama
mssql-python sürücüsü varsayılan olarak bağlantı havuzlamasını içerir, bu yüzden harici havuzlama kütüphaneleri artık gerekli değildir.
Harici havuzlamayı kaldırın
Eğer pyodbc ile harici havuzlama kullandıysanız, bu özellik mssql-python sürücüsünde yerleşik olarak bulunur:
Öncesi (pyodbc dış havuz):
from dbutils.pooled_db import PooledDB
pool = PooledDB(pyodbc, 5, driver="{ODBC Driver 18 for SQL Server}",
server="your_server", database="your_database",
uid="your_username", pwd="your_password")
conn = pool.connection()
Sonra (mssql-python yerleşik havuzlama):
conn = mssql_python.connect(connection_string)
conn.close()
Havuzu yapılandırma
Varsayılan havuz büyüklüğü ve zaman aşımı değerlerini mssql_python.pooling() ile geçersiz kılın:
import mssql_python
mssql_python.pooling()
Tam geçiş örneği
Aşağıda aynı fonksiyonun pyodbc ile yazıldığı ve ardından mssql-python ile yeniden yazıldığı gösterilmektedir.
Öncesi (pyodbc)
Bu versiyon, pyodbc bağlantı dizesi'i bir DRIVER anahtar kelimeyle kullanır:
import pyodbc
from datetime import date
def get_orders(customer_id: int, start_date: date):
conn = pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=localhost;"
"DATABASE=AdventureWorks2022;"
"Trusted_Connection=yes;"
)
cursor = conn.cursor()
cursor.execute("""
SELECT SalesOrderID, OrderDate, TotalDue
FROM Sales.SalesOrderHeader
WHERE CustomerID = ? AND OrderDate >= ?
ORDER BY OrderDate DESC
""", (customer_id, start_date))
orders = []
for row in cursor:
orders.append({
"id": row.SalesOrderID,
"date": row.OrderDate,
"total": row.TotalDue
})
cursor.close()
conn.close()
return orders
Sonra (mssql-python)
Bu sürümde anahtar DRIVER kelime kaldırılır. Tüm sorgular, parametreler ve satır erişim desenleri aynı kalır:
import mssql_python
from datetime import date
def get_orders(customer_id: int, start_date: date):
conn = mssql_python.connect(
"Server=localhost;"
"Database=AdventureWorks2022;"
"Trusted_Connection=yes;"
)
cursor = conn.cursor()
cursor.execute("""
SELECT SalesOrderID, OrderDate, TotalDue
FROM Sales.SalesOrderHeader
WHERE CustomerID = ? AND OrderDate >= ?
ORDER BY OrderDate DESC
""", (customer_id, start_date))
orders = []
for row in cursor:
orders.append({
"id": row.SalesOrderID,
"date": row.OrderDate,
"total": row.TotalDue
})
cursor.close()
conn.close()
return orders
Tek değişiklikler import ifadesi ve bağlantı dizesi'dir (anahtar kelime gerekmezDRIVER). Her sorgu, parametre, getirme deseni ve satır erişimi aynı kalır.
Geçişi test etme
Göçü tamamlamadan önce, aynı sorguları her iki sürücüye karşı çalıştırın ve sonuçları karşılaştırarak eşdeğer davranışı doğrulayın.
Eşdeğer davranışı doğrulayın
Her iki sürücüye karşı aynı sorguyu çalıştıran ve sonuçların eşleşmesini belirten bir karşılaştırma fonksiyonu kullanın:
import pyodbc
import mssql_python
def compare_results(pyodbc_conn_str: str, mssql_conn_str: str, query: str):
"""Compare results from both drivers."""
# pyodbc query
pyodbc_conn = pyodbc.connect(pyodbc_conn_str)
pyodbc_cursor = pyodbc_conn.cursor()
pyodbc_cursor.execute(query)
pyodbc_results = pyodbc_cursor.fetchall()
pyodbc_conn.close()
# mssql-python query
mssql_conn = mssql_python.connect(mssql_conn_str)
mssql_cursor = mssql_conn.cursor()
mssql_cursor.execute(query)
mssql_results = mssql_cursor.fetchall()
mssql_conn.close()
# Compare
assert len(pyodbc_results) == len(mssql_results)
for p_row, m_row in zip(pyodbc_results, mssql_results):
assert tuple(p_row) == tuple(m_row)
print(f"Results match: {len(pyodbc_results)} rows")
Checklist
- [ ] İçe aktarma işlemlerini
pyodbckonumundanmssql_pythonkonumuna güncelle. - [ ] Bağlantı dizilerinden çıkar
DRIVER=. - [ ] Mevcut
?parametre sorgularını koruyun (olduğu gibi çalışırlar). - [ ] Saklı yordam çağrıları için
EXECUTEdeyimlerini kullanın. - [ ] Harici bağlantı havuzlama yapılandırmasını kaldırın.
- [ ] İstisna işleme sınıf isimlerini güncelledin.
- [ ] Tüm sorguları ve saklanan prosedürleri test edin.
- [ ] Veri tipi işleme işlemlerini (özellikle ondalık ve tarihler) doğrulayın.
- [ ] ODBC sürücüsünü dağıtım gereksinimlerinden kaldırın.