Beheer verbindingen met mssql-python

De meeste applicaties volgen een eenvoudig patroon: open een verbinding, voer queries uit, sluit de verbinding. De volgende secties behandelen het openen en sluiten van verbindingen, het gebruik van contextbeheerders, het configureren van autocommit en het werken met verbindingsattributen.

Open een verbinding

Gebruik de connect() functie om een verbinding te maken. Geef een verbindingsreeks door met je server, database en authenticatiegegevens:

import mssql_python

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

De connect() functie accepteert:

  • Een verbindingsreeks als het eerste positionele argument of het trefwoord connection_str.
  • Individuele trefwoorden die de driver samenvoegt in de verbindingsreeks.
  • Andere opties zoals autocommit, timeout, en attrs_before.

Je kunt beide benaderingen combineren. Trefwoorden overschrijven waarden in de verbindingsreeks, wat handig is wanneer je een basis-verbindingsreeks opslaat in de configuratie en instellingen zoals timeout per call overschrijft:

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

Sluit een verbinding

Sluit altijd verbindingen als je klaar bent om ze terug te sturen naar de verbindingspool en serverbronnen vrij te geven. Ongesloten verbindingen bevatten server-side geheugen en kunnen uiteindelijk de verbindingspool uitputten, waardoor nieuwe verbindingspogingen blokkeren of mislukken.

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

Eenmaal gesloten kan de verbinding niet worden gebruikt:

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

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

close() meerdere keren aanroepen is veilig (idempotent):

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

Contextbeheerders

Gebruik de with statement om verbindingen in de meeste applicaties te beheren. Dit garandeert dat de driver de verbinding sluit wanneer het codeblok wordt verlaten, zelfs als er een uitzondering optreedt. Deze aanpak elimineert het risico van gelekte verbindingen door vergeten close() gesprekken:

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

De contextmanager sluit de verbinding bij het uitgaan. Het legt transacties niet automatisch vast en rolt ze niet terug:

  • Altijd: Roept close() aan bij het afsluiten, ongeacht of er een uitzondering is opgetreden.
  • close() gedrag: Als autocommit=False, worden wijzigingen die niet zijn gecommit teruggedraaid wanneer de verbinding wordt gesloten.
  • Je moet conn.commit() expliciet aanroepen om wijzigingen op te slaan.

Dit ontwerp volgt het gedrag van PEP 249 en voorkomt onbedoelde gedeeltelijke commits. Als je code een uitzondering veroorzaakt voordat commit() wordt bereikt, wordt de lopende transactie veilig teruggedraaid:

# 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

Modus Automatisch aanpassen

Standaard geldt autocommit=False, wat betekent dat elke verklaring binnen een impliciete transactie draait. Je moet oproepen conn.commit() om wijzigingen te behouden of conn.rollback() om ze te verwijderen. Impliciete transacties zijn de veiligste keuze voor data-aanpassingen omdat je hiermee meerdere statements kunt groeperen in één atomaire bewerking.

Schakel autocommit in wanneer je wilt dat elke statement direct committ. Autocommit is nuttig voor DDL-bewerkingen (CREATE TABLE, ALTER INDEX), workloads met alleen-lezenbewerkingen of administratieve scripts waarbij het groeperen van transacties niet nodig is:

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

Schakel autocommit in zodat elke instructie direct wordt vastgelegd. Gebruik autocommit=True tijdens het verbinden, of schakel het daarna om met setautocommit() of door de eigenschap rechtstreeks toe te wijzen:

# 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

Verbindingstijdoverschrijding

Stel de verbindingstimeout in om te bepalen hoe lang de driver wacht om een verbinding tot stand te brengen voordat er een foutmelding wordt gegeven. Een redelijke verbindingstimeout is belangrijk voor applicaties die worden ingezet in omgevingen met onbetrouwbare netwerken of voor snel uitvallen wanneer een server onbereikbaar is:

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

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

