Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Mendiagnosis dan menyelesaikan masalah umum saat menggunakan driver mssql-python untuk terhubung ke SQL Server, Azure SQL Database, Azure SQL Managed Instance, dan database SQL di Microsoft Fabric.
Masalah penginstalan
pip gagal diinstal atau dikompilasi dari kode sumber
Gejala:
error: Microsoft Visual C++ 14.0 or greater is required
ERROR: Failed building wheel for mssql-python
Kemungkinan penyebab dan solusi:
Tidak ada roda bawaan untuk platform Anda
- Periksa apakah Anda menjalankan versi Python yang didukung (versi 3.10 dan versi yang lebih baru) dan platform. Lihat Siklus hidup dukungan untuk matriks kompatibilitas. Perbarui pip sebelum menginstal dengan
pip install --upgrade pip. Untuk lingkungan tim yang dapat diulang, gunakan alur kerja terkunci di Penyebaran yang dapat diulang atau pola kontainer di Kontainer dan pengembangan lokal untuk mengurangi penyimpangan mesin lokal.
- Periksa apakah Anda menjalankan versi Python yang didukung (versi 3.10 dan versi yang lebih baru) dan platform. Lihat Siklus hidup dukungan untuk matriks kompatibilitas. Perbarui pip sebelum menginstal dengan
Lingkungan virtual tidak diaktifkan
- Aktifkan lingkungan virtual Anda terlebih dahulu. Menginstal ke dalam sistem Python dapat menyebabkan kesalahan atau konflik izin.
python -m venv .venv .venv\Scripts\activate pip install mssql-python
-
Pustaka sistem Linux yang hilang
- Driver memerlukan sekumpulan kecil pustaka sistem di Linux. Lihat Dependensi khusus platform untuk paket yang akan diinstal.
Penginstalan driver yang bertentangan
Gejala:
Impor kesalahan atau perilaku tak terduga setelah menginstal mssql-python bersama pyodbc di lingkungan yang sama.
Perbaikan pada :
mssql-python dan pyodbc dapat hidup berdampingan. Jika Anda melihat konflik, buat lingkungan virtual yang bersih:
python -m venv .venv --clear
.venv\Scripts\activate
pip install mssql-python
Masalah koneksi
Tidak dapat terhubung ke server
Gejala:
OperationalError: [08001] (0) Client unable to establish connection
Kemungkinan penyebab dan solusi:
Server tidak dapat dijangkau
- Pastikan nama server dan port sudah benar.
- Periksa konektivitas jaringan:
ping servernameatautelnet servername 1433. - Pastikan firewall mengizinkan koneksi keluar pada port 1433.
SQL Server tidak berjalan
- Verifikasi layanan SQL Server dimulai.
- Untuk instans bernama, pastikan bahwa layanan SQL Server Browser sedang berjalan.
Aturan firewall Azure SQL
- Tambahkan IP klien Anda ke aturan firewall Azure SQL di portal Azure.
- Untuk Azure SQL Managed Instance, pastikan Anda terhubung dari jaringan yang diizinkan.
# 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}")
Gagal masuk
Gejala:
OperationalError: [28000] (18456) Login failed for user 'username'.
Kemungkinan penyebab dan solusi:
Ketidakcocokan mode autentikasi
- Untuk Azure SQL Database, Azure SQL Managed Instance, dan database SQL dalam Fabric, sebaiknya gunakan mode autentikasi Microsoft Entra seperti
Authentication=ActiveDirectoryDefault. - Jika Anda menggunakan autentikasi SQL dengan sengaja, verifikasi bahwa server mengizinkannya dan Anda menggunakan format login yang benar untuk titik akhir tersebut.
- Untuk Azure SQL Database, Azure SQL Managed Instance, dan database SQL dalam Fabric, sebaiknya gunakan mode autentikasi Microsoft Entra seperti
Kredensial autentikasi SQL yang salah
- Verifikasi nama pengguna dan kata sandi.
- Untuk Azure SQL, sertakan nama pengguna lengkap:
username@servername.
Pengguna tidak ada dalam database
- Verifikasi pengguna memiliki akses ke database yang ditentukan.
- Periksa apakah proses masuk dipetakan ke pengguna basis data.
Autentikasi tidak dikonfigurasi
- Gunakan autentikasi Microsoft Entra (disarankan):
Authentication=ActiveDirectoryDefault. - Jika Anda memecahkan masalah SQL Server lokal yang harus menerima autentikasi SQL, verifikasi bahwa SQL Server menggunakan autentikasi mode campuran.
- Gunakan autentikasi Microsoft Entra (disarankan):
Waktu koneksi habis
Gejala:
OperationalError: [HYT00] (0) Timeout expired
OperationalError: [HYT01] (0) Connection timeout expired
Kemungkinan penyebab dan solusi:
Server lambat merespons
- Tingkatkan batas waktu koneksi:
conn = mssql_python.connect(connection_string, timeout=60)Latensi jaringan
- Periksa jalur jaringan ke server.
- Pertimbangkan untuk menggunakan jalur jaringan atau VPN yang lebih pendek.
Server di bawah beban berat
- Cobalah terhubung di luar jam sibuk.
- Hubungi administrator database Anda.
Kesalahan sertifikat SSL
Gejala:
OperationalError: [08001] SSL Provider: The certificate chain was issued by an authority that is not trusted
Solusi:
Pertama, utamakan sertifikat tepercaya atau pola pengembangan lokal di Container dan pengembangan lokal. Gunakan TrustServerCertificate=yes hanya untuk pengembangan lokal terhadap server yang Anda kendalikan.
Untuk pengembangan dan pengujian dengan sertifikat yang ditandatangani sendiri:
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 adalah cadangan yang hanya bersifat lokal. Jangan membawanya ke devcontainer bersama, alur CI, atau penyebaran produksi. Untuk panduan yang lebih luas, lihat Enkripsi dan sertifikat.
Untuk produksi, pastikan sertifikat yang tepat dipasang dan gunakan:
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes;"
"HostnameInCertificate=<server>.domain.com;"
)
Masalah eksekusi kueri
Tabel atau objek tidak ditemukan
Gejala:
ProgrammingError: [42S02] (208) Invalid object name 'TableName'.
Kemungkinan penyebab dan solusi:
Konteks database yang salah
# Ensure you're connected to the correct database cursor.execute("SELECT DB_NAME()") print(cursor.fetchone()[0])Skema tidak ditentukan
# Use fully qualified name cursor.execute("SELECT * FROM dbo.TableName")Tabel tidak ada
# Check if table exists cursor.execute(""" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'TableName' """)
Kesalahan sintaks
Gejala:
ProgrammingError: [42000] (102) Incorrect syntax near '...'.
Solusi:
Uji SQL di SSMS terlebih dahulu untuk memverifikasi sintaks
Periksa escape string - gunakan kueri berparameter:
# 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})
Kesalahan parameter
Gejala:
ProgrammingError: [07001] Wrong number of parameters
Solusi:
Hitung placeholder dan parameter - jumlahnya harus sama
Pilih gaya parameter yang tepat:
# 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())
Masalah jenis data
Kesalahan konversi tanggal dan waktu
Gejala:
DataError: [22007] Invalid datetime format
Solusi:
Gunakan objek datetime Python alih-alih string:
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())
Masalah presisi desimal
Gejala:
Angka tampak terpotong atau dibulatkan dengan tidak benar.
Solusi:
Gunakan decimal.Decimal untuk nilai numerik yang tepat:
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")}
)
Masalah pengkodean Unicode
Gejala:
Karakter khusus muncul kacau atau menyebabkan kesalahan.
Solusi:
Menggunakan kolom NVARCHAR untuk data Unicode dalam database Anda
Teruskan string secara langsung - driver menangani pengkodean:
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())
Masalah performa
Eksekusi kueri yang lambat
Kemungkinan penyebab dan solusi:
Indeks yang hilang: Periksa rencana eksekusi kueri di SSMS.
Kumpulan hasil besar: Gunakan
fetchmany()alih-alihfetchall():cursor.arraysize = 1000 while True: rows = cursor.fetchmany() if not rows: break process_rows(rows)Pengumpulan koneksi dinonaktifkan: Aktifkan pengumpulan:
import mssql_python mssql_python.pooling(max_size=20, idle_timeout=300)
Masalah memori dengan hasil yang besar
Gejala:
Proses Python kehabisan memori.
Solusi:
Tampilkan hasil secara streaming alih-alih memuat semuanya ke memori:
cursor.execute("SELECT * FROM LargeTable") for row in cursor: # Iterates one row at a time process_row(row)Gunakan paginasi sisi server:
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
Masalah transaksi
Ruang lingkup tabel temporer dengan autocommit
Tabel sementara (#tablename) yang dibuat di dalam transaksi menghilang saat transaksi diputar kembali. Hal ini adalah sumber kebingungan yang umum saat autocommit dinonaktifkan (setelan bawaan):
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")
Perbaiki: Terapkan segera setelah membuat tabel sementara, atau gunakan mode penerapan otomatis:
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()
Pernyataan DDL yang memerlukan mode penerapan otomatis, seperti CREATE DATABASE, gagal di dalam transaksi terbuka. Atur autocommit sebelum menjalankannya:
conn.autocommit = True
cursor.execute("CREATE DATABASE TestDB")
conn.autocommit = False
Transaksi tidak dilakukan
Gejala:
Perubahan data tidak akan tetap ada setelah menutup koneksi.
Solution:
Dengan autocommit=False (default), Anda harus memanggil 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!
Atau gunakan mode komit otomatis:
conn = mssql_python.connect(connection_string, autocommit=True)
Kesalahan deadlock
Gejala:
OperationalError: [40001] (1205) Transaction ... was deadlocked on lock resources with another process
Solution:
Logika coba lagi (lihat Logika coba ulang) menangani kegagalan langsung, tetapi kebuntuan berulang menunjukkan masalah desain. Untuk memperbaiki akar penyebabnya, tangkap grafik kebuntuan dan analisis pernyataan dan jenis kunci mana yang terlibat. Perbaikan umum mencakup mengubah urutan operasi agar transaksi yang saling bersaing memperoleh kunci dalam urutan yang sama, mengurangi ruang lingkup transaksi, dan menambahkan indeks yang sesuai untuk mengurangi durasi penguncian.
Untuk panduan lengkap analisis kebuntuan, lihat Panduan kebuntuan. Jika Anda menggunakan Azure SQL Database, lihat Menganalisis dan mencegah kebuntuan.
Masalah pemuatan massal
Pelanggaran batasan selama salinan massal
Gejala:
RuntimeError: CHECK constraint ... Conflict occurred in database ...
RuntimeError: Cannot insert duplicate key ... violation of PRIMARY KEY constraint
Penyebab:
Data dalam batch Anda melanggar batasan tabel (kunci utama, unik, CHECK, atau kunci asing).
Perbaikan pada :
Validasi data sebelum memuat. Untuk dataset besar, muat terlebih dahulu ke tabel staging, lalu gabungkan ke tabel target:
# 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()
Untuk pola upsert dengan tabel staging, lihat Pola pemuatan dan pemindahan data.
Kesalahan pemetaan kolom
Gejala:
RuntimeError: Bulk copy failure - column count mismatch
Penyebab:
Jumlah kolom dalam data Anda tidak cocok dengan jumlah kolom tabel target, atau kolom dalam urutan yang salah.
Perbaikan pada :
Pastikan data Anda cocok dengan skema tabel secara tepat dalam urutan dan jumlah:
# 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)
Ketidakcocokan tipe data selama bulk copy
Gejala:
Data dimuat tetapi nilai dipotong, dibulatkan, atau salah.
Penyebab:
Nilai Python tidak cocok secara langsung dengan tipe kolom target. Kasus umum: nilai float yang dimuat ke kolom decimal (hilangnya presisi), atau string yang terlalu panjang yang dimuat ke kolom dengan panjang tetap.
Perbaikan pada :
Gunakan jenis Python yang benar yang cocok dengan skema Anda:
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)
Kegagalan binding tipe NumPy
Gejala:
Parameter gagal tanpa peringatan atau memunculkan kesalahan tipe data saat menggunakan tipe bilangan bulat atau floating point NumPy.
Penyebab:
Tipe NumPy seperti numpy.int64 dan numpy.int32 tidak lolos isinstance(x, int) di NumPy 2.x. Inferensi tipe pada driver tidak dapat mengenalinya, yang menyebabkan perilaku tak terduga.
Perbaikan pada :
Konversi nilai numpy ke jenis Python asli sebelum mengikat:
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"])}
)
Untuk himpunan data yang lebih besar, gunakan opsi integrasi Arrow atau pandas, yang menangani konversi tipe secara internal.
Salin massal dengan tabel sementara
Gejala:
cursor.bulkcopy("#TempTable", data) menaikkan RuntimeError: Invalid object name '#TempTable'.
Penyebab:
bulkcopy() Tidak dapat menyelesaikan tabel sementara sesi (#tablename) karena batasan pencarian metadata. Tabel suhu global (##tablename) dan tabel permanen berfungsi.
Perbaikan pada :
Gunakan tabel temp global atau tabel pementasan reguler:
# 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)
Untuk himpunan data kecil di mana tabel sementara sesi lebih disukai, gunakan executemany() sebagai gantinya:
cursor.execute("CREATE TABLE #Staging (ID INT, Name NVARCHAR(50))")
cursor.executemany("INSERT INTO #Staging (ID, Name) VALUES (?, ?)", rows)
Masalah kontainer dan CI
Pustaka sistem yang hilang di Linux
Gejala:
ImportError: libltdl.so.7: cannot open shared object file: No such file or directory
ImportError: libkrb5.so.3: cannot open shared object file
Perbaikan pada :
Instal paket sistem yang diperlukan. Paketnya berbeda berdasarkan distribusi:
| Distribution | Perintah instalasi |
|---|---|
| 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 |
Untuk contoh Dockerfile, lihat Kontainer dan pengembangan lokal.
Kesalahan SSL macOS setelah penginstalan
Gejala:
Kesalahan terkait SSL saat menyambungkan dari macOS, terutama di Apple Silicon.
Perbaikan pada :
Instal OpenSSL melalui Homebrew dan atur bendera linker:
brew install openssl
export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"
Alat diagnostik
Aktifkan pencatatan log driver
Gunakan mssql_python.setup_logging() untuk mengaktifkan pengelogan DEBUG yang komprehensif untuk pemecahan masalah. Semua operasi driver dicatat, termasuk pernyataan SQL, parameter, operasi ODBC internal, dan perubahan status koneksi.
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")
File log ditulis dalam format CSV dan secara otomatis dirotasi saat mencapai 512 MB dengan lima file cadangan. Data sensitif seperti kata sandi dan token akses secara otomatis dibersihkan dalam output log.
Untuk menambahkan entri log Anda sendiri di samping log driver, gunakan 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
Pencatatan log menimbulkan overhead pada kinerja. Aktifkan hanya saat pemecahan masalah, bukan dalam produksi secara default.
Dapatkan informasi pengemudi
Ambil versi driver dan detail server dari koneksi aktif:
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)}")
Periksa status koneksi
Menguji apakah koneksi masih terbuka sebelum mencoba operasi:
try:
cursor = conn.cursor()
cursor.execute("SELECT 1")
print("Connection is open")
except mssql_python.Error:
print("Connection is closed or broken")
Referensi cepat: Kesalahan umum
| Kesalahan | SQLSTATE | Penyebab umum | Perbaikan cepat |
|---|---|---|---|
| Klien tidak dapat membuat koneksi | 08001 | Server tidak dapat dijangkau | Periksa nama server/port |
| Gagal masuk | 28000 | Kredensial tidak valid | Verifikasi nama pengguna/kata sandi |
| Waktu tunggu habis | HYT00 / HYT01 | Jaringan lambat | Meningkatkan batas waktu |
| Nama objek tidak valid | 42S02 | Tabel/skema yang salah | Gunakan nama yang sepenuhnya memenuhi syarat |
| Kesalahan sintaks | 42000 | Kesalahan SQL | Menggunakan kueri berparameter |
| Pelanggaran batasan | 23000 | Pelanggaran FK/PK | Periksa integritas data |
| Kebuntuan | 40001 | Mengunci ketidaksesuaian | Coba lagi, lalu analisis grafik kebuntuan |