Gerencie conexões com mssql-python

A maioria das aplicações segue um padrão simples: abrir uma conexão, rodar consultas, fechar a conexão. As seções seguintes abordam a abertura e o fechamento de conexões, uso de gerenciadores de contexto, configuração de autocommit e trabalho com atributos de conexão.

Abra uma conexão

Use a connect() função para estabelecer uma conexão. Passe uma cadeia de conexão com seus dados de servidor, banco de dados e autenticação:

import mssql_python

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;Database=<database>;"
    "Authentication=ActiveDirectoryDefault;Encrypt=yes"
)

A connect() função aceita:

  • Uma cadeia de conexão como o primeiro argumento posicional ou a palavra-chave connection_str.
  • Palavras-chave individuais que o driver mescla na cadeia de conexão.
  • Outras opções como autocommit, timeout, e attrs_before.

Você pode misturar as duas abordagens. Palavras-chave substituem valores na cadeia de conexão, o que é útil quando você armazena uma cadeia de conexão base na configuração e substitui configurações como timeout a cada chamada:

# Base connection string from config, with per-call overrides
conn = mssql_python.connect(
    "Server=<server>.database.windows.net;Database=<database>;"
    "Authentication=ActiveDirectoryDefault;Encrypt=yes",
    timeout=30,
    autocommit=True
)

Feche uma conexão

Sempre feche as conexões quando terminadas para devolvê-las ao pool de conexões e libere os recursos do servidor. Conexões não fechadas armazenam memória do lado do servidor e podem eventualmente esgotar o pool de conexões, causando novas tentativas de bloqueio ou falha.

conn = mssql_python.connect(connection_string)
try:
    # Use the connection
    cursor = conn.cursor()
    cursor.execute("SELECT 1")
finally:
    conn.close()

Uma vez fechada, a conexão não pode ser usada:

conn.close()
print(conn.closed)  # True

# This raises an error
cursor = conn.cursor()  # InterfaceError: Cannot create cursor on closed connection

Chamar close() várias vezes é seguro (idempotente):

conn.close()
conn.close()  # No error

Gerenciadores de contexto

Use a with instrução para gerenciar conexões na maioria das aplicações. Garante que o driver feche a conexão ao sair do bloco, mesmo que ocorra uma exceção. Essa abordagem elimina o risco de vazamento de conexões devido a chamadas close() esquecidas:

with mssql_python.connect(connection_string) as conn:
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE #Demo (Name NVARCHAR(50))")
    cursor.execute("INSERT INTO #Demo (Name) VALUES ('Widget')")
    conn.commit()  # Must commit explicitly when autocommit=False
# Connection automatically closed

O gerenciador de contexto fecha a conexão na saída. Não efetua commit automaticamente nem reverte transações:

  • Sempre: Chama close() na saída, tenha ocorrido uma exceção ou não.
  • close() comportamento: Se autocommit=False, quaisquer alterações não comprometidas são revertidas quando a conexão se fecha.
  • Você deve chamar conn.commit() explicitamente para persistir as mudanças.

Esta implementação segue o comportamento da PEP 249 e evita confirmações parciais acidentais. Se o seu código lançar uma exceção antes de atingir commit(), a transação em andamento será revertida com segurança:

# Equivalent manual code:
conn = mssql_python.connect(connection_string)
try:
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE #Demo (Name NVARCHAR(50))")
    cursor.execute("INSERT INTO #Demo (Name) VALUES ('Widget')")
    conn.commit()  # Must commit explicitly
finally:
    conn.close()  # Rolls back uncommitted changes if autocommit=False

Modo de confirmação automática

Por padrão, autocommit=False, o que significa que cada instrução é executada dentro de uma transação implícita. Você deve chamar conn.commit() para salvar as alterações ou conn.rollback() para descartá-las. Transações implícitas são a escolha mais segura para modificações de dados porque permitem agrupar múltiplas instruções em uma única operação atômica.

Ative a confirmação automática quando quiser que cada instrução seja efetivada imediatamente. Autocommit é útil para operações DDL (CREATE TABLE, ALTER INDEX), cargas de trabalho de somente leitura ou scripts administrativos em que não é necessário agrupar transações:

conn = mssql_python.connect(connection_string)
print(conn.autocommit)  # False

cursor = conn.cursor()
cursor.execute("CREATE TABLE #Demo (Name NVARCHAR(50))")
cursor.execute("INSERT INTO #Demo (Name) VALUES ('Widget')")
conn.commit()  # Required to persist changes

Ative a confirmação automática para que cada instrução seja confirmada imediatamente. Use autocommit=True no momento da conexão ou altere essa opção após se conectar com setautocommit() ou por atribuição direta da propriedade:

# At connection time
conn = mssql_python.connect(connection_string, autocommit=True)

# Or after connection (both forms work)
conn.setautocommit(True)
conn.autocommit = True
print(conn.autocommit)  # True

# Now changes are committed automatically
cursor = conn.cursor()
cursor.execute("SELECT TOP 1 Name FROM Production.Product")
print(cursor.fetchone().Name)
# No commit() needed

Tempo de espera da conexão esgotado

Defina o timeout da conexão para controlar quanto tempo o driver espera para estabelecer a conexão antes de gerar um erro. Um tempo de conexão razoável é importante para aplicações implantadas em ambientes com redes pouco confiáveis ou para falhas rápidas quando um servidor está inacessível:

# At connection time (in seconds)
conn = mssql_python.connect(connection_string, timeout=30)

