Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der mssql-python-Treiber bildet beim Senden von Parametern automatisch Python-Datentypen auf SQL Server-Typen ab und wandelt SQL Server-Typen in Python-Typen um, wenn Ergebnisse abgerufen werden.
Python-zu-SQL Server-Zuordnungen
Wenn du Python-Werte als Parameter an execute() oder executemany()gibst, wählt der Treiber automatisch den entsprechenden SQL Server-Typ. Für die meisten Anwendungen ist die automatische Zuordnung korrekt. Verwenden setinputsizes() Sie (später in diesem Artikel beschrieben) nur, wenn Sie den Standard überschreiben müssen, zum Beispiel um varchar statt nvarchar zu erzwingen oder um Parametermetadaten für String- und Ganzzahleingaben zu steuern.
| Python-Typ | SQL Server-Typ | Hinweise |
|---|---|---|
None |
NULL |
SQL NULL-Wert. |
bool |
bit |
True→1, False→0. |
int |
winzig, klein,int, bigint | Größe wird basierend auf dem Wertbereich ausgewählt. |
float |
float | 64-Bit-Gleitkomma. |
decimal.Decimal |
Dezimal, numerisch | Bewahrt eine Präzision bis zu 38 Ziffern. |
str |
Varchar, Nvarchar | Verwendet nvarchar für Unicode-Inhalte. |
bytes, bytearray |
varbinary | Binäre Daten. |
datetime.date |
date | Nur Datum. |
datetime.time |
Zeit | Nur Zeit. |
datetime.datetime |
datetime2 | Datum und Uhrzeit mit Nanosekundenpräzision. |
uuid.UUID |
uniqueidentifier | 16-Byte GUID. |
Ganzzahlige Typauswahl
Der Treiber wählt automatisch den kleinsten ganzzahligen Typ, der den Wert halten kann:
| Wertbereich | SQL Server-Typ |
|---|---|
| 0 bis 255 | tinyint |
| –32.768 bis 32.767 | smallint |
| -2,147,483,648 bis 2,147,483,647 | int |
| Höhere Werte | bigint |
Große Wert-Typen
Für Strings und Binärdaten, die Standardlimits überschreiten, verwendet der Treiber automatisch MAX-Typen:
| Zustand | SQL Server-Typ |
|---|---|
| String > 8.000 Bytes (varchar) | varchar(max) |
| String > 4.000 Zeichen (nvarchar) | nvarchar(max) |
| Binär: 8.000 Bytes > | varbinary(max) |
Der Treiber streamt große Werte an den Server, um den Speicherverbrauch zu minimieren.
SQL Server-zu-Python-Mappings
Wenn der Treiber Daten aus dem SQL Server abruft, wandelt er Werte in Python-Typen um:
| SQL Server-Typ | Python-Typ | Hinweise |
|---|---|---|
| bit | bool |
Wahr/Falsch. |
| winzig, klein,int, bigint | int |
Python Ganzzahl (beliebige Genauigkeit). |
| real | float |
32-Bit-Gleitkomma. |
| float | float |
64-Bit-Gleitkomma. |
| Dezimal, numerisch | decimal.Decimal |
Bewahrt die Präzision. |
| Geld, Kleingeld | decimal.Decimal |
Feste Genauigkeit (vier Dezimalstellen). |
| Char, Varchar, Text | str |
Entschlüsselt als UTF-8. |
| nchar, nvarchar, ntext | str |
Entschlüsselt als UTF-16LE. |
| Binär,Varbinär, Bild | bytes |
Rohe Binär. |
| date | datetime.date |
Nur Datum. |
| Zeit | datetime.time |
Zeit mit Mikrosekundenpräzision. |
| Datetime, SmallDatetime | datetime.datetime |
Legacy-Datetime-Typen. |
| datetime2 | datetime.datetime |
Hochpräzise Datumszeit. |
| datetimeoffset | datetime.datetime |
Zeitzonenbewusste Datezeit. |
| uniqueidentifier | uuid.UUID |
Python UUID-Objekte. |
| xml | str |
XML als Text. |
| Geografie, Geometrie | bytes |
Räumliche Typen als binär. |
| hierarchyid | bytes |
Hierarchiedaten als Binär. |
| sql_variant | Variiert | Auf den zugrundeliegenden Basistyp aufgelöst.
sql_variant Spalten verwenden einen Streaming-Fetch-Pfad, der im Vergleich zu Spalten mit festem Typ einen leichten Leistungseinfluss haben kann. |
NULL |
None |
Python Keine. |
SQL-Typkonstanten
Der Treiber exportiert Konstanten, die den ODBC SQL-Typ-Identifikatoren entsprechen. Du verwendest diese Konstanten typischerweise mit setinputsizes() , um die Standardtyp-Inferenz des Fahrers zu überschreiben, wenn die automatische Zuordnung nicht mit deinem Schema übereinstimmt.
Zeichentypen
| Dauerhaft | Wert | Beschreibung |
|---|---|---|
SQL_CHAR |
1 | ANSI-Zeichen mit fester Länge. |
SQL_VARCHAR |
12 | ANSI-Zeichen variabler Länge. |
SQL_LONGVARCHAR |
-1 | Lange, variable ANSI (ANSI). |
SQL_WCHAR |
-8 | Unicode mit fester Länge. |
SQL_WVARCHAR |
-9 | Unicode mit variabler Länge. |
SQL_WLONGVARCHAR |
-10 | Langer, variabler Länge Unicode. |
Numerische Typen
| Dauerhaft | Wert | Beschreibung |
|---|---|---|
SQL_BIT |
-7 | Bit/boolean. |
SQL_TINYINT |
-6 | 8-Bit-Ganzzahl ohne Vorzeichen. |
SQL_SMALLINT |
5 | 16-Bit-Ganzzahl mit Vorzeichen. |
SQL_INTEGER |
4 | 32-Bit-Ganzzahl mit Vorzeichen. |
SQL_BIGINT |
-5 | 64-Bit-signierte Ganzzahl. |
SQL_REAL |
7 | 32-Bit-Gleitkomma. |
SQL_FLOAT |
6 | 64-Bit-Gleitkomma. |
SQL_DOUBLE |
8 | 64-Bit-Gleitkomma. |
SQL_DECIMAL |
3 | Feste Dezimalgenauigkeit. |
SQL_NUMERIC |
2 | Zahlengenauigkeit mit fester Genauigkeit. |
Datums- und Uhrzeittypen
| Dauerhaft | Wert | Beschreibung |
|---|---|---|
SQL_TYPE_DATE |
91 | Nur Datum. |
SQL_TYPE_TIME |
92 | Nur Zeit. |
SQL_TYPE_TIMESTAMP |
93 | Datum und Uhrzeit. |
SQL_SS_TIME2 |
-154 | SQL Server time(n). |
SQL_DATETIMEOFFSET |
–155 | SQL Server datetimeoffset. |
Note
SQL_SS_TIME2 und SQL_DATETIMEOFFSET sind interne Konstanten, die nicht als modulbezogene Attribute exportiert werden. Verwenden Sie direkt die ganzzahligen Werte (-154, -155), wenn Sie aufgerufen add_output_converter()werden.
Binäre Typen
| Dauerhaft | Wert | Beschreibung |
|---|---|---|
SQL_BINARY |
-2 | Binäre Länge mit fester Länge. |
SQL_VARBINARY |
-3 | Binärfunktion mit variabler Länge. |
SQL_LONGVARBINARY |
–4 | Lange, variable Binärlänge. |
Andere Typen
| Dauerhaft | Wert | Beschreibung |
|---|---|---|
SQL_GUID |
-11 | Einzigartiger Identifikator. |
SQL_XML |
–152 | XML-Daten. |
SQL_SS_UDT |
–151 | Benutzerdefinierter Typ (räumlich). |
SQL_SS_VARIANT |
-150 | sql_variant Daten. |
Note
SQL_SS_UDT und SQL_SS_VARIANT sind interne Konstanten, die nicht als modulbezogene Attribute exportiert werden. Verwenden Sie direkt die ganzzahligen Werte (-151, -150), wenn Sie aufgerufen add_output_converter()werden.
Verwenden Sie setinputsizes()
Ruf vorher auf setinputsizes() , executemany() um explizit Parametertypen zu deklarieren, wenn die automatische Typinferenz des Fahrers unerwartetes Verhalten verursacht, zum Beispiel wenn eine Spalte ist varchar(100) , aber der Treiber sendet nvarchar:
Note
Für Dezimalwerte verlassen Sie sich auf die automatische Typinferenz des Fahrers statt SQL_DECIMAL auf oder SQL_NUMERIC. Diese expliziten Dezimaltypkonstanten haben derzeit ein bekanntes Problem mit setinputsizes(). Weitere Informationen finden Sie unter Abfragen ausführen.
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),
]
)
Dezimaltrennzeichen
Der Fahrer verwendet lokalisierte Dezimaltrenner. Zum Anpassen:
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(",")
Individuelle Wandler
Registrieren Sie benutzerdefinierte Konverter für bestimmte SQL-Typen:
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)
Weitere Informationen finden Sie unter Custom type Converters.
Handle spezielle Typen
UUID-Handhabung
Der Treiber wird automatisch zugeordnet uuid.UUIDuniqueidentifier . Du kannst UUIDs ohne manuelle String-Umwandlung einfügen und abrufen:
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})
Standardmäßig gibt der Treiber Spalten als UNIQUEIDENTIFIER Objekte zurückuuid.UUID. Um stattdessen pyodbc-kompatible Großbuchstaben-Zeichenketten zurückzugeben, setze 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()
Für die Konfiguration auf Modulebene siehe die native_uuidEinstellung in Modulkonfiguration.
Datumszeit mit Zeitzone
datetimeoffset Spalten geben zeitzonenbewusste datetime Objekte zurück. Für Hinweise zum Umgang mit offset-bewussten versus offset-naiven Werten siehe Datetime-Handling.
cursor.execute("SELECT SYSDATETIMEOFFSET()")
row = cursor.fetchone()
dt = row[0]
print(f"DateTime: {dt}")
print(f"Timezone: {dt.tzinfo}")
Räumliche Daten
Der Treiber gibt räumliche Typen (geography, geometry) als zurück bytes. Sie können Parameterstrings im WKT-Format verwenden:
# 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]
Reihenversion/Zeitstempel
SQL Server rowversion (früher timestamp) ist ein binärer Typ, kein Datetime:
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
Stream-Großwerttypen
Beim Einfügen oder Abrufen varchar(max)von , nvarchar(max), oder varbinary(max) Daten, verwendet der Treiber Data-at-Execution (DAE)-Streaming, um Daten in Chunks zu übertragen, anstatt den gesamten Wert auf einmal in den Speicher zu laden.
Das Streaming wird automatisch aktiviert, wenn die Eingabedaten die Größenschwellenwerte überschreiten:
| Datentyp | Streaming-Schwelle |
|---|---|
| varchar(max) | > 8.000 Bytes |
| nvarchar(max) | > 4.000 Zeichen |
| varbinary(max) | > 8.000 Bytes |
Streaming funktioniert mit execute(), executemany(), und allen Fetch-APIs (fetchone(), fetchmany(), fetchall()). Der Treiber benötigt keine spezielle Konfiguration und übernimmt das Streaming automatisch für große Werte.
Nicht unterstützte SQL Server-Typen
Die folgenden SQL Server-Typen haben keine nativen Python-Typzuordnungen.
| SQL Server-Typ | Status |
|---|---|
| json | Nicht unterstützt |
| vector | Nicht unterstützt |
| Tabelle | Nicht unterstützt (tabellenwertige Parameter) |
Tip
Obwohl der json SQL Server-Typ nicht direkt unterstützt wird, kann man JSON-Daten in nvarchar(max) Spalten speichern und sie mit SQL Server-JSON-Funktionen abfragen (JSON_VALUE, JSON_QUERY, OPENJSON). Für Muster und Beispiele siehe JSON-Daten.
Die folgenden Typen geben Daten zurückbytes, haben aber keine nativen Python-Typ-Mappings:
| SQL Server-Typ | Python-Typ | Hinweise |
|---|---|---|
| geography | bytes |
Verwendung .STAsBinary() für das WKB-Format. |
| geometry | bytes |
Verwendung .STAsBinary() für das WKB-Format. |
| hierarchyid | bytes |
Binäre Repräsentation. |
| sql_variant | Variiert | Auf den zugrundeliegenden Basistyp aufgelöst. |
Dezimal- versus Schwimmergenauigkeit
Verwenden decimal.Decimal Sie, wenn genaue Genauigkeit wichtig ist, wie bei finanziellen Berechnungen, Währung oder jedem Wert, bei dem Rundungsfehler nicht akzeptabel sind. Verwenden float Sie, wenn ungefähre Werte akzeptabel sind, wie wissenschaftliche Messungen oder Sensormessungen.
Der Treiber wird auf SQL Server decimal.Decimaldecimal/ abgebildet numeric und erhält eine Genauigkeit von bis zu 38 Ziffern.
floatwird auf den SQL Server float (64-Bit-IEEE 754) abgebildet, der Rundungsartefakte einführen kann:
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'>
Beim Abrufen decimal/numericvon Spalten gibt der Treiber immer Objekte zurück.decimal.Decimal Beim Abrufen float/realvon Spalten gibt der Treiber Python floatzurück.
Warning
Vergleiche float keine Werte für Gleichheit. Verwenden Sie stattdessen einen Toleranzbereich: abs(a - b) < 0.0001.
Numpy-Typbindung
Der Treiber mssql-python verwendet isinstance() Prüfungen, um SQL-Typen für Parameter zu bestimmen. Numpy-Ganzzahltypen (numpy.int64, numpy.int32, numpy.int8) passieren isinstance(x, int) in NumPy 2.x nicht, was zu Bindungsfehlern führt. Funktioniert nur numpy.float64 direkt, weil es eine Unterklasse von Python floatist.
Konvertiere Numpy-Werte in native Python-Typen, bevor du sie als Parameter übergibst:
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"])}
)
Wenn du stark mit Pandas oder Numpy-Daten arbeitest, solltest du die Arrow-Integration oder pandas-Integrationspfade nutzen, die intern die Typkonvertierung übernehmen.