mssql-python için veri tipi eşlemeleri

mssql-python sürücüsü, parametreler gönderirken Python veri tiplerini otomatik olarak SQL Server tiplerine eşler ve sonuçları alırken SQL Server tiplerini Python tiplerine dönüştürür.

Python'dan SQL Server'a eşlemeler

Python değerlerini parametre olarak veya execute()executemany(), ile aktardığınızda, sürücü otomatik olarak uygun SQL Server tipini seçer. Çoğu uygulama için otomatik eşleme doğrudur. setinputsizes() (Bu makalenin ilerleyen bölümlerinde açıklanan) sadece varsayılan değişkeni geçersiz kılmanız gerektiğinde kullanın, örneğin nvarchar yerine varchar'ı zorlamak veya dizi ve tamsayı girişleri için parametre meta verilerini kontrol etmek için.

Python türü SQL Server türü Notlar
None NULL SQL NULL değeri.
bool bit True→1, False→0.
int tinyint, smallint, int, bigint Boyut değer aralığına göre seçilir.
float float 64-bit kayan nokta.
decimal.Decimal ondalık, sayısal 38 haneli hassasiyeti korur.
str Varchar, Nvarchar Unicode içeriği için nvarchar kullanıyor.
bytes, bytearray varbinary İkili veri.
datetime.date date Sadece randevu için.
datetime.time time Sadece zaman.
datetime.datetime datetime2 Tarih ve saat, nanosaniye hassasiyetle gösterildi.
uuid.UUID uniqueidentifier 16 baytlık GUID.

Tamsayı tip seçimi

Sürücü, bu değeri tutabilecek en küçük tam sayı türünü otomatik olarak seçer:

Değer aralığı SQL Server türü
0 - 255 tinyint
-32.768 - 32.767 smallint
-2.147.483.648 ile 2.147.483.647 int
Daha büyük değerler bigint

Büyük değer türleri

Standart sınırları aşan dizeler ve ikili veriler için sürücü otomatik olarak MAX türlerini kullanır:

Koşul SQL Server türü
Diziye > 8.000 bayt (varchar) varchar(max)
4.000 karakter ( > nvarchar) nvarchar(max)
İkili > 8.000 bayt varbinary(max)

Sürücü, bellek kullanımını en aza indirmek için sunucuya büyük değerler gönderir.

SQL Server'dan Python'a eşlemeler

Sürücü SQL Server'dan veri aldığında, sürücü değerleri Python tiplerine dönüştürür:

SQL Server türü Python türü Notlar
bit bool Doğru/Yanlış.
tinyint, smallint, int, bigint int Python tam sayı (keyfi hassasiyet).
real float 32 bit kayan nokta.
float float 64-bit kayan nokta.
ondalık, sayısal decimal.Decimal Hassasiyeti korur.
para, küçük para decimal.Decimal Sabit hassasiyet (dört ondalık basamak).
char, varchar, metin str UTF-8 olarak çözüldü.
nchar, nvarchar, ntext str UTF-16LE olarak çözüldü.
ikili, varbinary, görüntü bytes Ham ikilik.
date datetime.date Sadece randevu için.
time datetime.time Mikrosaniye hassasiyetiyle zaman.
tarih zamanı, küçük tarih saati datetime.datetime Eski tarih saati türleri.
datetime2 datetime.datetime Yüksek hassasiyetle tarih saati.
datetimeoffset datetime.datetime Saat dilimi farkında tarih saati.
uniqueidentifier uuid.UUID Python UUID nesneleri.
xml str XML metin olarak.
Coğrafya, Geometri bytes Mekansal tipler ikili olarak kullanılır.
hierarchyid bytes Hiyerarşi verileri ikili olarak kullanılır.
sql_variant Varies Temel baz tipine (v1.5.0+) çözüm olarak sunuldu. sql_variant Sütunlar, sabit tip sütunlara kıyasla biraz performans etkisi yaratabilecek bir akış getirme yolu kullanır.
NULL None Python Hiçbiri.

SQL tür sabitleri

Sürücü, ODBC SQL tür tanımlayıcılarına karşılık gelen sabitleri dışa aktarır. Genellikle bu sabitleri setinputsizes() , otomatik eşleme şemanızla uyuşmadığında sürücünün varsayılan tür çıkarımını geçersiz kılmak için kullanırsınız.

Karakter türleri

