Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De mssql-python-driver koppelt automatisch Python-datatypes aan SQL Server-types bij het verzenden van parameters en zet SQL Server-types om naar Python-types bij het ophalen van resultaten.
Python naar SQL Server-mappings
Wanneer je Python-waarden als parameters aan execute() of executemany()doorgeeft, selecteert de driver automatisch het juiste type SQL Server. Voor de meeste toepassingen is de automatische mapping correct. Gebruik setinputsizes() (later beschreven in dit artikel) alleen wanneer je de standaard moet overschrijven, bijvoorbeeld om varchar te forceren in plaats van nvarchar of om parametermetadata voor string- en integer-invoer te regelen.
| type van Python | SQL Server-type | Aantekeningen |
|---|---|---|
None |
NULL |
SQL NULL-waarde. |
bool |
bit |
True→1, False→0. |
int |
tinyint, smallint, int, bigint | Grootte gekozen op basis van waardebereik. |
float |
float | 64-bits drijfkomma. |
decimal.Decimal |
Decimaal, numeriek | Behoud van precisie tot 38 cijfers. |
str |
Varchar, Nvarchar | Gebruikt nvarchar voor Unicode-content. |
bytes, bytearray |
varbinary | Binaire gegevens. |
datetime.date |
date | Alleen op date. |
datetime.time |
time | Alleen tijd. |
datetime.datetime |
datetime2 | Datum en tijd met nanosecondenprecisie. |
uuid.UUID |
uniqueidentifier | 16-byte GUID. |
Selectie van gehele getaltypes
De driver selecteert automatisch het kleinste gehele getal dat de waarde kan bevatten:
| Waardebereik | SQL Server-type |
|---|---|
| 0 tot 255 | tinyint |
| -32.768 tot 32.767 | smallint |
| -2.147.483.648 tot 2.147.483.647 | int |
| Grotere waarden | bigint |
Grote waardetypen
Voor strings en binaire gegevens die de standaardlimieten overschrijden, gebruikt de driver automatisch MAX-typen:
| Conditie | SQL Server-type |
|---|---|
| String > 8.000 bytes (varchar) | varchar(max) |
| String > 4.000 tekens (nvarchar) | nvarchar(max) |
| Binair > 8.000 bytes | varbinary(max) |
De driver streamt grote waarden naar de server om het geheugengebruik te minimaliseren.
SQL Server naar Python-mappingen
Wanneer de driver gegevens ophaalt van SQL Server, zet de driver waarden om naar Python-typen:
| SQL Server-type | type van Python | Aantekeningen |
|---|---|---|
| bit | bool |
Waar/onwaar. |
| tinyint, smallint, int, bigint | int |
Python integer (willekeurige precisie). |
| real | float |
32-bits drijvende komma. |
| float | float |
64-bits drijfkomma. |
| Decimaal, numeriek | decimal.Decimal |
Dat behoudt precisie. |
| geld, kleingeld | decimal.Decimal |
Vaste precisie (vier decimalen). |
| Char, Varchar, tekst | str |
Gedecodeerd als UTF-8. |
| nchar, nvarchar, ntext | str |
Gedecodeerd als UTF-16LE. |
| binair, varbinary, afbeelding | bytes |
Rauw binair. |
| date | datetime.date |
Alleen op date. |
| time | datetime.time |
Tijd met microsecondenprecisie. |
| Datetime, smalldatetime | datetime.datetime |
Legacy datumtijdtypes. |
| datetime2 | datetime.datetime |
Hoge precisie op date-tijd. |
| datetimeoffset | datetime.datetime |
Tijdzonebewuste datetime. |
| uniqueidentifier | uuid.UUID |
Python UUID-objecten. |
| xml | str |
XML als tekst. |
| Geografie, meetkunde | bytes |
Ruimtelijke types als binair. |
| hierarchyid | bytes |
Hiërarchiegegevens als binair. |
| sql_variant | Varies | Opgelost op het onderliggende basistype.
sql_variant Kolommen gebruiken een streaming fetch-pad, wat een lichte prestatie-impact kan hebben vergeleken met vaste type kolommen. |
NULL |
None |
Python Geen. |
SQL-typeconstanten
De driver exporteert constanten die overeenkomen met ODBC SQL-type-identificaties. Je gebruikt deze constanten setinputsizes() meestal om de standaard type-inferentie van de bestuurder te overschrijven wanneer de automatische mapping niet overeenkomt met jouw schema.
Tekentypen
| Constant | Waarde | Beschrijving |
|---|---|---|
SQL_CHAR |
1 | ANSI-personage met vaste lengte. |
SQL_VARCHAR |
12 | ANSI-karakter van variabele lengte. |
SQL_LONGVARCHAR |
-1 | Lange variabele lengte ANSI. |
SQL_WCHAR |
-8 | Unicode met vaste lengte. |
SQL_WVARCHAR |
-9 | Unicode van variabele lengte. |
SQL_WLONGVARCHAR |
-10 | Lange variabele lengte Unicode. |
Numerieke typen
| Constant | Waarde | Beschrijving |
|---|---|---|
SQL_BIT |
-7 | Bit/booleaan. |
SQL_TINYINT |
-6 | 8-bits geheel getal zonder teken. |
SQL_SMALLINT |
5 | 16-bits ondertekend geheel getal. |
SQL_INTEGER |
4 | 32-bits ondertekend geheel getal. |
SQL_BIGINT |
-5 | 64-bits getekend geheel getal. |
SQL_REAL |
7 | 32-bits drijvende komma. |
SQL_FLOAT |
6 | 64-bits drijfkomma. |
SQL_DOUBLE |
8 | 64-bits drijfkomma. |
SQL_DECIMAL |
3 | Vaste precisie decimaal. |
SQL_NUMERIC |
2 | Vaste precisie numeriek. |
Datum- en tijdtypen
| Constant | Waarde | Beschrijving |
|---|---|---|
SQL_TYPE_DATE |
91 | Alleen op date. |
SQL_TYPE_TIME |
92 | Alleen tijd. |
SQL_TYPE_TIMESTAMP |
93 | Datum en tijd. |
SQL_SS_TIME2 |
-154 | SQL Server time(n). |
SQL_DATETIMEOFFSET |
-155 | SQL Server datetimeoffset. |
Opmerking
SQL_SS_TIME2 en SQL_DATETIMEOFFSET zijn interne constanten die niet als module-niveau attributen worden geëxporteerd. Gebruik direct de gehele getalwaarden (-154, -155) bij het aanroepen add_output_converter()van .
Binaire typen
| Constant | Waarde | Beschrijving |
|---|---|---|
SQL_BINARY |
-2 | Binaire variabele lengte met vaste lengte. |
SQL_VARBINARY |
-3 | Variabele lengte binaire functie. |
SQL_LONGVARBINARY |
-4 | Lange variabele lengte binaire artiesten. |
Andere typen
| Constant | Waarde | Beschrijving |
|---|---|---|
SQL_GUID |
-11 | Uniqueidentifier. |
SQL_XML |
-152 | XML-gegevens. |
SQL_SS_UDT |
-151 | Door de gebruiker gedefinieerd type (ruimtelijk). |
SQL_SS_VARIANT |
-150 | sql_variant data. |
Opmerking
SQL_SS_UDT en SQL_SS_VARIANT zijn interne constanten die niet als module-niveau attributen worden geëxporteerd. Gebruik direct de gehele getalwaarden (-151, -150) bij het aanroepen add_output_converter()van .
Gebruik setinputsizes()
Roep setinputsizes() eerder executemany() aan om expliciet parametertypes te declareren wanneer de automatische typeinferentie van de bestuurder onverwacht gedrag veroorzaakt, bijvoorbeeld wanneer een kolom is varchar(100) maar de driver stuurt nvarchar:
Opmerking
Voor decimale waarden kun je vertrouwen op de automatische typeinferentie van de bestuurder in plaats van SQL_DECIMAL op of SQL_NUMERIC. Die expliciete decimale typeconstanten hebben momenteel een bekend probleem met setinputsizes(). Voor meer informatie, zie Uitvoeren van zoekopdrachten.
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),
]
)
Decimaalteken
De bestuurder gebruikt locale-bewuste decimale scheidingstekens. Om aan te passen:
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(",")
Aangepaste type omzetters
Registreer aangepaste converters voor specifieke 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)
Voor meer informatie, zie Custom type converters.
Hanteer speciale types
UUID-behandeling
De driver wordt automatisch toegewezen uuid.UUIDuniqueidentifier . Je kunt UUID's invoegen en ophalen zonder handmatige stringconversie:
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})
Standaard levert de driver kolommen als UNIQUEIDENTIFIER objecten teruguuid.UUID. Om pyodbc-compatibele hoofdletterstrings terug te geven, zet native_uuid=Falseje :
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()
Voor module-niveau configuratie, zie de native_uuid instelling in Moduleconfiguratie.
Datumtijd met tijdzone
datetimeoffset kolommen geven objecten terug die zich bewust datetime zijn van de tijdzone. Voor richtlijnen over het werken met offset-aware versus offset-naïeve waarden, zie Datetime handling.
cursor.execute("SELECT SYSDATETIMEOFFSET()")
row = cursor.fetchone()
dt = row[0]
print(f"DateTime: {dt}")
print(f"Timezone: {dt.tzinfo}")
Ruimtelijke gegevens
De driver geeft ruimtelijke types (geography, geometry) terug als bytes. Je kunt parameterstrings gebruiken in WKT-formaat:
# 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]
Rijversie/Tijdstempel
SQL Server's rowversion (voorheen timestamp) is een binair type, geen datumtijd:
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-typen met grote waarde
Bij het invoegen of ophalen varchar(max)van , nvarchar(max), of varbinary(max) data, gebruikt de driver Data-at-Execution (DAE) streaming om data in stukken te verzenden in plaats van de volledige waarde in één keer in het geheugen te laden.
Streaming wordt automatisch geactiveerd wanneer de invoerdata de groottedrempels overschrijdt:
| Gegevenstype | Streamingdrempel |
|---|---|
| varchar(max) | > 8.000 bytes |
| nvarchar(max) | > 4.000 tekens |
| varbinary(max) | > 8.000 bytes |
Streaming werkt met execute(), executemany(), en alle fetch API's (fetchone(), fetchmany(), fetchall()). De driver vereist geen speciale configuratie en verwerkt streaming automatisch voor grote waarden.
Niet-ondersteunde SQL Server-typen
De volgende SQL Server-types hebben geen native Python-type mappings.
| SQL Server-type | Status |
|---|---|
| json | Niet ondersteund |
| vector | Niet ondersteund |
| table | Niet ondersteund (tabelwaardige parameters) |
Tip
Hoewel het json type SQL Server niet direct wordt ondersteund, kun je JSON-gegevens in nvarchar(max) kolommen opslaan en deze opvragen met SQL Server JSON-functies (JSON_VALUE, JSON_QUERY, OPENJSON). Voor patronen en voorbeelden, zie JSON-gegevens.
De volgende types geven data terug alsbytes, maar hebben geen native Python-type mappings:
| SQL Server-type | type van Python | Aantekeningen |
|---|---|---|
| geography | bytes |
Gebruik .STAsBinary() voor WKB-formaat. |
| geometry | bytes |
Gebruik .STAsBinary() voor WKB-formaat. |
| hierarchyid | bytes |
Binaire representatie. |
| sql_variant | Varies | Opgelost op het onderliggende basistype. |
Decimale versus floatprecisie
Gebruik decimal.Decimal wanneer exacte precisie belangrijk is, zoals financiële berekeningen, valuta of elke waarde waarbij afrondingsfouten onacceptabel zijn. Gebruik float wanneer benaderende waarden acceptabel zijn, zoals wetenschappelijke metingen of sensormetingen.
De driver is gekoppeld decimal.Decimal aan SQL Server decimal/numeric en behoudt precisie tot 38 cijfers.
floatafbeeldingen naar SQL Server float (64-bit IEEE 754), wat afrondingsartefacten kan introduceren:
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'>
Bij het decimal/numeric ophalen van kolommen geeft de driver altijd objecten terug.decimal.Decimal Bij het float/real ophalen van kolommen geeft de driver Python . float
Warning
Vergelijk float geen waarden voor gelijkheid. Gebruik in plaats daarvan een tolerantiebereik: abs(a - b) < 0.0001.
Numpy-type binding
De mssql-python driver gebruikt isinstance() controles om SQL-types voor parameters te bepalen. Numpy integertypes (numpy.int64, , ) numpy.int32worden niet doorgegeven numpy.int8 in NumPy 2.x, wat leidt tot isinstance(x, int)binding failures. Werkt alleen numpy.float64 direct omdat het een subklasse van Python floatis.
Converteer numpy-waarden naar native Python-types voordat je ze als parameters doorgeeft:
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"])}
)
Als je veel werkt met pandas of numpy-data, overweeg dan de Arrow-integratie - of pandas-integratiepaden te gebruiken, die de typeconversie intern regelen.