# Or after connection
conn.timeout = 60
print(conn.timeout)  # 60

Um tempo limite de 0 significa nenhum tempo limite (aguarda indefinidamente). Defina tempos razoáveis na produção; Uma tentativa de conexão travada sem timeout bloqueia permanentemente a thread de chamada.

Atributos de conexão

Use set_attr() para modificar o comportamento da conexão em tempo de execução. Os atributos de conexão controlam configurações de driver de baixo nível, como modo de acesso, isolamento de transações e tamanho do pacote. A maioria das aplicações não precisa alterar esses atributos, mas eles são úteis para cenários específicos:

  • Modo somente leitura: Previne escritas acidentais em consultas de relatórios.
  • Isolamento de transações: Controla como as transações concorrentes interagem (uso SERIALIZABLE para consistência estrita, READ_COMMITTED para uso geral).
  • Tamanho do pacote: Ajuste para redes de alta latência ou alta taxa de transferência.
import mssql_python

conn = mssql_python.connect(connection_string)

# Set read-only mode
conn.set_attr(mssql_python.SQL_ATTR_ACCESS_MODE, mssql_python.SQL_MODE_READ_ONLY)

# Set transaction isolation level
conn.set_attr(mssql_python.SQL_ATTR_TXN_ISOLATION, mssql_python.SQL_TXN_SERIALIZABLE)

Atributos disponíveis:

Constante Descrição
SQL_ATTR_CONNECTION_TIMEOUT Tempo limite de conexão em segundos.
SQL_ATTR_LOGIN_TIMEOUT Tempo limite para login em segundos.
SQL_ATTR_PACKET_SIZE Tamanho do pacote de rede.
SQL_ATTR_ACCESS_MODE Modo somente leitura ou leitura e gravação.
SQL_ATTR_TXN_ISOLATION Nível de isolamento de transações.
SQL_ATTR_CURRENT_CATALOG Nome atual do banco de dados.

Atributos de pré-conexão

Alguns atributos devem ser definidos antes que o driver estabeleça a conexão (por exemplo, o tempo de encerramento de login). Passe-os por attrs_before:

conn = mssql_python.connect(
    connection_string,
    attrs_before={
        mssql_python.SQL_ATTR_LOGIN_TIMEOUT: 30,
        mssql_python.SQL_ATTR_CONNECTION_TIMEOUT: 60,
    }
)

Obter informações de conexão

Use getinfo() para recuperar metadados de drivers e servidores para registro, diagnóstico ou adaptação de comportamento com base nas capacidades do servidor:

conn = mssql_python.connect(connection_string)

# Server information
print(f"Server name: {conn.getinfo(mssql_python.SQL_SERVER_NAME)}")
print(f"Database name: {conn.getinfo(mssql_python.SQL_DATABASE_NAME)}")

# Driver information
print(f"Driver name: {conn.getinfo(mssql_python.SQL_DRIVER_NAME)}")
print(f"Driver version: {conn.getinfo(mssql_python.SQL_DRIVER_VER)}")

Obtenha uma lista de constantes de informação disponíveis:

constants = mssql_python.get_info_constants()
for name, value in constants.items():
    print(f"{name}: {value}")

Caractere de escape de pesquisa

A propriedade searchescape retorna o caractere usado para escapar caracteres curinga (% e _) nos padrões LIKE. Use-o para buscar com segurança caracteres coringa literais na entrada do usuário:

escape = conn.searchescape

# Use in queries with wildcard characters
cursor.execute(
    f"SELECT Name FROM Production.Product WHERE Name LIKE '%{escape}%%' ESCAPE '{escape}'"
)
# Matches names containing literal '%' character

Codificação e decodificação

Configure a codificação de texto para instruções e resultados SQL. As configurações padrão funcionam para a maioria das aplicações. Altere-as apenas se você se conectar a um servidor que use uma codificação diferente de UTF-8 para colunas char/varchar. A codificação que um servidor usa depende da ordenação da coluna:

# Set encoding for outbound text
conn.setencoding(encoding='utf-8')

# Get current encoding settings
settings = conn.getencoding()
print(settings)  # {'encoding': 'utf-8', 'ctype': ...}

# Set decoding for inbound text from specific SQL types
conn.setdecoding(mssql_python.SQL_CHAR, encoding='utf-8')

# Get current decoding settings
settings = conn.getdecoding(mssql_python.SQL_CHAR)
print(settings)

Codificações padrão:

Direção Tipo SQL Codificação padrão
De saída (string) SQL_WCHAR utf-16le
Entrada SQL_CHAR utf-8
Entrada SQL_WCHAR utf-16le
Entrada SQL_WMETADATA utf-16le

Práticas recomendadas

  • Use gerenciadores de contexto (blocos with) para todas as conexões no código da aplicação. Eles garantem a limpeza mesmo quando ocorrem exceções.
  • Use o pool de conexão para melhor desempenho (ativado por padrão). Consulte pool de conexões.
  • Defina tempos limite apropriados para seu ambiente de rede. Um timeout de 30 segundos é adequado para a maioria das implantações em nuvem; aumente para conexões multi-região ou VPN.
  • Uso autocommit=False (o padrão) para cenários de modificação de dados onde você precisa de atomicidade transacional.
  • Use autocommit=True para operações DDL, consultas somente de leitura e scripts administrativos.
  • Não compartilhe conexões entre threads. O nível de segurança de thread do driver é 1 (as threads podem compartilhar o módulo, mas não as conexões).