Sabit Değer Açıklama
SQL_CHAR 1 Sabit uzunluklu ANSI karakteri.
SQL_VARCHAR 12 Değişken uzunlukta ANSI karakteri.
SQL_LONGVARCHAR -1 Uzun değişken uzunluklu ANSI.
SQL_WCHAR -8 Sabit uzunluklu Unicode.
SQL_WVARCHAR -9 Değişken uzunlukta Unicode.
SQL_WLONGVARCHAR -10 Uzun değişken uzunluklu Unicode.

Sayısal türler

Sabit Değer Açıklama
SQL_BIT -7 Bit/boolean.
SQL_TINYINT -6 8 bit işaretsiz tamsayı.
SQL_SMALLINT 5 16 bit işaretli tamsayı.
SQL_INTEGER 4 32 bit işaretli tamsayı.
SQL_BIGINT -5 64-bit işaretli tam sayı.
SQL_REAL 7 32 bit kayan nokta.
SQL_FLOAT 6 64-bit kayan nokta.
SQL_DOUBLE 8 64-bit kayan nokta.
SQL_DECIMAL 3 Sabit hassas ondalık sistem.
SQL_NUMERIC 2 Sabit, hassasiyet sayısal.

Tarih ve saat türleri

Sabit Değer Açıklama
SQL_TYPE_DATE 91 Sadece randevu için.
SQL_TYPE_TIME 92 Sadece zaman.
SQL_TYPE_TIMESTAMP 93 Tarih ve saat.
SQL_SS_TIME2 -154 SQL Server time(n).
SQL_DATETIMEOFFSET -155 SQL Server datetimeoffset.

Note

SQL_SS_TIME2 ve SQL_DATETIMEOFFSET modül düzeyinde öznitelikler olarak dışa aktarılmayan iç sabitlerdir. Tam sayı değerlerini (-154, -155) doğrudan çağırırken add_output_converter()kullanın.

İkili türler

Sabit Değer Açıklama
SQL_BINARY -2 Sabit uzunluklu ikili sistem.
SQL_VARBINARY -3 Değişken uzunlukta ikili arter.
SQL_LONGVARBINARY -4 Uzun, değişken uzunlukta ikili dosya.

Diğer türler

Sabit Değer Açıklama
SQL_GUID -11 Uniqueidentifier.
SQL_XML -152 XML verileri.
SQL_SS_UDT -151 Kullanıcı tarafından tanımlanan tip (uzamsalsal).
SQL_SS_VARIANT -150 sql_variant veri.

Note

SQL_SS_UDT ve SQL_SS_VARIANT modül düzeyinde öznitelikler olarak dışa aktarılmayan iç sabitlerdir. Tam sayı değerlerini (-151, -150) doğrudan çağırırken add_output_converter()kullanın.

setinputsizes() kullanın

Sürücünün otomatik tip çıkarımı beklenmedik davranışa yol açtığında, örneğin bir sütun ise varchar(100) sürücü nvarchargönderdiğinde parametre türlerini açıkça bildirmek için önce executemany() çağrı setinputsizes() yapın:

Note

Ondalık değerler için, sürücünün otomatik tip çıkarımına güvenin, SQL_DECIMAL veya SQL_NUMERICyerine . Bu açık ondalık tür sabitlerin şu anda bilinen bir sorunu vardır.setinputsizes() Daha fazla bilgi için bkz. Sorguları yürüt.

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),
    ]
)

Ondalık ayırıcı

Sürücü, yerel olarak ondalık ayırıcılar kullanır. Özelleştirmek için:

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(",")

Özel tip dönüştürücüler

Belirli SQL türleri için özel dönüştürücüleri kaydet:

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)

Daha fazla bilgi için Özel tip dönüştürücüler sayfasına bakınız.

Özel tipleri tut

UUID yönetimi

Sürücü otomatik olarak haritalanıruuid.UUID.uniqueidentifier UUID'leri manuel dizi dönüştürmeden ekleyip alabilirsiniz:

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})

Varsayılan olarak, sürücü sütunları nesne olarak uuid.UUID döndürürUNIQUEIDENTIFIER. Bunun yerine pyodbc uyumlu büyük harf dizelerini döndürmek için 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()

Modül düzeyinde yapılandırma için, Modül yapılandırması içindeki ayara bakınıznative_uuid.

Saat dilimiyle tarih saati

datetimeoffset sütunlar zaman dilimi farkında datetime nesneleri döndürür. Ofset farkında ve ofset-naif değerlerle çalışma konusunda rehberlik için bkz. Datetime handling.

