Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Sterownik mssql-python automatycznie mapuje typy danych Python na typy SQL Server podczas wysyłania parametrów i konwertuje typy SQL Server na typy Python podczas pobierania wyników.
Mappingi Python do SQL Server
Gdy przekazujesz wartości Python jako parametry do execute() lub executemany(), sterownik automatycznie wybiera odpowiedni typ SQL Server. W większości zastosowań automatyczne mapowanie jest poprawne. Używaj setinputsizes() (opisanego później w tym artykule) tylko wtedy, gdy musisz nadpisać domyślne, na przykład aby wymusić varchar zamiast nvarchar lub kontrolować metadane parametrów dla łańcuchów i liczb całkowitych.
| Typ języka Python | Typ programu SQL Server | Notatki |
|---|---|---|
None |
NULL |
Wartość SQL NULL. |
bool |
bit |
True→1, False→0. |
int |
tinyint, smallint, int, bigint | Rozmiar wybierany w zależności od zakresu wartości. |
float |
float | 64-bitowy zmiennoprzecinkowy. |
decimal.Decimal |
Dziesiętny, numeryczny | Zachowuje precyzję do 38 cyfr. |
str |
Varchar, Nvarchar | Używa nvarchar do zawartości Unicode. |
bytes, bytearray |
varbinary | Dane binarne. |
datetime.date |
date | Tylko randka. |
datetime.time |
time | Tylko czas. |
datetime.datetime |
datetime2 | Data i czas z precyzją nanosekund. |
uuid.UUID |
uniqueidentifier | 16-bajtowy GUID. |
Wybór typu całkowitego
Sterownik automatycznie wybiera najmniejszy typ liczby całkowitej, który może pomieścić tę wartość:
| Zakres wartości | Typ programu SQL Server |
|---|---|
| Od 0 do 255 | tinyint |
| -32,768 do 32,767 | smallint |
| -2,147,483,648 do 2,147,483,647 | int |
| Większe wartości | bigint |
Typy o dużej wartości
Dla łańcuchów i danych binarnych przekraczających standardowe limity, sterownik automatycznie używa typów MAX:
| Warunek | Typ programu SQL Server |
|---|---|
| Ciąg > 8 000 bajtów (varchar) | varchar(max) |
| String > 4 000 chars (nvarchar) | nvarchar(max) |
| Binarne > 8 000 bajtów | varbinary(max) |
Sterownik przesyła duże wartości do serwera, aby zminimalizować zużycie pamięci.
Mappingi SQL Server do Python
Gdy sterownik pobiera dane z SQL Server, konwertuje wartości na typy w Python:
| Typ programu SQL Server | Typ języka Python | Notatki |
|---|---|---|
| bit | bool |
Prawda/fałsz. |
| tinyint, smallint, int, bigint | int |
Python integer (dowolna precyzja). |
| prawdziwy | float |
32-bitowy zmiennoprzecinkowa. |
| float | float |
64-bitowy zmiennoprzecinkowy. |
| Dziesiętny, numeryczny | decimal.Decimal |
Zachowuje precyzję. |
| pieniądze, drobne pieniądze | decimal.Decimal |
Stała precyzja (cztery miejsca po przecinku). |
| Char, Varchar, tekst | str |
Rozszyfrowane jako UTF-8. |
| nchar, nvarchar, ntext | str |
Rozszyfrowane jako UTF-16LE. |
| binarny, varbinary, obraz | bytes |
Surowa binarność. |
| date | datetime.date |
Tylko randka. |
| time | datetime.time |
Czas z mikrosekundową precyzją. |
| randka,mała randkagodzina | datetime.datetime |
Starsze typy randki. |
| datetime2 | datetime.datetime |
Bardzo precyzyjny czas randkowy. |
| datetimeoffset | datetime.datetime |
Czas randkowy świadomy strefy czasowej. |
| uniqueidentifier | uuid.UUID |
Obiekty UUID Python. |
| xml | str |
XML jako tekst. |
| Geografia, geometria | bytes |
Typy przestrzenne jako binarne. |
| hierarchyid | bytes |
Dane hierarchiczne jako binarne. |
| sql_variant | Varies | Rozwiązane do podstawowego typu bazowego.
sql_variant Kolumny korzystają ze ścieżki pobierania strumieniowej, co może mieć niewielki wpływ na wydajność w porównaniu do kolumn typu stałego. |
NULL |
None |
Python Żadna. |
Stałe typu SQL
Sterownik eksportuje stałe odpowiadające identyfikatorom typu SQL ODBC. Zazwyczaj używasz tych stałych z , setinputsizes() aby nadpisać domyślne wnioskowanie typu sterownika, gdy automatyczne mapowanie nie odpowiada twojemu schematowi.
Typy znaków
| Stały | Wartość | Opis |
|---|---|---|
SQL_CHAR |
1 | Znak ANSI o stałej długości. |
SQL_VARCHAR |
12 | Znak ANSI o zmiennej długości. |
SQL_LONGVARCHAR |
-1 | Długie ANSI o zmiennej długości. |
SQL_WCHAR |
-8 | Unicode o stałej długości. |
SQL_WVARCHAR |
-9 | Unicode o zmiennej długości. |
SQL_WLONGVARCHAR |
-10 | Długi Unicode o zmiennej długości. |
Typy liczbowe
| Stały | Wartość | Opis |
|---|---|---|
SQL_BIT |
-7 | Bit/boolean. |
SQL_TINYINT |
-6 | 8-bitowa liczba całkowita bez znaku. |
SQL_SMALLINT |
5 | 16-bitowa liczba całkowita ze znakiem. |
SQL_INTEGER |
4 | 32-bitowa liczba całkowita ze znakiem. |
SQL_BIGINT |
-5 | 64-bitowa liczba całkowita ze znakiem. |
SQL_REAL |
7 | 32-bitowy zmiennoprzecinkowa. |
SQL_FLOAT |
6 | 64-bitowy zmiennoprzecinkowy. |
SQL_DOUBLE |
8 | 64-bitowy zmiennoprzecinkowy. |
SQL_DECIMAL |
3 | Stała precyzja dziesiętna. |
SQL_NUMERIC |
2 | Stała precyzja numeryczna. |
Typy dat i godzin
| Stały | Wartość | Opis |
|---|---|---|
SQL_TYPE_DATE |
91 | Tylko randka. |
SQL_TYPE_TIME |
92 | Tylko czas. |
SQL_TYPE_TIMESTAMP |
93 | Data i godzina. |
SQL_SS_TIME2 |
-154 | SQL Server time(n). |
SQL_DATETIMEOFFSET |
-155 | SQL Server datetimeoffset. |
Note
SQL_SS_TIME2 oraz SQL_DATETIMEOFFSET są stałymi wewnętrznymi, które nie są eksportowane jako atrybuty na poziomie modułu. Używaj wartości całkowitych (-154, -155) bezpośrednio podczas wywoływania add_output_converter().
Typy binarne
| Stały | Wartość | Opis |
|---|---|---|
SQL_BINARY |
-2 | Binarny o stałej długości. |
SQL_VARBINARY |
-3 | Binarny o zmiennej długości. |
SQL_LONGVARBINARY |
-4 | Długi binarny o zmiennej długości. |
Inne typy
| Stały | Wartość | Opis |
|---|---|---|
SQL_GUID |
-11 | Unikalny identyfikator. |
SQL_XML |
-152 | Dane XML. |
SQL_SS_UDT |
-151 | Typ zdefiniowany przez użytkownika (przestrzenny). |
SQL_SS_VARIANT |
-150 | sql_variant danych. |
Note
SQL_SS_UDT oraz SQL_SS_VARIANT są stałymi wewnętrznymi, które nie są eksportowane jako atrybuty na poziomie modułu. Używaj wartości całkowitych (-151, -150) bezpośrednio podczas wywoływania add_output_converter().
Użyj setinputsizes()
Wywołaj przed setinputsizes() wywołaniemexecutemany(), aby jawnie zadeklarować typy parametrów, gdy automatyczne wnioskowanie typu sterownika powoduje nieoczekiwane zachowanie, na przykład gdy kolumna jest, varchar(100) ale sterownik wysyła nvarchar:
Note
Dla wartości dziesiętnych polegaj na automatycznym wnioskowaniu typów kierowcy, a nie SQL_DECIMAL na lub SQL_NUMERIC. Te jawne stałe typu dziesiętnego mają obecnie znany problem z .setinputsizes() Więcej informacji można znaleźć w artykule Wykonaj zapytania.
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
# Declare types: (sql_type, precision, scale)
cursor.setinputsizes([
(mssql_python.SQL_WVARCHAR, 100, 0), # nvarchar(100)
(mssql_python.SQL_INTEGER, 0, 0), # int
])
cursor.executemany(
"SELECT ProductID, Name FROM Production.Product WHERE Name LIKE ? AND ProductSubcategoryID = ?",
[
("Road%", 2),
("Mountain%", 1),
]
)
Separator dziesiętny
Sterownik używa separatorów dziesiętnych uwzględniających lokalizację. Opcje dostosowania:
import mssql_python
# Get current separator
sep = mssql_python.getDecimalSeparator()
print(f"Current separator: {sep}") # Usually "."
# Set custom separator (for locales using comma)
mssql_python.setDecimalSeparator(",")
Konwertery niestandardowe typu
Rejestruj niestandardowe konwertery dla konkretnych typów SQL:
import mssql_python
from decimal import Decimal
def money_to_float(value):
"""Convert money values to float instead of Decimal."""
if value is None:
return None
return float(value)
conn.add_output_converter(Decimal, money_to_float)
Więcej informacji można znaleźć w artykule Niestandardowe przetworniki typu.
Specjalne typy uchwytów
Obsługa UUID
Sterownik automatycznie się mapuje uuid.UUIDuniqueidentifier . Możesz wstawiać i pobierać UUID bez ręcznej konwersji ciągów znaków:
import uuid
cursor.execute("CREATE TABLE #Users (UserId UNIQUEIDENTIFIER PRIMARY KEY, Name NVARCHAR(100))")
# Insert a generated UUID
user_id = uuid.uuid4()
cursor.execute("INSERT INTO #Users (UserId, Name) VALUES (%(user_id)s, %(name)s)", {"user_id": user_id, "name": "Alice"})
conn.commit()
# Retrieve as uuid.UUID object (default behavior)
cursor.execute("SELECT UserId, Name FROM #Users WHERE Name = %(name)s", {"name": "Alice"})
row = cursor.fetchone()
print(f"Type: {type(row.UserId)}") # <class 'uuid.UUID'>
print(f"UUID: {row.UserId}") # e.g., 3b4c8f2a-...
# Use the returned UUID directly in subsequent queries
cursor.execute("SELECT Name FROM #Users WHERE UserId = %(user_id)s", {"user_id": row.UserId})
Domyślnie sterownik zwraca UNIQUEIDENTIFIER kolumny jako uuid.UUID obiekty. Aby zwrócić ciągi znaków zgodnych z pyodbc, ustaw native_uuid=False:
import uuid
# Per-connection: return UUIDs as strings
conn2 = mssql_python.connect(connection_string, native_uuid=False)
cursor2 = conn2.cursor()
cursor2.execute("CREATE TABLE #UuidDemo (Id UNIQUEIDENTIFIER DEFAULT NEWID(), Label NVARCHAR(50))")
cursor2.execute("INSERT INTO #UuidDemo (Label) VALUES (%(label)s)", {"label": "test"})
conn2.commit()
cursor2.execute("SELECT Id FROM #UuidDemo")
row = cursor2.fetchone()
print(type(row[0])) # <class 'str'>
print(row[0]) # e.g., 3B4C8F2A-...
conn2.close()
Aby poznać konfigurację na poziomie modułu, zobacz native_uuid ustawienia w konfiguracji modułu.
Czas daty ze strefą czasową
datetimeoffset kolumny zwracają obiekty uwzględniające datetime strefy czasowe. Aby uzyskać wskazówki dotyczące pracy z wartościami świadomymi offsetu a wartościami naiwnymi offsetowymi, zobacz Obsługa czasu datowego.
cursor.execute("SELECT SYSDATETIMEOFFSET()")
row = cursor.fetchone()
dt = row[0]
print(f"DateTime: {dt}")
print(f"Timezone: {dt.tzinfo}")
Dane przestrzenne
Sterownik zwraca typy przestrzenne (geography, geometry) jako .bytes Możesz używać ciągów parametrów w formacie WKT:
# Insert using WKT
cursor.execute("CREATE TABLE #Locations (Name NVARCHAR(100), Geo GEOGRAPHY)")
cursor.execute(
"INSERT INTO #Locations (Name, Geo) VALUES (%(name)s, geography::STGeomFromText(%(wkt)s, 4326))",
{"name": "Seattle", "wkt": "POINT(-122.33 47.60)"}
)
# Retrieve as bytes
cursor.execute("SELECT Geo.STAsBinary() FROM #Locations")
row = cursor.fetchone()
geo_bytes = row[0]
wersja wiersza/znacznik czasu
SQL Server (dawniej rowversion) jest timestamp typem binarnym, a nie datą:
cursor.execute("""
CREATE TABLE #RowVersionDemo (
ID int PRIMARY KEY,
Version rowversion
)
""")
cursor.execute("INSERT INTO #RowVersionDemo (ID) VALUES (1)")
cursor.execute("SELECT Version FROM #RowVersionDemo WHERE ID = 1")
row = cursor.fetchone()
version = row[0] # bytes, not datetime
Strumienie dużych wartości
Podczas wstawiania lub pobierania varchar(max), nvarchar(max), lub varbinary(max) danych, sterownik korzysta ze strumieniowania danych przy wykonaniu (DAE) do przesyłania danych w fragmentach, zamiast ładować całą wartość do pamięci jednocześnie.
Streaming aktywuje się automatycznie, gdy dane wejściowe przekraczają progi rozmiaru:
| Typ danych | Próg strumieniowania |
|---|---|
| varchar(max) | > 8 000 bajtów |
| nvarchar(max) | > 4 000 znaków |
| varbinary(max) | > 8 000 bajtów |
Streaming działa z execute(), executemany(), oraz wszystkimi API pobierania (fetchone(), fetchmany(), ). fetchall() Sterownik nie wymaga specjalnej konfiguracji i obsługuje automatyczne strumieniowanie dla dużych wartości.
Nieobsługiwane typy SQL Server
Poniższe typy SQL Server nie mają natywnych mapowań typów Python.
| Typ programu SQL Server | Status |
|---|---|
| json | Niewspierane |
| vector | Niewspierane |
| table | Nie obsługiwane (parametry tabelowe) |
Wskazówka
Chociaż typ SQL Server nie jest bezpośrednio obsługiwany json , można przechowywać dane JSON w nvarchar(max) kolumnach i zapytywać je za pomocą funkcji JSON w SQL Server (JSON_VALUE, JSON_QUERY, ). OPENJSON Wzorce i przykłady można znaleźć w danych JSON.
Następujące typy zwracają dane jako bytes natywne mapowania typów Python, ale nie posiadają:
| Typ programu SQL Server | Typ języka Python | Notatki |
|---|---|---|
| geography | bytes |
Zastosowanie .STAsBinary() w formacie WKB. |
| geometry | bytes |
Zastosowanie .STAsBinary() w formacie WKB. |
| hierarchyid | bytes |
Reprezentacja binarna. |
| sql_variant | Varies | Rozwiązane do podstawowego typu bazowego. |
Precyzja dziesiętna vs pływająca
Używaj wtedy decimal.Decimal , gdy istotna jest dokładna precyzja, na przykład przy obliczeniach finansowych, pieniądzu lub w jakiejkolwiek wartości, gdzie błędy zaokrągleń są nie do przyjęcia. Stosuj, float gdy wartości przybliżone są akceptowalne, na przykład w pomiarach naukowych lub odczytach z czujników.
Sterownik mapuje decimal.Decimal się na SQL Server decimal/numeric i zachowuje precyzję do 38 cyfr.
floatmapuje do SQL Server float (64-bitowy IEEE 754), który może wprowadzać artefakty zaokrągleń:
from decimal import Decimal
# Exact - use for currency and financial data
price = Decimal("19.99")
tax_rate = Decimal("0.0825")
total = price * (1 + tax_rate) # Decimal("21.6391750")
cursor.execute("""
CREATE TABLE #PrecisionDemo (
Description NVARCHAR(100),
DiscountPct DECIMAL(5,2),
Rating FLOAT
)
""")
cursor.execute(
"INSERT INTO #PrecisionDemo (Description, DiscountPct, Rating) VALUES (%(desc)s, %(pct)s, %(rating)s)",
{"desc": "Summer sale", "pct": Decimal("0.15"), "rating": 4.5}
)
cursor.execute("SELECT DiscountPct, Rating FROM #PrecisionDemo WHERE Description = %(desc)s", {"desc": "Summer sale"})
row = cursor.fetchone()
print(type(row.DiscountPct)) # <class 'decimal.Decimal'>
print(type(row.Rating)) # <class 'float'>
Podczas pobierania decimal/numeric kolumn sterownik zawsze zwraca decimal.Decimal obiekty. Podczas pobierania float/real kolumn sterownik zwraca Python . float
Warning
Nie porównuj float wartości równości. Zamiast tego użyj zakresu tolerancji: abs(a - b) < 0.0001.
Oprawę typu numpy
Sterownik mssql-python wykorzystuje isinstance() kontrole do określania typów SQL dla parametrów. Typy liczb całkowitych Numpy (numpy.int64, numpy.int32, ) numpy.int8nie przechodzą isinstance(x, int) w NumPy 2.x, co powoduje awarie wiązania. Działa to tylko numpy.float64 bezpośrednio, bo to podklasa Pythonfloat.
Przekonwertuj wartości numpy na natywne typy Python przed przekazaniem ich jako parametrów:
import numpy as np
row_id = np.int64(42)
score = np.float32(3.14)
# This fails: numpy.int64 is not recognized as int
# cursor.execute("SELECT * FROM Products WHERE ID = ?", (row_id,))
# Convert to native Python types first
cursor.execute(
"SELECT * FROM Production.Product WHERE ProductID = %(product_id)s",
{"product_id": int(row_id)}
)
# For DataFrames, convert the whole column
import pandas as pd
df = pd.DataFrame({"ProductID": [1, 2, 3], "Quantity": [10, 20, 30]})
cursor.execute("CREATE TABLE #Orders (ProductID INT, Quantity INT)")
for _, row in df.iterrows():
cursor.execute(
"INSERT INTO #Orders (ProductID, Quantity) VALUES (%(product_id)s, %(quantity)s)",
{"product_id": int(row["ProductID"]), "quantity": int(row["Quantity"])}
)
Jeśli intensywnie pracujesz z pandas lub numpy data, rozważ użycie ścieżek integracji z Arrow lub pandas , które obsługują konwersję typów wewnętrznie.