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 biedt Apache Arrow-ophaalmethoden voor hoogpresterende kolomgegevensopvraging uit Microsoft SQL en Azure SQL Database.
Apache Arrow is een platform voor taaloverstijgende ontwikkeling voor kolomgegevens in het geheugen. De driver zet ODBC-resultaatsets direct om in het Arrow-formaat in C++, waarbij Python-objectcreatie wordt omzeild voor betere prestaties.
Arrow-integratie maakt het volgende mogelijk:
- Zero-copy gegevensoverdracht naar Polars, pandas en DuckDB. "Zero-copy" betekent dat de data in één enkele geheugenbuffer blijft die de driver schrijft en die de consumerende bibliotheken direct lezen, zodat er geen rijen worden gedupliceerd in intermediaire Python-objecten.
- Resultaatsets streamen via
RecordBatchReaderzonder alles in het geheugen te laden. - Columnar dataformaat ideaal voor analytics- en machine learning-workloads.
- Minder geheugengebruik vergeleken met het opmaken van Python-objecten per rij.
Cursormethoden
Het pyarrow pakket moet Arrow-ophaalmethoden gebruiken. Installeer het met pip install pyarrow. Als pyarrow niet geïnstalleerd is, genereert het aanroepen van een Arrow-methode een ImportError.
De mssql-python-driver voegt drie methoden toe aan het cursorobject voor Arrow-data-toegang. Alle drie de methoden converteren ODBC-resultatensets naar Arrow-formaat in de C++-laag van de driver, waardoor het creëren van tussenliggende Python-objecten voorkomt.
-
arrow()geeft de volledige resultaatset terug als één in-memory tabel. Zijn het eenvoudigst te gebruiken. -
arrow_batch()geeft één batch rijen tegelijk terug, waardoor je handmatige controle over de lus hebt. -
arrow_reader()geeft een iterator terug die automatisch batches oplevert. Het beste voor het streamen van grote resultaten.
Het gebruiken van cursor.arrow(batch_size=8192)
Haal de volledige resultaatset op als één enkele pyarrow.Table. Deze methode is de eenvoudigste en werkt goed wanneer de volledige resultaatset in het geheugen past.
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product")
table = cursor.arrow()
print(type(table)) # <class 'pyarrow.lib.Table'>
print(table.num_rows) # Number of rows fetched
print(table.num_columns) # Number of columns
print(table.schema) # Column names and Arrow types
print(table.to_pandas()) # Convert to pandas DataFrame
Opmerking
Als je verbindingsreeks Authentication=ActiveDirectoryDefault gebruikt, gebruikt de driver DefaultAzureCredential, die meerdere referentieproviders opeenvolgend probeert. De eerste verbinding kan traag zijn omdat de SDK de keten doorloopt totdat hij een werkende provider vindt. In productie, als je weet welk type inloggegevens je omgeving gebruikt, specificeer het dan direct (bijvoorbeeld ActiveDirectoryMSI voor managed identity) om de chain walk te voorkomen. Zie Microsoft Entra-verificatie voor meer informatie.
Het gebruiken van cursor.arrow_batch(batch_size=8192)
Haal één pyarrow.RecordBatch op met maximaal batch_size rijen. Gebruik deze methode voor aangepaste batchverwerkingslussen waarbij je fijnmazige controle nodig hebt over hoeveel rijen tegelijk worden opgehaald.
cursor.execute("SELECT * FROM Production.TransactionHistory")
while True:
batch = cursor.arrow_batch(batch_size=10000)
if batch.num_rows == 0:
break
# Process each batch
print(f"Fetched {batch.num_rows} rows")
Het gebruiken van cursor.arrow_reader(batch_size=8192)
Geef een pyarrow.RecordBatchReader terug die objecten oplevert RecordBatch totdat de resultaatset is uitgeput. Deze methode is de meest geheugen-efficiënte optie voor grote resultaatsets.
cursor.execute("SELECT * FROM Production.TransactionHistory")
reader = cursor.arrow_reader(batch_size=50000)
for batch in reader:
# Process streaming batches without loading all data
print(f"Batch: {batch.num_rows} rows")
Algemene patronen
Arrow-tabellen integreren direct met populaire Python-databibliotheken. De volgende voorbeelden laten zien hoe je Arrow-gegevens kunt doorgeven aan pandas, Polars, DuckDB en bestandsformaten zonder data te kopiëren.
Laad resultaten in pandas
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
# Convert to pandas with zero-copy where possible
df = table.to_pandas()
print(df.head())
Resultaten laden in Polars
import polars as pl
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
df = pl.from_arrow(table)
print(df)
Zoekresultaten met DuckDB
DuckDB kan Arrow-tabellen direct in SQL bevragen zonder data te kopiëren. Deze mogelijkheid is handig wanneer je SQL-achtige analyses nodig hebt op resultaatsets die al in Arrow-formaat zijn.
import duckdb
cursor.execute("SELECT * FROM Sales.SalesOrderHeader")
arrow_table = cursor.arrow()
# Query the Arrow table with DuckDB SQL
result = duckdb.sql("SELECT CustomerID, SUM(TotalDue) FROM arrow_table GROUP BY CustomerID")
print(result.fetchall())
Grote resultaatsets naar Parquet streamen
Voor grote resultaatsets streamt u Arrow-batches direct naar een Parquet-bestand zonder de volledige dataset in het geheugen te laden. De ParquetWriter schrijft elke batch incrementeel.
import pyarrow.parquet as pq
cursor.execute("SELECT * FROM Production.TransactionHistory")
reader = cursor.arrow_reader(batch_size=100000)
# Write streaming batches to a Parquet file
writer = None
for batch in reader:
if writer is None:
writer = pq.ParquetWriter("output.parquet", batch.schema)
writer.write_batch(batch)
if writer:
writer.close()
Export naar andere formaten
PyArrow biedt ingebouwde schrijvers voor CSV en het Arrow IPC-bestandsformaat (ook bekend als Feather V2). Arrow IPC-bestanden behouden Arrow-types exact en zijn snel terug te lezen.
import pyarrow as pa
import pyarrow.csv as pcsv
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
# Write to CSV
pcsv.write_csv(table, "products.csv")
# Write to an Arrow IPC file
with pa.ipc.new_file("products.arrow", table.schema) as writer:
writer.write_table(table)
Gegevenstypetoewijzingen
De Arrow-ophaalmethoden mappen Microsoft SQL-types toe aan Arrow-types op C++-niveau.
| Microsoft SQL-type | Pijltype |
|---|---|
| int, smallint, tinyint, bigint |
int32,int16,int8,int64 |
| Float, Reëel |
float64, float32 |
| decimaal, numeriek | decimal128 |
| bit | bool |
| Char, Varchar, Nchar, Nvarchar | utf8 |
| Tekst, Ntext | large_utf8 |
| binair, varbinair |
binary, large_binary |
| date | date32 |
| time | time64[us] |
| Datetime, Datetime2, Smalldatetime | timestamp[us] |
| datetimeoffset | timestamp[us, tz=UTC] |
| uniqueidentifier |
utf8 (tekst in hoofdletters) |
| xml | utf8 |
Opmerking
De chauffeur zet het datetimeoffset type om naar UTC omdat pijlkolommen een vaste tijdzone vereisen. De driver normaliseert de tijdzone-informatie per cel van Microsoft SQL naar UTC tijdens de conversie.
Het sql_variant type wordt niet ondersteund door Arrow-ophaalmethoden en veroorzaakt een uitzondering voor het niet-ondersteunde datatype. Gebruik standaard fetchone(), fetchmany() of fetchall() voor query's die sql_variant kolommen retourneren.
Prestatie-overwegingen
Arrow fetch-methoden zijn het snelst voor analytics en bulkdata-operaties, terwijl standaard cursormethoden beter geschikt zijn voor transactionele patronen met kleine resultatensets.
Wanneer te gebruiken met Arrow versus standaard fetch
| Scenario | Aanbevolen aanpak |
|---|---|
| Haal een paar rijen op voor weergave | fetchone() / fetchall() |
| Laad data in pandas of Polars | cursor.arrow() |
| Verwerk grote datasets in delen | cursor.arrow_reader() |
| Zoekopdrachten met één rij of kleine resultaatsets | fetchone() / fetchval() |
| Analytics- of aggregatiepijplijnen |
cursor.arrow() + Polars/DuckDB |
| Schrijf resultaten naar Parquet of Arrow IPC |
cursor.arrow_reader() + PyArrow I/O |
Geheugenbeheer voor grote datasets
Voor resultaatsets die mogelijk het beschikbare geheugen overschrijden, gebruik arrow_reader() met een redelijke batch_size.
cursor.execute("SELECT * FROM Production.TransactionHistory")
# Process in batches of 100K rows
reader = cursor.arrow_reader(batch_size=100000)
total_rows = 0
for batch in reader:
# Work with each batch individually
total_rows += batch.num_rows
# batch goes out of scope and memory is freed
print(f"Processed {total_rows} rows")
Batchgrootte afstemmen
De batch_size parameter bepaalt hoeveel rijen er per batch worden opgehaald. De optimale grootte hangt af van je rijbreedte en beschikbare geheugen. Bredere rijen met grote kolommen zoals nvarchar(max) of varbinary(max) profiteren van kleinere batchgroottes, terwijl smalle rijen profiteren van grotere.
- Standaard (8192): Goede balans voor de meeste werklasten.
- Kleiner (1000-5000): Gebruik voor brede tabellen met grote kolommen.
- Groter (50000-100000): Gebruik voor smalle tabellen of wanneer doorvoer belangrijker is dan geheugen.
# Narrow table with many rows - use larger batches
cursor.execute("SELECT ProductID, ListPrice FROM Production.Product")
table = cursor.arrow(batch_size=100000)
# Wide table with LOB columns - use smaller batches
cursor.execute("SELECT * FROM Production.Document")
table = cursor.arrow(batch_size=1000)