Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
mssql-python-drivrutinen mappar automatiskt Python-datatyper till SQL Server-typer när parametrar skickas och konverterar SQL Server-typer till Python-typer vid resultatinsamling.
Python till SQL Server-mappningar
När du skickar Python-värden som parametrar till execute() eller executemany(), väljer drivrutinen automatiskt rätt SQL Server-typ. För de flesta tillämpningar är den automatiska mappningen korrekt. Använd setinputsizes() (beskrivs senare i denna artikel) endast när du behöver åsidosätta standarden, till exempel för att tvinga varchar istället för nvarchar eller för att kontrollera parametermetadata för sträng- och heltalsindata.
| Python-typ | SQL Server-typ | Noteringar |
|---|---|---|
None |
NULL |
SQL NULL-värde. |
bool |
bit |
True→1, False→0. |
int |
tinyint, littleint, int, bigint | Storlek vald baserat på värdeintervall. |
float |
float | 64-bitars flyttal. |
decimal.Decimal |
decimal, numerisk | Bevarar precision upp till 38 siffror. |
str |
Varchar, Nvarchar | Använder nvarchar för Unicode-innehåll. |
bytes, bytearray |
varbinary | Binära data. |
datetime.date |
date | Endast dejt. |
datetime.time |
time | Endast tid. |
datetime.datetime |
datetime2 | Datum och tid med nanosekundprecision. |
uuid.UUID |
uniqueidentifier | 16-bytes GUID. |
Heltalstypval
Drivrutinen väljer automatiskt den minsta heltalstypen som kan hålla värdet:
| Värdeintervall | SQL Server-typ |
|---|---|
| 0 till 255 | tinyint |
| -32 768 till 32 767 | smallint |
| -2 147 483 648 till 2 147 483 647 | int |
| Större värden | bigint |
Stora värdetyper
För strängar och binär data som överskrider standardgränser använder drivrutinen automatiskt MAX-typer:
| Tillstånd | SQL Server-typ |
|---|---|
| Sträng > 8 000 byte (varchar) | varchar(max) |
| Sträng > 4 000 tecken (nvarchar) | nvarchar(max) |
| Binär > 8 000 byte | varbinary(max) |
Drivrutinen strömmar stora värden till servern för att minimera minnesanvändningen.
SQL Server till Python-mappningar
När drivrutinen hämtar data från SQL Server konverterar drivrutinen värden till Python-typer:
| SQL Server-typ | Python-typ | Noteringar |
|---|---|---|
| bit | bool |
Sant/falskt. |
| tinyint, littleint, int, bigint | int |
Python heltal (godtycklig precision). |
| real | float |
32-bitars flyttal. |
| float | float |
64-bitars flyttal. |
| decimal, numerisk | decimal.Decimal |
Bevarar precisionen. |
| pengar, småpengar | decimal.Decimal |
Fast precision (fyra decimaler). |
| Char, Varchar, text | str |
Avkodad som UTF-8. |
| Nchar, Nvarchar, ntext | str |
Avkodad som UTF-16LE. |
| binär, varbinär, bild | bytes |
Rå binär. |
| date | datetime.date |
Endast dejt. |
| time | datetime.time |
Tid med mikrosekundprecision. |
| Datumtid, smådatetid | datetime.datetime |
Legacy-datum-tid-typer. |
| datetime2 | datetime.datetime |
Hög precision på datetime. |
| datetimeoffset | datetime.datetime |
Tidszonsmedveten datetime. |
| uniqueidentifier | uuid.UUID |
Python UUID-objekt. |
| xml | str |
XML som text. |
| json | str |
JSON-dokumentet som text. |
| vector | str |
Vektor som en JSON-arraysträng. |
| Geografi, geometri | bytes |
Rumsliga typer som binära. |
| hierarchyid | bytes |
Hierarkidata som binär. |
| sql_variant | Varierar | Löst till den underliggande bastypen.
sql_variant Kolumner använder en strömmande hämtaväg, vilket kan ha en liten prestandapåverkan jämfört med kolumner av fast typ. |
NULL |
None |
Python Ingen. |
SQL-typkonstanter
Drivrutinen exporterar konstanter som motsvarar ODBC SQL-typidentifierare. Du brukar använda dessa konstanter för setinputsizes() att åsidosätta förarens standardtypinferens när den automatiska mappningen inte matchar ditt schema.
Teckentyper
| Konstant | Värde | Beskrivning |
|---|---|---|
SQL_CHAR |
1 | ANSI-tecken med fast längd. |
SQL_VARCHAR |
12 | ANSI-tecken med variabel längd. |
SQL_LONGVARCHAR |
-1 | Lång variabel längd ANSI. |
SQL_WCHAR |
-8 | Unicode med fast längd. |
SQL_WVARCHAR |
-9 | Unicode med variabel längd. |
SQL_WLONGVARCHAR |
-10 | Lång variabel längd Unicode. |
Numeriska typer
| Konstant | Värde | Beskrivning |
|---|---|---|
SQL_BIT |
-7 | Bit/booleskt. |
SQL_TINYINT |
-6 | 8-bitars osignerat heltal. |
SQL_SMALLINT |
5 | 16-bitars signerat heltal. |
SQL_INTEGER |
4 | 32-bitars signerat heltal. |
SQL_BIGINT |
-5 | 64-bitars signerat heltal. |
SQL_REAL |
7 | 32-bitars flyttal. |
SQL_FLOAT |
6 | 64-bitars flyttal. |
SQL_DOUBLE |
8 | 64-bitars flyttal. |
SQL_DECIMAL |
3 | Fast decimalprecision. |
SQL_NUMERIC |
2 | Numerisk med fast precision. |
Datum- och tidstyper
| Konstant | Värde | Beskrivning |
|---|---|---|
SQL_TYPE_DATE |
91 | Endast dejt. |
SQL_TYPE_TIME |
92 | Endast tid. |
SQL_TYPE_TIMESTAMP |
93 | Datum och tid. |
SQL_SS_TIME2 |
-154 | SQL Server time(n). |
SQL_DATETIMEOFFSET |
-155 | SQL Server datetimeoffset. |
Note
SQL_SS_TIME2 och SQL_DATETIMEOFFSET är interna konstanter som inte exporteras som modulnivåattribut. Använd heltalsvärdena (-154, -155) direkt när du anropar add_output_converter().
Binära typer
| Konstant | Värde | Beskrivning |
|---|---|---|
SQL_BINARY |
-2 | Binära med fast längd. |
SQL_VARBINARY |
-3 | Variabellängds binär. |
SQL_LONGVARBINARY |
-4 | Långvarigad binär. |
Andra typer
| Konstant | Värde | Beskrivning |
|---|---|---|
SQL_GUID |
-11 | Unikidentifierare. |
SQL_XML |
-152 | XML-data. |
SQL_SS_UDT |
-151 | Användardefinierad typ (rumslig). |
SQL_SS_VARIANT |
-150 | sql_variant data. |
Note
SQL_SS_UDT och SQL_SS_VARIANT är interna konstanter som inte exporteras som modulnivåattribut. Använd heltalsvärdena (-151, -150) direkt när du anropar add_output_converter().
Använd setinputsizes()
Anropa setinputsizes() före executemany() för att uttryckligen deklarera parametertyper när förarens automatiska typinferens orsakar oväntat beteende, till exempel när en kolumn är varchar(100) men föraren skickar nvarchar:
Note
För decimalvärden, förlita dig på förarens automatiska typinferens snarare än SQL_DECIMAL eller SQL_NUMERIC. Dessa explicita decimaltypkonstanter har för närvarande ett känt problem med setinputsizes(). För mer information, se Utför frågor.
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),
]
)
Decimaltecken
Föraren använder lokalmedvetna decimalseparatorer. Så här anpassar du:
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(",")
Specialtypomvandlare
Registrera anpassade konverterare för specifika SQL-typer:
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)
För mer information, se Anpassade typomvandlare.
Hantera specialtyper
UUID-hantering
Drivrutinen mappas uuid.UUID automatiskt till uniqueidentifier det. Du kan sätta in och hämta UUID:er utan manuell strängkonvertering:
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})
Som standard returnerar UNIQUEIDENTIFIER drivrutinen kolumner som uuid.UUID objekt. För att returnera pyodbc-kompatibla versalisatorsträngar istället, sätt 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 modulnivåkonfiguration, se inställningen native_uuid i Modulkonfiguration.
Datumtid med tidszon
datetimeoffset kolumner returnerar objekt som är tidszonsmedvetna datetime . För vägledning om hur man arbetar med offset-medvetna kontra offset-naive värden, se Datetime-hantering.
cursor.execute("SELECT SYSDATETIMEOFFSET()")
row = cursor.fetchone()
dt = row[0]
print(f"DateTime: {dt}")
print(f"Timezone: {dt.tzinfo}")
Geodata
Drivern returnerar rumsliga typer (geography, geometry) som bytes. Du kan använda parametersträngar i WKT-format:
# 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]
Radversion/tidsstämpel
SQL Server rowversion (tidigare timestamp) är en binär typ, inte en 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
Strömtyper med stort värde
När man infogar eller hämtar varchar(max), nvarchar(max), eller varbinary(max) data, använder drivrutinen Data-at-Execution (DAE) strömning för att överföra data i delar istället för att ladda hela värdet i minnet på en gång.
Streaming aktiveras automatiskt när indatan överskrider storlekströskeln:
| Datatyp | Strömningströskel |
|---|---|
| varchar(max) | > 8 000 byte |
| nvarchar(max) | > 4 000 tecken |
| varbinary(max) | > 8 000 byte |
Streaming fungerar med execute(), executemany(), och alla hämta-API:er (fetchone(), fetchmany(), fetchall()). Drivrutinen kräver ingen speciell konfiguration och hanterar streaming automatiskt för stora värden.
Icke-stödda SQL Server-typer
Följande SQL Server-typer har inte inbyggda Python-typer.
| SQL Server-typ | Status |
|---|---|
| table | Ej stödd (tabellvärda parametrar) |
Tip
Drivern returnerar json och vector värderar som str. På servrar utan den inbyggda json typen, lagra JSON-data i nvarchar(max) kolumner och fråga den med SQL Server JSON-funktioner (JSON_VALUE, JSON_QUERY, OPENJSON). För mönster och exempel, se JSON-data.
Följande typer returnerar data som bytes men har inte inbyggda Python-typer:
| SQL Server-typ | Python-typ | Noteringar |
|---|---|---|
| geography | bytes |
Användning .STAsBinary() för WKB-format. |
| geometry | bytes |
Användning .STAsBinary() för WKB-format. |
| hierarchyid | bytes |
Binära representation. |
| sql_variant | Varierar | Löst till den underliggande bastypen. |
Decimal kontra flottörprecision.
Använd decimal.Decimal när exakt precision är viktig, såsom finansiella beräkningar, valuta eller andra värden där avrundningsfel är oacceptabla. Använd float när ungefärliga värden är acceptabla, såsom vetenskapliga mätningar eller sensoravläsningar.
Drivrutinen mappas decimal.Decimal till SQL Server decimal/numeric och bevarar precision upp till 38 siffror.
floatmappar till SQL Server float (64-bitars IEEE 754), vilket kan introducera avrundningsartefakter:
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'>
När man hämtar kolumner decimal/numeric returnerar decimal.Decimal drivrutinen alltid objekt. När kolumner hämtas float/real returnerar drivrutinen Python. float
Varning
Jämför float inte värden för jämlikhet. Använd istället ett toleransintervall: abs(a - b) < 0.0001.
Numpy-typbindning
Drivrutinen mssql-python använder isinstance() kontroller för att bestämma SQL-typer för parametrar. Numpy-heltalstyper (numpy.int64, numpy.int32, numpy.int8) passerar isinstance(x, int) inte i NumPy 2.x, vilket orsakar bindningsfel. Fungerar bara numpy.float64 direkt eftersom det är en underklass av Pythonfloat.
Konvertera numpy-värden till inbyggda Python-typer innan du skickar dem som parametrar:
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"])}
)
Om du arbetar mycket med pandas eller numpy-data, överväg att använda Arrow-integrationen eller pandas-integrationsvägarna , som hanterar typkonvertering internt.