Een time-out van 0 betekent geen time-out (er wordt voor onbepaalde tijd gewacht). Stel redelijke timeouts in productie in; een vastgelopen verbindingspoging zonder timeout blokkeert de aanroepende thread permanent.

Verbindingskenmerken

Gebruik set_attr() om het verbindingsgedrag tijdens runtime aan te passen. Verbindingsattributen bepalen laag-niveau driverinstellingen zoals toegangsmodus, transactie-isolatie en pakketgrootte. De meeste applicaties hoeven deze attributen niet te wijzigen, maar ze zijn nuttig voor specifieke scenario's:

  • Alleen-lezen-modus: Voorkomt per ongeluk schrijven in rapportagezoekopdrachten.
  • Transactieisolatie: Regelt hoe gelijktijdige transacties interageren (gebruik SERIALIZABLE voor strikte consistentie, READ_COMMITTED voor algemeen gebruik).
  • Pakketgrootte: Stel af op netwerken met hoge latentie of hoge doorvoersnelheid.
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)

Beschikbare attributen:

Constante Beschrijving
SQL_ATTR_CONNECTION_TIMEOUT Time-out van de verbinding in seconden.
SQL_ATTR_LOGIN_TIMEOUT Aanmeldtime-out in seconden.
SQL_ATTR_PACKET_SIZE Pakketgrootte van het netwerk.
SQL_ATTR_ACCESS_MODE Alleen-lezen- of lees-/schrijfmodus.
SQL_ATTR_TXN_ISOLATION Transactie-isolatieniveau.
SQL_ATTR_CURRENT_CATALOG Huidige databasenaam.

Attributen voor voorafgaande verbinding

Sommige attributen moeten worden ingesteld voordat de driver de verbinding tot stand brengt (bijvoorbeeld inlogtimeout). Geef ze door:attrs_before

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

Verbindingsgegevens ophalen

Gebruik getinfo() om driver- en servermetadata op te halen voor loggen, diagnostiek of het aanpassen van gedrag op basis van servermogelijkheden:

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

Krijg een lijst met beschikbare informatieconstanten:

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

zoek-escape-teken

De searchescape eigenschap geeft het karakter terug dat gebruikt is om jokers (% en _) te ontwijken in patronen LIKE . Gebruik het om veilig te zoeken naar letterlijke wildcardtekens in gebruikersinvoer:

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

Codering en decodering

Configureer tekstcodering voor SQL-statements en resultaten. De standaardinstellingen werken voor de meeste applicaties. Verander ze alleen als je verbinding maakt met een server die een niet-UTF-8 codering voor char/varchar kolommen gebruikt. De codering die een server gebruikt hangt af van de kolom-collatie:

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

Standaardcoderingen:

Richting SQL-type Standaardcodering
Uitgaand (str) SQL_WCHAR utf-16le
Inkomend SQL_CHAR utf-8
Inkomend SQL_WCHAR utf-16le
Inkomend SQL_WMETADATA utf-16le

Beste praktijken

  • Gebruik contextmanagers (with-blokken) voor alle connecties in de applicatiecode. Ze garanderen opruiming, zelfs als er uitzonderingen zijn.
  • Gebruik verbindingspooling voor betere prestaties (standaard ingeschakeld). Zie Verbindingspooling.
  • Stel passende time-outs in voor je netwerkomgeving. Een time-out van 30 seconden past bij de meeste cloudimplementaties; verhoog het voor cross-region of VPN-verbindingen.
  • Gebruik autocommit=False (de standaard) voor data-wijzigingsscenario's waarbij je transactionele atomiciteit nodig hebt.
  • Gebruik autocommit=True voor DDL-operaties, alleen-lezen queries en admin-scripts.
  • Deel geen verbindingen over threads heen. Het threadveiligheidsniveau van de driver is 1 (threads kunnen de module delen, maar geen verbindingen).