Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der mssql-python-Treiber bietet Apache Arrow-Abrufmethoden für die Hochleistungs-Kolumnendatenabrufe aus Microsoft SQL und Azure SQL-Datenbank.
Apache Arrow ist eine sprachübergreifende Entwicklungsplattform für In-Memory-Kolumnendaten. Der Treiber wandelt ODBC-Ergebnissets direkt in das Arrow-Format in C++ um und umgeht damit die Erstellung von Python-Objekten für eine bessere Leistung.
Die Arrow-Integration ermöglicht:
- Datenübertragung ohne Kopie an Polars, Pandas und DuckDB. "Zero-copy" bedeutet, dass die Daten in einem einzigen Speicherpuffer bleiben, den der Treiber schreibt und die konsumierenden Bibliotheken direkt lesen, sodass keine Zeilen in zwischenliegende Python-Objekte dupliziert werden.
- Streaming von Ergebnismengen über
RecordBatchReader, ohne alles in den Speicher zu laden. - Spalten-Datenformat, ideal für Analyse- und Machine-Learning-Workloads.
- Geringerer Speicherverbrauch im Vergleich zur zeilenweisen Erstellung von Python-Objekten.
Cursormethoden
Das Paket pyarrow muss Arrow-Abrufmethoden verwenden. Installieren Sie es mit pip install pyarrow. Wenn pyarrow nicht installiert ist, erzeugt das Aufrufen einer beliebigen Arrow-Methode ein ImportError.
Der mssql-python-Treiber fügt dem Cursor-Objekt für den Datenzugriff auf Arrow drei Methoden hinzu. Alle drei Methoden konvertieren ODBC-Ergebnismengen in der C++-Schicht des Treibers in das Arrow-Format, sodass keine Python-Zwischenobjekte erzeugt werden müssen.
-
arrow()gibt die gesamte Ergebnismenge als eine einzelne In-Memory-Tabelle zurück. Sind am einfachsten zu verwenden. -
arrow_batch()gibt jeweils eine Reihe von Zeilen zurück, sodass du die Schleife manuell steuern kannst. -
arrow_reader()gibt einen Iterator zurück, der automatisch Chargen liefert. Am besten geeignet für das Streaming großer Ergebnismengen.
Verwenden von cursor.arrow(batch_size=8192)
Ruf die gesamte Ergebnismenge als eine einzelne pyarrow.Tableab. Diese Methode ist die einfachste und funktioniert gut, wenn der gesamte Ergebnissatz im Arbeitsspeicher Platz findet.
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
Note
Wenn Ihre Verbindungszeichenfolge Authentication=ActiveDirectoryDefault verwendet, nutzt der Treiber DefaultAzureCredential, das mehrere Anmeldeinformationsanbieter nacheinander ausprobiert. Die erste Verbindung kann langsam sein, weil das SDK die Kette durchläuft, bis es einen funktionierenden Anbieter findet. In der Produktion gilt: Wenn du weißt, welchen Zugangsdatentyp deine Umgebung verwendet, gib ihn direkt an (zum Beispiel ActiveDirectoryMSI für eine verwaltete Identität), um den Chain Walk zu vermeiden. Weitere Informationen finden Sie unter Microsoft Entra-Authentifizierung.
Verwenden von cursor.arrow_batch(batch_size=8192)
Rufen Sie eine einzelne pyarrow.RecordBatch ab, die bis zu batch_size Zeilen enthält. Verwenden Sie diese Methode für individuelle Batch-Verarbeitungsschleifen, bei denen Sie eine feine Kontrolle darüber benötigen, wie viele Zeilen gleichzeitig abgerufen werden.
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")
Verwenden von cursor.arrow_reader(batch_size=8192)
Geben Sie pyarrow.RecordBatchReader zurück, das RecordBatch-Objekte liefert, bis die Ergebnismenge erschöpft ist. Diese Methode ist die speichereffizienteste Option für große Ergebnismengen.
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")
Allgemeine Muster
Pfeiltabellen integrieren sich direkt in gängige Python-Datenbibliotheken. Die folgenden Beispiele zeigen, wie man Arrow-Daten an pandas, Polars, DuckDB und Dateiformate überträgt, ohne Daten zu kopieren.
Die Ladung führt zu 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())
Ergebnisse in Polars laden
import polars as pl
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
df = pl.from_arrow(table)
print(df)
Abfrageergebnisse mit DuckDB
DuckDB kann Arrow-Tabellen direkt in SQL abfragen, ohne Daten kopieren zu müssen. Diese Funktion ist nützlich, wenn Sie SQL-ähnliche Analysen von Ergebnissätzen benötigen, die bereits im Arrow-Format sind.
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())
Stream-Large-Ergebnismengen zu Parquet
Für große Ergebnissätze werden Arrow-Batches direkt in eine Parquet-Datei übertragen, ohne den gesamten Datensatz in den Speicher zu laden. Er ParquetWriter schreibt jeden Batch schrittweise.
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 in andere Formate
PyArrow bietet integrierte Schreiber für CSV und das Arrow IPC-Dateiformat (auch bekannt als Feather V2). Arrow IPC-Dateien bewahren Arrow-Typen genau und lassen sich schnell zurücklesen.
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)
Datentypzuordnungen
Die Arrow-Abrufmethoden bilden Microsoft-SQL-Typen auf der C++-Ebene auf Arrow-Typen ab.
| Microsoft SQL-Typ | Pfeiltyp |
|---|---|
| int, smallint, tinyint, bigint |
int32, int16, int8, int64 |
| schweben, echt |
float64, float32 |
| Dezimal, numerisch | decimal128 |
| bit | bool |
| Char, Varchar, Nchar, Nvarchar | utf8 |
| Text, Ntext | large_utf8 |
| Binär,varbinär |
binary, large_binary |
| date | date32 |
| Zeit | time64[us] |
| Datetime, Datetime2, SmallDatetime | timestamp[us] |
| datetimeoffset | timestamp[us, tz=UTC] |
| uniqueidentifier |
utf8 (Zeichenfolge in Großbuchstaben) |
| xml | utf8 |
Note
Der Fahrer wandelt den datetimeoffset Typ in UTC um, da die Pfeilspalten eine feste Zeitzone erfordern. Der Treiber normalisiert während der Umwandlung die Zeitzoneninformationen pro Zelle von Microsoft SQL zu UTC.
Der Typ sql_variant wird von Arrow-Fetch-Methoden nicht unterstützt und erzeugt eine nicht unterstützte Datentyp-Ausnahme. Verwenden Sie fetchone(), fetchmany() oder fetchall() als Standard für Abfragen, die sql_variant Spalten zurückgeben.
Leistungsüberlegungen
Pfeil-Fetch-Methoden sind am schnellsten für Analysen und Massendatenoperationen, während Standard-Cursor-Methoden besser für transaktionale Muster mit kleinen Ergebnismengen geeignet sind.
Wann man Arrow im Vergleich zum Standard-Fetch verwenden sollte
| Scenario | Empfohlener Ansatz |
|---|---|
| Einige Zeilen zur Anzeige abrufen | fetchone() / fetchall() |
| Daten in pandas oder Polars laden | cursor.arrow() |
| Verarbeiten Sie große Datensätze in Chunks | cursor.arrow_reader() |
| Suchvorgänge für einzelne Zeilen oder kleine Ergebnismengen | fetchone() / fetchval() |
| Analytik- oder Aggregationspipelines |
cursor.arrow() + Polars/DuckDB |
| Schreibe Ergebnisse in Parquet oder Arrow IPC |
cursor.arrow_reader() + PyArrow I/O |
Speicherverwaltung für große Datensätze
Für Ergebnismengen, die den verfügbaren Speicher überschreiten könnten, verwenden Sie arrow_reader() mit einer angemessenen 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")
Batch-Größe anpassen
Der Parameter batch_size steuert, wie viele Zeilen in jedem Batch abgerufen werden. Die optimale Größe hängt von deiner Zeilenbreite und dem verfügbaren Speicher ab. Breitere Reihen mit großen Spalten wie nvarchar(max) oder varbinary(max) profitieren von kleineren Chargen, während schmale Reihen von größeren profitieren.
- Standard (8192): Gute Balance für die meisten Workloads.
- Kleiner (1000–5000): Verwendung für breite Tabellen mit großen Spalten.
- Größer (50000–100000): Verwendung für schmale Tabellen oder wenn der Durchsatz wichtiger ist als der Speicher.
# 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)