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.
Diagnostikujte a vyřešte běžné problémy při použití ovladače mssql-python pro připojení k SQL Server, Azure SQL Database, Azure SQL Managed Instance a SQL databázi v Microsoft Fabric.
Problémy s instalací
Instalace PIP selže nebo se sestaví ze zdrojového kódu
Příznaky:
error: Microsoft Visual C++ 14.0 or greater is required
ERROR: Failed building wheel for mssql-python
Možné příčiny a řešení:
Pro vaši platformu není k dispozici žádný předem sestavený balíček wheel
- Zkontrolujte, že používáte podporovanou verzi Python (verze 3.10 a vyšší) a platformu. Viz Životní cyklus podpory, kde najdete matici kompatibility. Před instalací pomocí
pip install --upgrade pipaktualizujte pip. Pro opakovatelná prostředí pro týmy použijte uzamčený workflow v Opakovatelných nasazeních nebo kontejnerové postupy v Kontejnerech a místním vývoji, abyste omezili odchylky v konfiguraci místních počítačů.
- Zkontrolujte, že používáte podporovanou verzi Python (verze 3.10 a vyšší) a platformu. Viz Životní cyklus podpory, kde najdete matici kompatibility. Před instalací pomocí
Virtuální prostředí neaktivováno
- Nejprve aktivujte své virtuální prostředí. Instalace Python do systému může způsobit chyby oprávnění nebo konflikty.
python -m venv .venv .venv\Scripts\activate pip install mssql-python
-
Chybějící systémové knihovny Linuxu
- Ovladač vyžaduje malou sadu systémových knihoven na Linuxu. Viz Platformově specifické závislosti pro balíčky k instalaci.
Konfliktní instalace ovladačů
Příznaky:
Chyby při importu nebo neočekávané chování po instalaci mssql-python spolu s pyodbc ve stejném prostředí.
Oprava:
mssql-python a pyodbc mohou koexistovat. Pokud vidíte konflikty, vytvořte čisté virtuální prostředí:
python -m venv .venv --clear
.venv\Scripts\activate
pip install mssql-python
Problémy s připojením
Nelze se připojit k serveru
Příznaky:
OperationalError: [08001] (0) Client unable to establish connection
Možné příčiny a řešení:
Server není dostupný
- Ověřte, že název serveru a port jsou správné.
- Zkontrolujte síťové připojení:
ping servernamenebotelnet servername 1433. - Ujistěte se, že firewall umožňuje odchozí připojení na portu 1433.
SQL Server neběží
- Ověřte, že služba SQL Server je spuštěna.
- Pro pojmenované instance ověřte, že služba SQL Server Browser běží.
Azure SQL firewall rules
- Přidejte IP klienta do pravidel Azure SQL firewallu v Azure portálu.
- Pro Azure SQL Managed Instance se ujistěte, že se připojujete z povolené sítě.
# Test basic connectivity
import socket
try:
sock = socket.create_connection(("<server>.database.windows.net", 1433), timeout=5)
print("TCP connection successful")
sock.close()
except Exception as e:
print(f"Cannot reach server: {e}")
Přihlášení se nezdařilo.
Příznaky:
OperationalError: [28000] (18456) Login failed for user 'username'.
Možné příčiny a řešení:
Nesoulad autentizačního režimu
- Pro Azure SQL Database, Azure SQL Managed Instance a SQL database in Fabric preferují režim Microsoft Entra, například
Authentication=ActiveDirectoryDefault. - Pokud používáte SQL autentizaci záměrně, ověřte, že server to umožňuje a že používáte správný přihlašovací formát pro daný endpoint.
- Pro Azure SQL Database, Azure SQL Managed Instance a SQL database in Fabric preferují režim Microsoft Entra, například
Nesprávné SQL autentizační údaje
- Ověřte uživatelské jméno a heslo.
- Pro Azure SQL zahrňte celé uživatelské jméno:
username@servername.
Uživatel v databázi neexistuje
- Ověřte, že uživatel má přístup ke specifikované databázi.
- Zkontrolujte, zda je přihlášení přiřazeno uživateli databáze.
Autentizace není nakonfigurována
- Používejte Microsoft Entra autentizaci (doporučeno):
Authentication=ActiveDirectoryDefault. - Pokud řešíte problém s lokálním SQL Server, který by měl přijímat SQL autentizaci, ověřte, že SQL Server používá smíšené režimy autentizace.
- Používejte Microsoft Entra autentizaci (doporučeno):
Časový limit připojení vypršel
Příznaky:
OperationalError: [HYT00] (0) Timeout expired
OperationalError: [HYT01] (0) Connection timeout expired
Možné příčiny a řešení:
Server reaguje pomalu
- Zvyšte časový limit připojení:
conn = mssql_python.connect(connection_string, timeout=60)Latence sítě
- Zkontrolujte síťovou cestu na server.
- Zvažte použití kratší síťové cesty nebo VPN.
Server pod velkým zatížením
- Zkuste se připojit mimo špičku.
- Kontaktujte správce své databáze.
Chyby certifikátu SSL
Příznaky:
OperationalError: [08001] SSL Provider: The certificate chain was issued by an authority that is not trusted
Řešení:
Za prvé, preferujte důvěryhodný certifikát nebo místní vývojové vzorce v kontejnerech a lokálním rozvoji. Používejte TrustServerCertificate=yes pouze pro lokální vývoj na serveru, který ovládáte.
Pro vývoj a testování s vlastním podpisem certifikátu:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"TrustServerCertificate=yes;" # Don't use in production
)
Caution
TrustServerCertificate=yes je to záložní varianta pouze pro místní obyvatele. Nepřenášej to do sdílených vývojových kontejnerů, kanálů CI ani produkčních nasazení. Pro širší pokyny viz Šifrování a certifikáty.
Pro výrobu zajistěte instalaci správných certifikátů a použijte:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"HostnameInCertificate=<server>.domain.com;"
)
Problémy s prováděním dotazů
Tabulka nebo objekt nenalezený
Příznaky:
ProgrammingError: [42S02] (208) Invalid object name 'TableName'.
Možné příčiny a řešení:
Špatný kontext databáze
# Ensure you're connected to the correct database cursor.execute("SELECT DB_NAME()") print(cursor.fetchone()[0])Schéma nespecifikované
# Use fully qualified name cursor.execute("SELECT * FROM dbo.TableName")Tabulka neexistuje
# Check if table exists cursor.execute(""" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TableName' """)
Chyba syntaxe
Příznaky:
ProgrammingError: [42000] (102) Incorrect syntax near '...'.
Řešení:
Nejprve otestujte SQL v SSMS, abyste ověřili syntaxi
Zkontrolujte escapování řetězců – použijte parametrizované dotazy:
# Wrong - vulnerable to syntax issues and SQL injection cursor.execute(f"SELECT * FROM Production.Product WHERE Name = '{name}'") # Correct - use parameters cursor.execute("SELECT * FROM Production.Product WHERE Name = %(name)s", {"name": name})
Chyby parametrů
Příznaky:
ProgrammingError: [07001] Wrong number of parameters
Řešení:
Počítejte zástupné znaky a parametry – musí se shodovat
Vyberte správný styl parametrů:
# Qmark style - positional cursor.execute("SELECT * FROM Production.Product WHERE ProductID = ? AND Name LIKE ?", (1, "Adjustable%")) print(cursor.fetchone()) # Pyformat style - named cursor.execute("SELECT * FROM Production.Product WHERE ProductID = %(id)s AND Name LIKE %(name)s", {"id": 1, "name": "Adjustable%"}) print(cursor.fetchone())
Problémy s datovými typy
Chyby při převodu data a času
Příznaky:
DataError: [22007] Invalid datetime format
Řešení:
Používejte Python datetime objekty místo řetězců:
from datetime import datetime
cursor.execute("CREATE TABLE #Events (EventDate DATETIME)")
# Wrong - this raises an error for invalid dates
try:
cursor.execute("INSERT INTO #Events (EventDate) VALUES (%(event_date)s)", {"event_date": "2024-13-45"})
except Exception as e:
print(f"Expected error: {e}")
# Correct - use Python datetime objects
cursor.execute("INSERT INTO #Events (EventDate) VALUES (%(event_date)s)", {"event_date": datetime(2024, 3, 15)})
cursor.execute("SELECT EventDate FROM #Events")
print(cursor.fetchone())
Problémy s desetinnou přesností
Příznaky:
Čísla se zobrazují oříznutá nebo nesprávně zaokrouhlená.
Řešení:
Použití decimal.Decimal pro přesné číselné hodnoty:
from decimal import Decimal
cursor.execute("CREATE TABLE #PriceDemo (ListPrice DECIMAL(10,2))")
# Preserve full precision
cursor.execute(
"INSERT INTO #PriceDemo (ListPrice) VALUES (%(list_price)s)",
{"list_price": Decimal("19.99")}
)
Problémy s kódováním v Unicode
Příznaky:
Speciální znaky se objevují zkresleně nebo způsobují chyby.
Řešení:
Používejte sloupce NVARCHAR pro Unicode data ve vaší databázi
Předávejte řetězce přímo – ovladač zajišťuje kódování:
cursor.execute("CREATE TABLE #UnicodeDemo (Name NVARCHAR(50))") cursor.execute("INSERT INTO #UnicodeDemo (Name) VALUES (%(name)s)", {"name": "日本語"}) cursor.execute("SELECT Name FROM #UnicodeDemo") print(cursor.fetchone())
Problémy s výkonem
Pomalé provádění dotazů
Možné příčiny a řešení:
Chybějící indexy: Zkontrolujte plán provádění dotazů v SSMS.
Velké množiny výsledků: Použijte
fetchmany()místo :fetchall()cursor.arraysize = 1000 while True: rows = cursor.fetchmany() if not rows: break process_rows(rows)Sdružování připojení je zakázáno: Povolte sdružování připojení:
import mssql_python mssql_python.pooling(max_size=20, idle_timeout=300)
Problémy s pamětí při velkých výsledcích
Příznaky:
Procesu Python dochází paměť.
Řešení:
Výsledky streamu místo načítání všeho do paměti:
cursor.execute("SELECT * FROM LargeTable") for row in cursor: # Iterates one row at a time process_row(row)Použijte stránkování na straně serveru:
page_size = 1000 offset = 0 while True: cursor.execute( "SELECT * FROM LargeTable ORDER BY ID " "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY", (offset, page_size) ) rows = cursor.fetchall() if not rows: break process_rows(rows) offset += page_size
Problémy s transakcí
Rozsah platnosti dočasné tabulky s autocommit režimem
Dočasné tabulky (#tablename) vytvořené uvnitř transakce zmizí, když je transakce vrácena zpět. To je častý zdroj zmatku, když je automatický commit vypnutý (výchozí):
conn = mssql_python.connect(connection_string) # autocommit=False by default
cursor = conn.cursor()
cursor.execute("CREATE TABLE #TempData (ID INT, Name NVARCHAR(50))")
cursor.execute("INSERT INTO #TempData VALUES (1, 'test')")
# If the connection rolls back (explicit or on error), #TempData disappears
conn.rollback()
# This fails: Invalid object name '#TempData'
cursor.execute("SELECT * FROM #TempData")
Oprava: Potvrďte transakci ihned po vytvoření dočasné tabulky nebo použijte režim automatického potvrzování:
cursor.execute("CREATE TABLE #TempData (ID INT, Name NVARCHAR(50))")
conn.commit() # Lock in the table definition
cursor.execute("INSERT INTO #TempData VALUES (1, 'test')")
conn.commit()
DDL příkazy, které vyžadují automatický commit režim, například CREATE DATABASE, selžou uvnitř otevřené transakce. Nastavte automatický commit před jejich spuštěním:
conn.autocommit = True
cursor.execute("CREATE DATABASE TestDB")
conn.autocommit = False
Transakce neprovedena
Příznaky:
Změny dat se po uzavření připojení nepřetrvávají.
Solution:
S autocommit=False (výchozí) musíte zavolat commit():
cursor.execute("CREATE TABLE #Products (Name NVARCHAR(100))")
cursor.execute("INSERT INTO #Products (Name) VALUES (%(name)s)", {"name": "Widget"})
conn.commit() # Don't forget this!
Nebo použijte režim automatického závazku:
conn = mssql_python.connect(connection_string, autocommit=True)
Chyby zablokování
Příznaky:
OperationalError: [40001] (1205) Transaction ... was deadlocked on lock resources with another process
Solution:
Logika opakování (viz logika opakování) řeší okamžité selhání, ale opakující se patové situace naznačují problém v návrhu. Chcete-li odstranit hlavní příčinu, zachyťte graf uváznutí a analyzujte, které příkazy a typy zámků se na něm podílejí. Běžné opravy zahrnují přeuspořádání operací, aby konkurenční transakce získaly zámky ve stejné sekvenci, což omezuje rozsah transakcí a přidává vhodné indexy ke zkrácení doby zámku.
Podrobný návod k analýze deadlocků najdete v článku Průvodce deadlocky. Pokud používáte Azure SQL Database, podívejte se na Analyzovat a předcházet zablokování.
Problémy s hromadným zatížením
Porušení omezení během hromadného kopírování
Příznaky:
RuntimeError: CHECK constraint ... Conflict occurred in database ...
RuntimeError: Cannot insert duplicate key ... violation of PRIMARY KEY constraint
Příčina:
Data ve vaší dávce porušují omezení tabulky (primární klíč, omezení jedinečnosti, CHECK nebo cizí klíč).
Oprava:
Před načtením ověřte data. Pro velké datové sady je nejprve načtěte do pracovní tabulky a poté je sloučte do cílové tabulky:
# Load into staging, then validate
cursor.execute("CREATE TABLE ##Staging (ID INT, Name NVARCHAR(100))")
cursor.bulkcopy("##Staging", rows)
# Check for duplicates before merging
cursor.execute("""
SELECT s.ID FROM ##Staging s
INNER JOIN dbo.Target t ON s.ID = t.ID
""")
dupes = cursor.fetchall()
if dupes:
print(f"Skipping {len(dupes)} duplicate rows")
# Insert only non-duplicate rows
cursor.execute("""
INSERT INTO dbo.Target (ID, Name)
SELECT s.ID, s.Name FROM ##Staging s
WHERE NOT EXISTS (SELECT 1 FROM dbo.Target t WHERE t.ID = s.ID)
""")
conn.commit()
Vzory pro operace upsert s přípravnými tabulkami najdete v tématu Vzory načítání a přesunu dat.
Chyby při mapování sloupců
Příznaky:
RuntimeError: Bulk copy failure - column count mismatch
Příčina:
Počet sloupců ve vašich datech neodpovídá počtu sloupců v cílové tabulce, nebo jsou sloupce ve špatném pořadí.
Oprava:
Ujistěte se, že vaše data přesně odpovídají schématu tabulky v pořadí a počtu:
# Check the target table schema
cursor.execute("""
SELECT COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
ORDER BY ORDINAL_POSITION
""")
for col in cursor.fetchall():
print(col)
# Match your data to the column order
rows = [
(1, "Widget", Decimal("19.99")), # Must match table column order
(2, "Gadget", Decimal("29.99")),
]
cursor.bulkcopy("dbo.MyTable", rows)
Typové neshody během hromadné kopie
Příznaky:
Data se načítají, ale hodnoty jsou zkrácené, zaokrouhlené nebo nesprávné.
Příčina:
Hodnoty Pythonu nelze jednoznačně mapovat na typy cílových sloupců. Běžné případy: float hodnoty načtené do decimal sloupců (ztráta přesnosti) nebo nadměrně velké řetězce načtené do sloupců s pevnou délkou.
Oprava:
Použijte správné typy Python, které odpovídají vašemu schématu:
from decimal import Decimal
# Use Decimal for decimal/numeric columns, not float
rows = [
(1, "Widget", Decimal("19.99")), # Correct
# (1, "Widget", 19.99), # Avoid: float loses precision
]
cursor.bulkcopy("dbo.Products", rows)
Selhání vázání typu Numpy
Příznaky:
Parametry při použití celočíselných typů NumPy nebo typů s plovoucí desetinnou čárkou buď tiše selžou, nebo vyvolají chyby datového typu.
Příčina:
Typy NumPy, jako numpy.int64 a numpy.int32, neprojdou přes isinstance(x, int) v NumPy 2.x. Typová inference řidiče je nerozpozná, což způsobuje neočekávané chování.
Oprava:
Převeďte hodnoty NumPy na nativní typy jazyka Python před navázáním:
import numpy as np
# Convert individual values
cursor.execute("SELECT * FROM Production.Product WHERE ProductID = %(product_id)s", {"product_id": int(np.int64(42))})
# Convert DataFrame values
for _, row in df.iterrows():
cursor.execute(
"INSERT INTO #Orders (ProductID, Qty) VALUES (%(product_id)s, %(qty)s)",
{"product_id": int(row["ProductID"]), "qty": int(row["Qty"])}
)
Pro větší datové sady použijte integrační cesty Arrow nebo pandas , které interně řeší převod typů.
Bulkcopy s dočasnými tabulkami
Příznaky:
cursor.bulkcopy("#TempTable", data) vyvolá RuntimeError: Invalid object name '#TempTable'.
Příčina:
bulkcopy() nelze rozpoznat dočasné tabulky relace (#tablename) kvůli omezením při vyhledávání metadat. Globální dočasné tabulky (##tablename) a trvalé tabulky fungují.
Oprava:
Použijte globální dočasnou tabulku nebo běžnou pracovní tabulku:
# Global temp table (visible to all sessions, dropped when last session disconnects)
cursor.execute("CREATE TABLE ##Staging (ID INT, Name NVARCHAR(50))")
cursor.bulkcopy("##Staging", rows)
# Or use a permanent staging table
cursor.execute("CREATE TABLE dbo.Staging (ID INT, Name NVARCHAR(50))")
cursor.bulkcopy("dbo.Staging", rows)
Pro malé datové sady, kde je preferována tabulka session temp, použijte executemany() místo toho:
cursor.execute("CREATE TABLE #Staging (ID INT, Name NVARCHAR(50))")
cursor.executemany("INSERT INTO #Staging (ID, Name) VALUES (?, ?)", rows)
Problémy s kontejnery a CI
Chybějící systémové knihovny na Linuxu
Příznaky:
ImportError: libltdl.so.7: cannot open shared object file: No such file or directory
ImportError: libkrb5.so.3: cannot open shared object file
Oprava:
Nainstalujte potřebné systémové balíčky. Balíčky se liší podle rozdělení:
| Distribution | Instalační příkaz |
|---|---|
| Ubuntu / Debian | sudo apt-get install libltdl7 libkrb5-3 libgssapi-krb5-2 |
| Red Hat / Fedora | sudo dnf install libtool-ltdl krb5-libs |
| Alpine | apk add libltdl krb5-libs |
Pro příklady Dockerfile viz Container a lokální vývoj.
Chyby macOS SSL po instalaci
Příznaky:
Chyby související se SSL při připojení z macOS, zejména na Apple Silicon.
Oprava:
Nainstalujte OpenSSL pomocí Homebrew a nastavte příznaky pro linker:
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"
Diagnostické nástroje
Povolit logování ovladačů
Použijte mssql_python.setup_logging() pro povolení komplexního DEBUG logování pro řešení problémů. Všechny operace ovladačů jsou zaznamenány, včetně SQL příkazů, parametrů, interních operací ODBC a změn stavu spojení.
import mssql_python
# Enable logging to file (default)
mssql_python.setup_logging()
# Output to stdout (useful for CI/CD and containers)
mssql_python.setup_logging(output='stdout')
# Output to both file and stdout
mssql_python.setup_logging(output='both')
# Custom log file path (must use .txt, .log, or .csv extension)
mssql_python.setup_logging(log_file_path="/var/log/myapp/mssql.log")
Protokolové soubory se ukládají ve formátu CSV a při dosažení velikosti 512 MB se automaticky rotují s uchováním pěti záložních souborů. Citlivá data jako hesla a přístupové tokeny jsou automaticky sanitizována ve výstupu z logu.
Pro přidání vlastních záznamů v logu vedle záznamů řidičů použijte driver_logger:
from mssql_python.logging import driver_logger
mssql_python.setup_logging()
driver_logger.debug("[App] Starting data processing")
driver_logger.error("[App] Failed to process record")
# Your entries appear in the same file with the same format
Caution
Logování má dopad na výkon. Zapněte ho pouze při řešení problémů, ne ve výchozím nastavení v produkci.
Získejte informace o řidiči
Získejte verzi ovladače a detaily serveru z aktivního připojení:
import mssql_python
conn = mssql_python.connect(connection_string)
# Driver version
print(f"Version: {mssql_python.__version__}")
# Server information
print(f"Server name: {conn.getinfo(mssql_python.SQL_SERVER_NAME)}")
print(f"Database name: {conn.getinfo(mssql_python.SQL_DATABASE_NAME)}")
Kontrola stavu připojení
Otestujte, zda je spojení stále otevřené, než se pokusíte o operace:
try:
cursor = conn.cursor()
cursor.execute("SELECT 1")
print("Connection is open")
except mssql_python.Error:
print("Connection is closed or broken")
Rychlá reference: Běžné chyby
| Error | SQLSTATE | Obvyklá příčina | Rychlá oprava |
|---|---|---|---|
| Klient nedokáže navázat spojení | 08001 | Nedostupný server | Zkontrolujte název serveru/port |
| Přihlášení se nezdařilo. | 28000 | Špatné kvalifikace | Ověřte uživatelské jméno/heslo |
| Vypršel časový limit. | HYT00/HYT01 | Pomalá síť | Zvyšte časový limit |
| Neplatný název objektu | 42S02 | Špatná tabulka/schéma | Používejte plně kvalifikovaná jména |
| Chyba syntaxe | 42000 | SQL chyba | Použití parametrizovaných dotazů |
| Porušení omezení | 23000 | Porušení FK/PK | Zkontrolujte integritu dat |
| Vzájemné zablokování | 40001 | Soutěž o zámky | Zkuste to znovu a poté analyzujte graf uváznutí |