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=AdventureWorks2022;"
"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 je součástí balení. |
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 středně velké objemy vkládání nevyžadují žádný speciální příznak. Pro velké datové zatížení preferujeme bulkcopy(), které streamuje řádky přes protokol hromadné kopie a je mnohem rychlejší než vydávání jednotlivých INSERT příkazů. 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=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
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=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
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í.