Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O driver mssql-python mapeia automaticamente tipos de dados Python para tipos SQL Server ao enviar parâmetros e converte tipos SQL Server para tipos Python ao recuperar resultados.
Mapeamentos de Python para SQL Server
Quando passa valores Python como parâmetros para execute() ou executemany(), o driver seleciona automaticamente o tipo de SQL Server apropriado. Para a maioria das aplicações, o mapeamento automático está correto. Use setinputsizes() (descrito mais adiante neste artigo) apenas quando precisar de sobrescrever o padrão, por exemplo para forçar varchar em vez de nvarchar ou para controlar metadados de parâmetros para entradas de string e inteiros.
| Tipo Python | Tipo de SQL Server | Notes |
|---|---|---|
None |
NULL |
SQL NULL value. |
bool |
bit |
True→1, False→0. |
int |
tinyint, smallint, int,bigint | Tamanho selecionado com base na gama de valores. |
float |
float | Ponto flutuante de 64 bits. |
decimal.Decimal |
decimal, numérico | Preserva a precisão até 38 dígitos. |
str |
Varchar, Nvarchar | Usa nvarchar para conteúdo Unicode. |
bytes, bytearray |
varbinary | Dados binários. |
datetime.date |
date | Só para o encontro. |
datetime.time |
time | Só o tempo. |
datetime.datetime |
datetime2 | Data e hora com precisão em nanossegundos. |
uuid.UUID |
uniqueidentifier | GUID de 16 bytes. |
Seleção de tipos inteiros
O driver seleciona automaticamente o menor tipo inteiro que pode conter o valor:
| Intervalo de valores | Tipo de SQL Server |
|---|---|
| 0 a 255 | tinyint |
| -32.768 a 32.767 | smallint |
| -2.147.483.648 a 2.147.483.647 | int |
| Valores maiores | bigint |
Tipos de grande valor
Para strings e dados binários que excedam os limites padrão, o driver usa automaticamente os tipos MAX:
| Condição | Tipo de SQL Server |
|---|---|
| String > 8.000 bytes (varchar) | varchar(max) |
| String > 4.000 caracteres (nvarchar) | nvarchar(max) |
| Binário > de 8.000 bytes | varbinary(max) |
O driver transmite valores elevados para o servidor para minimizar o uso de memória.
Mapeamentos de SQL Server para Python
Quando o driver recupera dados do SQL Server, converte valores para tipos Python:
| Tipo de SQL Server | Tipo Python | Notes |
|---|---|---|
| bit | bool |
Verdadeiro/Falso. |
| tinyint, smallint, int,bigint | int |
Python inteiro (precisão arbitrária). |
| real | float |
Ponto flutuante de 32 bits. |
| float | float |
Ponto flutuante de 64 bits. |
| decimal, numérico | decimal.Decimal |
Preserva a precisão. |
| dinheiro, dinheiro pequeno | decimal.Decimal |
Precisão fixa (quatro casas decimais). |
| Char, Varchar, Texto | str |
Descodificado como UTF-8. |
| nchar, nvarchar, ntext | str |
Decodificado como UTF-16LE. |
| binário, varbinário, imagem | bytes |
Binário bruto. |
| date | datetime.date |
Só para o encontro. |
| time | datetime.time |
Tempo com precisão de microssegundos. |
| Hora do encontro, PequenoEncontroHora | datetime.datetime |
Tipos de datas legadas. |
| datetime2 | datetime.datetime |
Hora de encontro de alta precisão. |
| datetimeoffset | datetime.datetime |
Data-hora com base no fuso horário. |
| uniqueidentifier | uuid.UUID |
Objetos UUID em Python. |
| xml | str |
XML como texto. |
| Geografia, geometria | bytes |
Tipos espaciais como binários. |
| hierarchyid | bytes |
Dados da hierarquia como binários. |
| sql_variant | Variações | Resolvido para o tipo base subjacente.
sql_variant As colunas usam um caminho de busca em streaming, que pode ter um ligeiro impacto no desempenho em comparação com colunas do tipo fixo. |
NULL |
None |
Python Nenhum. |
Constantes de tipo SQL
O driver exporta constantes que correspondem a identificadores de tipo SQL ODBC. Normalmente usas estas constantes para setinputsizes() sobrepor a inferência de tipo padrão do driver quando o mapeamento automático não corresponde ao teu esquema.
Tipos de personagens
| Constante | Valor | Descrição |
|---|---|---|
SQL_CHAR |
1 | Carácter ANSI de comprimento fixo. |
SQL_VARCHAR |
12 | Carácter ANSI de comprimento variável. |
SQL_LONGVARCHAR |
-1 | ANSI longo de comprimento variável. |
SQL_WCHAR |
-8 | Unicode de comprimento fixo. |
SQL_WVARCHAR |
-9 | Unicode de comprimento variável. |
SQL_WLONGVARCHAR |
-10 | Unicode longo de comprimento variável. |
Tipos numéricos
| Constante | Valor | Descrição |
|---|---|---|
SQL_BIT |
-7 | Bit/booleano. |
SQL_TINYINT |
-6 | Inteiro não assinado de 8 bits. |
SQL_SMALLINT |
5 | Inteiro assinado de 16 bits. |
SQL_INTEGER |
4 | Inteiro assinado de 32 bits. |
SQL_BIGINT |
5- | Inteiro assinado de 64 bits. |
SQL_REAL |
7 | Ponto flutuante de 32 bits. |
SQL_FLOAT |
6 | Ponto flutuante de 64 bits. |
SQL_DOUBLE |
8 | Ponto flutuante de 64 bits. |
SQL_DECIMAL |
3 | Decimal de precisão fixa. |
SQL_NUMERIC |
2 | Numérico de precisão fixa. |
Tipos de data e hora
| Constante | Valor | Descrição |
|---|---|---|
SQL_TYPE_DATE |
91 | Só para o encontro. |
SQL_TYPE_TIME |
92 | Só o tempo. |
SQL_TYPE_TIMESTAMP |
93 | Data e hora. |
SQL_SS_TIME2 |
-154 | SQL Server tempo(n). |
SQL_DATETIMEOFFSET |
-155 | SQL Server datetimeoffset. |
Note
SQL_SS_TIME2 e SQL_DATETIMEOFFSET são constantes internas que não são exportadas como atributos ao nível do módulo. Use os valores inteiros (-154, -155) diretamente ao chamar add_output_converter().
Tipos binários
| Constante | Valor | Descrição |
|---|---|---|
SQL_BINARY |
-2 | Binário de comprimento fixo. |
SQL_VARBINARY |
-3 | Binário de comprimento variável. |
SQL_LONGVARBINARY |
-4 | Binário longo de comprimento variável. |
Outros tipos
| Constante | Valor | Descrição |
|---|---|---|
SQL_GUID |
-11 | Identificador único. |
SQL_XML |
-152 | Dados XML. |
SQL_SS_UDT |
-151 | Tipo definido pelo utilizador (espacial). |
SQL_SS_VARIANT |
-150 | sql_variant dados. |
Note
SQL_SS_UDT e SQL_SS_VARIANT são constantes internas que não são exportadas como atributos ao nível do módulo. Use os valores inteiros (-151, -150) diretamente ao chamar add_output_converter().
Use setinputsizes()
Chame setinputsizes() antes executemany() para declarar explicitamente os tipos de parâmetros quando a inferência automática de tipos do driver causa comportamentos inesperados, por exemplo, quando uma coluna é varchar(100) mas o driver envia nvarchar:
Note
Para valores decimais, baseia-se na inferência automática de tipos do condutor em vez de SQL_DECIMAL ou SQL_NUMERIC. Essas constantes decimais explícitas do tipo têm atualmente um problema conhecido com setinputsizes(). Para mais informações, veja Executar consultas.
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),
]
)
Separador decimal
O driver utiliza separadores decimais conscientes da localidade. Para personalizar:
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(",")
Conversores de tipo personalizado
Registe conversores personalizados para tipos específicos de 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)
Para mais informações, consulte Conversores de tipo personalizado.
Tipos especiais de alça
Tratamento de UUID
O condutor mapeia uuid.UUID para uniqueidentifier automaticamente. Pode inserir e recuperar UUIDs sem conversão manual de cadeias:
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})
Por defeito, o driver devolve UNIQUEIDENTIFIER as colunas como uuid.UUID objetos. Para devolver cordas maiúsculas compatíveis com pyodbc, defina 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()
Para configuração ao nível do módulo, consulte a native_uuid definição em Configuração do módulo.
Data-hora com fuso horário
datetimeoffset as colunas devolvem objetos conscientes datetime do fuso horário. Para orientações sobre como trabalhar com valores conscientes do offset versus ingênuos do deslocamento, veja Gestão da data-hora.
cursor.execute("SELECT SYSDATETIMEOFFSET()")
row = cursor.fetchone()
dt = row[0]
print(f"DateTime: {dt}")
print(f"Timezone: {dt.tzinfo}")
Dados geográficos
O driver devolve tipos espaciais (geography, geometry) como bytes. Pode usar cadeias de parâmetros no formato 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]
Rowversion/timestamp
O SQL Server rowversion (anteriormentetimestamp) é um tipo binário, não uma data-hora:
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
Tipos de grande valor de fluxo
Ao inserir ou recuperar varchar(max), nvarchar(max), ou varbinary(max) dados, o driver utiliza streaming Data-at-Execution (DAE) para transmitir dados em blocos, em vez de carregar o valor total na memória de uma só vez.
O streaming ativa automaticamente quando os dados de entrada ultrapassam os limiares de tamanho:
| Tipo de dados | Limiar de transmissão |
|---|---|
| varchar(max) | > 8.000 bytes |
| nvarchar(max) | > 4.000 caracteres |
| varbinary(max) | > 8.000 bytes |
O streaming funciona com execute(), executemany(), e todas as APIs de fetch (fetchone(), fetchmany(), fetchall()). O driver não requer configuração especial e gere o streaming automaticamente para valores elevados.
Tipos de SQL Server não suportados
Os seguintes tipos de SQL Server não têm mapeamentos nativos de tipos Python.
| Tipo de SQL Server | Situação |
|---|---|
| json | Não suportado |
| vector | Não suportado |
| table | Não suportado (parâmetros com valores de tabela) |
Sugestão
Embora o json tipo SQL Server não seja suportado diretamente, pode armazenar dados JSON em nvarchar(max) colunas e consultá-los com funções JSON do SQL Server (JSON_VALUE, JSON_QUERY, OPENJSON). Para padrões e exemplos, veja dados JSON.
Os seguintes tipos devolvem dados como bytes mapeamentos nativos de Python mas não possuem:
| Tipo de SQL Server | Tipo Python | Notes |
|---|---|---|
| geography | bytes |
Use .STAsBinary() para o formato WKB. |
| geometry | bytes |
Use .STAsBinary() para o formato WKB. |
| hierarchyid | bytes |
Representação binária. |
| sql_variant | Variações | Resolvido para o tipo base subjacente. |
Precisão decimal versus float
Use decimal.Decimal quando a precisão exata for importante, como cálculos financeiros, moeda ou qualquer valor onde erros de arredondamento sejam inaceitáveis. Use float quando valores aproximados são aceitáveis, como medições científicas ou leituras de sensores.
O driver mapeia decimal.Decimal para SQL Server decimal/numeric e preserva a precisão até 38 dígitos.
floatmapeia para o SQL Server float (IEEE 754 de 64 bits), que pode introduzir artefactos de arredondamento:
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'>
Ao recuperar decimal/numeric colunas, o driver devolve decimal.Decimal sempre objetos. Ao recuperar float/real colunas, o driver devolve Python . float
Warning
Não compares float valores para igualdade. Use antes um intervalo de tolerância: abs(a - b) < 0.0001.
Encadernação tipo entorpecido
O mssql-python driver utiliza isinstance() verificações para determinar os tipos SQL dos parâmetros. Os tipos de inteiros numpy (numpy.int64, numpy.int32, numpy.int8) não passam isinstance(x, int) no NumPy 2.x, o que causa falhas nas ligações. Só numpy.float64 funciona diretamente porque é uma subclasse de Pythonfloat.
Converter valores numpy para tipos nativos de Python antes de os passar como parâmetros:
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"])}
)
Se trabalhas muito com pandas ou dados numpy, considera usar a integração Arrow ou os caminhos de integração pandas , que tratam internamente da conversão de tipos.