Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ovladač mssql-python je první oficiální ovladač Microsoftu pro Python pro Microsoft SQL. Pokud preferujete možnost ovladačů spravovaných Microsoft, nabízí:
- Žádná závislost na externím ODBC ovladači.
- Vestavěné sdružování připojení.
- Podpora moderního Python 3.10+.
- Nativní Microsoft Entra autentizace.
Hlavní rozdíly
| funkce | pyodbc | mssql-python |
|---|---|---|
| Styl parametrů |
qmark (?) |
qmark(?) a pyformat ()%(name)s |
| Vyžaduje se ODBC ovladač | Yes | Ne |
| Sdílení připojení | Externí | Vestavěný |
| Minimální verze Pythonu | 3.6 | 3.10 |
callproc() |
Podporováno | Není implementováno |
| Výchozí automatické potvrzení | Off | Off |
Základní migrační kroky
Následující kroky pokrývají změny klíčů pro migraci aplikace pyodbc do mssql-python.
1. Aktualizovat importy
Nahraďte import pyodbc za mssql_python:
Předtím (pyodbc):
import pyodbc
Po (mssql-python):
import mssql_python
2. Aktualizovat spojovací řetězce
Odstraňte klíčové slovo DRIVER= a aktualizujte způsob ověřování:
Před (pyodbc, vyžaduje ovladač ODBC):
conn = pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=localhost;"
"DATABASE=AdventureWorks2025;"
"Trusted_Connection=yes;"
)
Po (mssql-python, bez potřeba ovladače, pomocí Microsoft Entra autentizace):
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
)
3. Ponechte své dotazy beze změny
Ovladač mssql-python podporuje jak ? (qmark), tak (pyformat) styly %(name)s parametrů. Vaše stávající ? dotazy fungují bez změn:
Předtím (pyodbc):
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Color = ?", (1, "Red"))
Po (mssql-python, stejný dotaz):
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Color = ?", (1, "Red"))
4. Ponechte executemany beze změny
Stávající executemany volání s nticemi a značkami ? fungují beze změny:
Předtím (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)
Po (mssql-python, stejný 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)
Migrace uložených procedur
Ovladač mssql-python neimplementuje callproc(). Následující sekce ukazují, jak místo toho použít EXECUTE .
Použijte EXECUTE pro uložené procedury
Ovladač pyodbc podporuje callproc(), ale ovladač mssql-python ne. Místo toho použijte EXECUTE :
Předtím (pyodbc):
cursor.callproc("dbo.uspGetEmployeeManagers", (5,))
results = cursor.fetchall()
Po (mssql-python):
cursor.execute(
"EXECUTE dbo.uspGetEmployeeManagers @BusinessEntityID = %(id)s",
{"id": 5}
)
results = cursor.fetchall()
print(f"Got {len(results)} rows")
Výstupní parametry
Použijte T-SQL proměnné k zachycení výstupních hodnot místo spoléhání se na callproc() výstupní parametry:
Předtím (pyodbc, při použití callproc):
params = (category_id, pyodbc.SQL_INTEGER)
cursor.callproc("dbo.GetProductCount", params)
count = params[1].value
Po (mssql-python, s použitím proměnných T-SQL):
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}")
Migrace pro konkrétní funkce
Následující sekce pokrývají konkrétní funkce pyodbc a jejich ekvivalenty mssql-python.
Připojovací řetězce
| Klíčové slovo pyodbc | Klíčové slovo mssql-python | Poznámky |
|---|---|---|
DRIVER={...} |
Není potřeba | Ovladač ODBC se automaticky instaluje jako závislost balíčku. |
SERVER= |
Server= |
Žádné změny chování. |
DATABASE= |
Database= |
Žádné změny chování. |
Trusted_Connection= |
Trusted_Connection= |
Žádné změny chování. |
UID= / PWD= |
UID= / PWD= |
Žádné změny chování. |
Authentication= |
Authentication= |
Přijímá stejné hodnoty. |
Autocommit
V obou ovladačích je chování automatického potvrzování identické:
pyodbc:
conn.autocommit = True
pyodbc.connect(connection_string, autocommit=True)
mssql-python:
conn.autocommit = True
Hromadné vkládání
Pro urychlení velkých INSERT dávek uživatelé pyodbc nastavují fast_executemany = True. Ovladač mssql-python už optimalizuje executemany pro parametrizované dávky, takže speciální příznak nepotřebujete. Pro hromadné načítání použijte bulkcopy(), které streamuje řádky přes protokol hromadného kopírovaní místo odeslání jednoho INSERT příkazu na řádek. Pro celý pracovní postup viz Použít hromadnou kopii.
pyodbc:
cursor.fast_executemany = True
cursor.executemany(query, data)
Po (mssql-python) moderujte dávky s 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()
Po použití (mssql-python), rozsáhlá načítání s bulkcopy (doporučeno):
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()
Generátor řádků
Ovladač mssql-python vrací objekty Row, které ve výchozím nastavení podporují přístup k atributům, aniž by byla vyžadována vlastní row factory:
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 (přístup k atributům ve výchozím nastavení):
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
Zpracování chyb
Ovladač mssql-python používá stejnou hierarchii výjimek jako pyodbc, takže většina obslužných nástrojů výjimek vyžaduje pouze změnu názvu modulu.
Hierarchie výjimek
Názvy tříd výjimek se mapují přímo mezi ovladači:
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
Podrobnosti o chybě
Oba ovladače odhalují chybové detaily prostřednictvím výjimek:
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))
Sdílení připojení
Ovladač mssql-python ve výchozím nastavení zahrnuje sdružování připojení, takže externí knihovny pro sdružování připojení už nejsou potřeba.
Odeberte externí sdružování
Pokud jste použili externí pooling s pyodbc, ovladač mssql-python to má zabudované:
Před (externí bazén pyodbc):
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()
Po (integrovaném sdružování připojení v mssql-python):
conn = mssql_python.connect(connection_string)
conn.close()
Konfigurovat fond
Přepište výchozí velikost poolu a časový limit pomocí mssql_python.pooling():
import mssql_python
mssql_python.pooling()
Příklad dokončení migrace
Následující ukazuje stejnou funkci napsanou v pyodbc a poté přepsánou v mssql-python.
Předtím (pyodbc)
Tato verze používá pyodbc připojovací řetězec s klíčovým slovemDRIVER:
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=AdventureWorks2025;"
"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
Po (mssql-python)
Tato verze odstraní klíčové slovo DRIVER . Všechny dotazy, parametry a vzory přístupu k řádkům zůstávají totožné:
import mssql_python
from datetime import date
def get_orders(customer_id: int, start_date: date):
conn = mssql_python.connect(
"Server=localhost;"
"Database=AdventureWorks2025;"
"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
Jediné změny jsou příkaz import a připojovací řetězec (klíčové slovo není DRIVER potřeba). Každý dotaz, parametr, vzor načtení a přístup k řádku zůstávají stejné.
Otestujte migraci
Před dokončením migrace spusťte stejné dotazy v obou ovladačích a porovnejte výsledky, abyste ověřili ekvivalentní chování.
Ověřte ekvivalentní chování
Použijte srovnávací funkci, která spustí stejný dotaz na oběma ovladačích a potvrdí, že výsledky se shodují:
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")
Kontrolní seznam
- [ ] Aktualizovat importy z
pyodbcdo .mssql_python - [ ] Odstraňte
DRIVER=z propojovacích řetězců. - [ ] Udržujte existující
?dotazy na parametry (fungují as-is). - [ ] Použijte
EXECUTEpříkazy pro volání uložených procedur. - [ ] Odstraňte konfiguraci externího připojení pro pooling.
- [ ] Aktualizace názvů tříd při zpracování výjimek.
- [ ] Otestujte všechny dotazy a uložené procedury.
- [ ] Ověřte zpracování datových typů (zejména desetinné čísla a data).
- [ ] Odstraňte ovladač ODBC z požadavků na nasazení.