cursor.execute("SELECT SYSDATETIMEOFFSET()")
row = cursor.fetchone()
dt = row[0]

print(f"DateTime: {dt}")
print(f"Timezone: {dt.tzinfo}")

Uzamsal veriler

Sürücü, uzamsal tipleri (geography, geometry) olarak döndürür.bytes Parametre dizileri WKT formatında kullanabilirsiniz:

# 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]

sıralı versiyon/zaman damgası

SQL Server'rowversionın (eski timestampadıyla ) bir ikili tiptir, tarih saati değildir:

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

Akış büyük değer türleri

, nvarchar(max), veya varbinary(max) veri eklendiğinde veya alındığındavarchar(max), sürücü tüm değeri aynı anda belleğe yüklemek yerine verileri parçalar halinde iletmek için Data-at-Execution (DAE) akışını kullanır.

Akış, giriş verisi boyut eşiklerini aştığında otomatik olarak aktive olur:

Veri türü Yayın eşiği
varchar(max) > 8.000 bayt
nvarchar(max) > 4.000 karakter
varbinary(max) > 8.000 bayt

Akış, , executemany(), ve tüm fetch API'leri (fetchone(), fetchmany(), fetchall()) ile çalışırexecute(). Sürücü özel bir yapılandırma gerektirmez ve büyük değerler için yayını otomatik olarak yönetir.

Desteklenmeyen SQL Server türleri

Aşağıdaki SQL Server türlerinin yerel Python tipi eşlemeleri yoktur. Uygulamanız bu tür türleri gerektiriyorsa, geçici olarak string veya ikili temsil kullanın ya da ihtiyacınız olan tipi destekliyorsa pyodbc kullanın.

SQL Server türü Statü
json Desteklenmiyor
vector Desteklenmiyor
table Desteklenmiyor (tablo değerli parametreler)

Tip

SQL Server türü doğrudan desteklenmese de json , JSON verilerini sütunlarda nvarchar(max) depolayıp SQL Server JSON fonksiyonlarıyla sorgulayabilirsiniz (JSON_VALUE, JSON_QUERY, OPENJSON). Kalıplar ve örnekler için JSON verilerine bakınız.

Aşağıdaki türler veriyi döndürür bytes ancak yerel Python tür eşlemeleri yoktur:

SQL Server türü Python türü Notlar
geography bytes WKB formatı için kullanım .STAsBinary() .
geometry bytes WKB formatı için kullanım .STAsBinary() .
hierarchyid bytes İkili temsil.
sql_variant Varies Altta yatan baz tipine çözüm bulmuş.

ondalık ve yüzme hassasiyeti

Finansal hesaplamalar, para birimi veya yuvarlatma hatalarının kabul edilemez olduğu herhangi bir değer gibi hassas hassasiyet önemli durumlarda kullanın decimal.Decimal . Bilimsel ölçümler veya sensör okumaları gibi yaklaşık değerler kabul edilebilir olduğunda kullanın float .

Sürücü SQL Server'a decimal/numeric eşlenir decimal.Decimal ve 38 haneli hassasiyeti korur. floatSQL Server'a float (64-bit IEEE 754) eşlemesi yapılır, bu da yuvarlama artefaktları getirebilir:

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'>

Sütunları alırkendecimal/numeric, sürücü her zaman nesneleri döndürür.decimal.Decimal Sütunları alırkenfloat/real, sürücü Python floatdöndürür.

Warning

Eşitlik için değerleri karşılaştırmayın float . Bunun yerine bir tolerans aralığı kullanın: abs(a - b) < 0.0001.

Numpy tip bağlanma

Sürücü, mssql-python parametreler için SQL türlerini belirlemek için kontrolleri kullanır isinstance() . Numpy tam sayı tipleri (numpy.int64, numpy.int32, numpy.int8) NumPy 2.x'te geçmez isinstance(x, int) ve bu da bağlama hatalarına yol açar. Doğrudan çalışıyor numpy.float64 çünkü Pythonfloat'un bir alt sınıfıdır.

Numpy değerleri parametre olarak aktarmadan önce yerel Python tiplerine dönüştürün:

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"])}
    )

Pandas veya numpy verileriyle yoğun çalışıyorsanız, tip dönüşümünü dahili olarak yöneten Arrow entegrasyonu veya pandas entegrasyon yollarını kullanmayı düşünün.