Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az mssql-python illesztőprogram a Microsoft első saját fejlesztésű Python-illesztőprogramja a Microsoft SQL-hez. Ha inkább egy Microsoft által karbantartott illesztőprogram-lehetőséget részesít előnyben, az a következőket kínálja:
- Nincs külső ODBC illezőprogramfüggőség.
- Beépített csatlakozási csoportosítás.
- Modern Python 3.10+ támogatás.
- Natív Microsoft Entra hitelesítés.
Főbb különbségek
| Feature | pyodbc | mssql-python |
|---|---|---|
| Paraméterstílus |
qmark (?) |
qmark (?) és pyformat (%(name)s) |
| ODBC-illesztőprogram szükséges | Yes | No |
| Kapcsolatmegosztás | Külső | Beépített |
| Minimális Python-verzió | 3.6 | 3.10 |
callproc() |
Támogatott | Nincs implementálva |
| Autocommit alapértelmezett | Off | Off |
Alapvető migrációs lépések
Az alábbi lépések lefedik a pyodbc alkalmazás mssql-pythonra történő migrálásához szükséges kulcsfontosságú változtatásokat.
1. Frissítsék az importokat
Az pyodbc importot helyettesítsük :mssql_python
Előtte (pyodbc):
import pyodbc
(mssql-python) után:
import mssql_python
2. Kapcsolódási láncok frissítése
Távolítsa el a DRIVER= kulcsszót, és frissítse a hitelesítési módszert:
Mielőtt (pyodbc, ODBC drivert igényel):
conn = pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=localhost;"
"DATABASE=AdventureWorks2022;"
"Trusted_Connection=yes;"
)
Miután (mssql-python, nincs szükség driverre, Microsoft Entra auth-val):
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
)
3. Hagyd a lekérdezéseidet változatlanul
Az mssql-python illesztőprogram támogatja mind ? a (qmark), mind %(name)s (pyformat) paraméterstílusokat. A meglévő ? lekérdezéseid változtatás nélkül működnek:
Előtte (pyodbc):
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Color = ?", (1, "Red"))
Utána (mssql-python, ugyanaz a lekérdezés):
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Color = ?", (1, "Red"))
4. Tartsa meg az executemany elemet változatlanul
A meglévő executemany hívások tuple-okkal és ? jelölőkkel változtatás nélkül működnek:
Korábban (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)
Miután (mssql-python, ugyanaz a kód):
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)
Tárolt eljárás migráció
Az mssql-python illesztőprogram nem valósítja meg a callproc() elemet. A következő szakaszok bemutatják, hogyan kell helyette használni EXECUTE .
EXECUTE használata tárolt eljárásokhoz
A pyodbc illezser támogatja callproc(), de az mssql-python illesztőprogram nem. Használja inkább a következőt EXECUTE :
Mielőtt (pyodbc):
cursor.callproc("dbo.uspGetEmployeeManagers", (5,))
results = cursor.fetchall()
(mssql-python) után:
cursor.execute(
"EXECUTE dbo.uspGetEmployeeManagers @BusinessEntityID = %(id)s",
{"id": 5}
)
results = cursor.fetchall()
print(f"Got {len(results)} rows")
Kimeneti paraméterek
Használj T-SQL változókat a kimeneti értékek rögzítésére a callproc() kimeneti paraméterek helyett:
Mielőtt (pyodbc, callproc használatával):
params = (category_id, pyodbc.SQL_INTEGER)
cursor.callproc("dbo.GetProductCount", params)
count = params[1].value
Miután (mssql-python, T-SQL-változók használatával):
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}")
Jellemző-specifikus migrációk
Az alábbi szakaszok specifikus pyodbc jellemzőket és azok mssql-python megfelelőit tárgyalják.
Kapcsolódási karakterláncok
| pyodbc kulcsszó | mssql-python kulcsszó | Jegyzetek |
|---|---|---|
DRIVER={...} |
Nem szükséges | Az ODBC illesztőprogram beépítve van a csomagban. |
SERVER= |
Server= |
Nincs változás a viselkedésben. |
DATABASE= |
Database= |
Nincs változás a viselkedésben. |
Trusted_Connection= |
Trusted_Connection= |
Nincs változás a viselkedésben. |
UID= / PWD= |
UID= / PWD= |
Nincs változás a viselkedésben. |
Authentication= |
Authentication= |
Ugyanazokat az értékeket fogadja el. |
Automatikus véglegesítés
Az automatikus elköteleződés viselkedése mindkét illesztőprogramban azonos:
pyodbc:
conn.autocommit = True
pyodbc.connect(connection_string, autocommit=True)
MSSQL-Python:
conn.autocommit = True
Tömeges beszúrás
A nagy INSERT adagok gyorsításához a pyodbc felhasználók beállítják fast_executemany = True. Az mssql-python illesztőprogram már optimalizálja a(z) executemany használatát paraméterezett kötegek esetén, így mérsékelt mennyiségű beszúrásokhoz nincs szükség külön kapcsolóra. Nagy mennyiségű adat betöltésekor inkább a bulkcopy() használata javasolt, amely a sorokat a tömeges másolási protokollon keresztül folyamatosan továbbítja, és sokkal gyorsabb, mint az egyes INSERT utasítások kiadása. A teljes munkafolyamatért lásd: Használj tömeges másolatot.
pyodbc:
cursor.fast_executemany = True
cursor.executemany(query, data)
A (mssql-python) után mérsékelt adag a következőkkel executemany:
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()
A(z) (mssql-python) után, nagy terhelés esetén bulkcopy (előnyben részesített):
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()
Sorgyár
Az mssql-python illesztőprogram olyan objektumokat ad vissza Row , amelyek alapértelmezetten támogatják az attribútum-hozzáférést, anélkül, hogy egyedi sorgyárat kellene létrehozni:
PyoDBC (Custom Row Factory):
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 (attribútum-hozzáférés alapértelmezett):
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
Hibakezelés
Az mssql-python illesztőprogram ugyanazt a kivételhierarchiát használja, mint a pyodbc, így a legtöbb kivételkezelő csak modulnévváltoztatást igényel.
Kivételhierarchia
A kivételosztályok nevei közvetlenül megfeleltethetők az illesztőprogramok között:
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
A hiba részletei
Mindkét illesztőprogram a kivétel argumentumain keresztül teszi elérhetővé a hiba részleteit:
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))
Kapcsolatmegosztás
Az mssql-python illesztőprogram alapértelmezetten tartalmazza a csatlakozási poolingot, így külső pooling könyvtárakra már nem lesz szükség.
Távolítsd el a külső készletezést
Ha külső poolingot használtál pyodbc-vel, az mssql-python driverben ez beépített:
Előtte (pyodbc külső pool):
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()
A(z) mssql-python beépített kapcsolatkészlete után:
conn = mssql_python.connect(connection_string)
conn.close()
Pool konfigurálása
Felülírd az alapértelmezett medence méretét és időkorlátot a következőkkel:mssql_python.pooling()
import mssql_python
mssql_python.pooling()
Teljes migrálási példa
Az alábbiakban ugyanazt a függvényt mutatja pyodbc-vel írva, majd mssql-pythonnal újraírva.
Előtte (pyodbc)
Ez a verzió a pyodbc kapcsolati karakterlánc-et használja egy DRIVER kulcsszóval együtt:
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
Miután (mssql-python)
Ez a verzió eltávolítja a DRIVER kulcsszót. Minden lekérdezés, paraméter és sorhozzáférési mintázat azonos marad:
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
A módosítások csak az importálási utasítást és a kapcsolati sztringet érintik (nincs szükség a DRIVER kulcsszóra). Minden lekérdezés, paraméter, bevonási minta és sor hozzáférés ugyanaz marad.
A migráció tesztelése.
A migráció befejezése előtt ugyanazokat a lekérdezéseket futtatjuk mindkét meghajtón, és hasonlítsd össze az eredményeket, hogy megerősítsd az egyenlő viselkedést.
Ellenőrizze az egyenértékű működést
Használj egy összehasonlító függvényt, amely ugyanazt a lekérdezést futtatja mindkét meghajtóval szemben, és kiállítja, hogy az eredmények egyeznek:
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
- [ ] Frissítse az importokat a
pyodbc-től -remssql_python. - [ ] Távolítsd
DRIVER=el a csatlakozási szálakat. - [ ] Tartsák meg a meglévő
?paraméterlekérdezéseket (működnek as-is). - [ ] Használj
EXECUTEutasításokat tárolt eljáráshívásokhoz. - [ ] Távolítsd el a külső kapcsolatcsoportosítás konfigurációját.
- [ ] Frissítse a kivételkezelő osztályneveket.
- [ ] Teszteljük az összes lekérdezést és tárolt eljárást.
- [ ] Ellenőrizd az adattípusok kezelését (különösen a tizedeseket és dátumokat).
- [ ] Távolítsd el az ODBC illeperesítőt a telepítési követelményekből.