Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Sterownik mssql-python udostępnia metody pobierania danych w formacie Apache Arrow, umożliwiające wydajne pobieranie danych kolumnowych z Microsoft SQL i Azure SQL Database.
Apache Arrow to wielojęzyczna platforma programistyczna do przetwarzania kolumnowych danych w pamięci. Sterownik konwertuje zestawy wyników ODBC bezpośrednio na format Arrow w C++, omijając tworzenie obiektów w Python dla poprawy wydajności.
Integracja Arrow umożliwia:
- Transfer danych bez kopiowania do Polars, Pandas i DuckDB. „Zero-copy” oznacza, że dane pozostają w jednym buforze pamięci, do którego sterownik zapisuje dane, a biblioteki korzystające odczytują je bezpośrednio, więc żaden wiersz nie jest kopiowany do pośrednich obiektów Pythona.
- Strumieniowe przesyłanie zestawów wyników za pośrednictwem
RecordBatchReaderbez wczytywania wszystkiego do pamięci. - Kolumnowy format danych idealny do zadań związanych z analityką i uczeniem maszynowym.
- Zmniejszone zużycie pamięci w porównaniu do tworzenia obiektów w Python wiersz po wierszu.
Metody kursora
Pakiet pyarrow jest wymagany do korzystania z metod pobierania Arrow. Zainstaluj go za pomocą polecenia pip install pyarrow. Jeśli pyarrow nie jest zainstalowany, wywołanie dowolnej metody Arrow powoduje ImportError.
Sterownik mssql-python dodaje trzy metody do obiektu kursora do dostępu do danych Arrow. Wszystkie trzy metody konwertują zestawy wyników ODBC na format Arrow w warstwie C++ sterownika, co pozwala uniknąć tworzenia pośrednich obiektów Python.
-
arrow()zwraca cały zbiór wyników jako jedną tablicę w pamięci. Najprostsze w użyciu. -
arrow_batch()Zwraca jedną partię wierszy naraz, zapewniając ręczną kontrolę nad pętlą. -
arrow_reader()zwraca iterator, który automatycznie generuje partie. Najlepsze do streamowania dużych wyników.
Korzystanie z cursor.arrow(batch_size=8192)
Pobierz cały zbiór wyników jako pojedynczy pyarrow.Table. Ta metoda jest najprostsza i dobrze działa, gdy cały zbiór wyników mieści się w pamięci.
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
Jeśli w parametrach połączenia użyto Authentication=ActiveDirectoryDefault, sterownik używa DefaultAzureCredential, który po kolei próbuje użyć wielu dostawców poświadczeń. Pierwsze połączenie może być wolne, ponieważ SDK przechodzi przez łańcuch, aż znajdzie dostawcę, który działa. W środowisku produkcyjnym, jeśli wiesz, jakiego typu poświadczeń używa środowisko, wskaż go bezpośrednio (na przykład ActiveDirectoryMSI w przypadku tożsamości zarządzanej), aby uniknąć przechodzenia przez łańcuch. Aby uzyskać więcej informacji, zobacz Microsoft Entra authentication (Uwierzytelnianie w usłudze Microsoft Entra).
Korzystanie z cursor.arrow_batch(batch_size=8192)
Pobierz pojedynczy pyarrow.RecordBatch, zawierający maksymalnie batch_size wierszy. Użyj tej metody w przypadku niestandardowych pętli przetwarzania wsadowego, gdy potrzebujesz szczegółowej kontroli nad liczbą wierszy pobieranych jednocześnie.
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")
Korzystanie z cursor.arrow_reader(batch_size=8192)
Zwróć pyarrow.RecordBatchReader, która zwraca obiekty RecordBatch do wyczerpania zestawu wyników. Ta metoda jest najbardziej efektywną pod względem pamięci opcją dla dużych zbiorów wyników.
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")
Często używane wzorce
Tabele strzałek integrują się bezpośrednio z popularnymi bibliotekami danych Python. Poniższe przykłady pokazują, jak przekazywać dane Arrow do panda, polarzy, DuckDB oraz formatów plików bez kopiowania danych.
Wczytaj wyniki do 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())
Załaduj wyniki do Polars
import polars as pl
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
df = pl.from_arrow(table)
print(df)
Wyniki zapytań za pomocą DuckDB
DuckDB może zapytywać tabele strzałek bezpośrednio w SQL bez kopiowania danych. Ta możliwość jest przydatna, gdy potrzebujesz analizy w stylu SQL na zestawach wyników już w formacie Arrow.
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())
Przesyłaj strumieniowo duże zbiory wyników do formatu Parquet
Dla dużych zbiorów wyników streamuj partie Arrow bezpośrednio do pliku Parquet, nie ładując całego zbioru danych do pamięci.
ParquetWriter zapisuje każdą partię przyrostowo.
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()
Eksport do innych formatów
PyArrow oferuje wbudowane mechanizmy zapisu do formatu CSV i formatu plików Arrow IPC (znanego również jako Feather V2). Pliki IPC Arrow zachowują dokładnie typy Arrow i są szybkie do odczytu.
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)
Mapowanie typu danych
Metody pobierania strzałek mapują typy Microsoft SQL na typy strzałek na poziomie C++.
| Typ Microsoft SQL | Typ strzałki |
|---|---|
| int, smallint, tinyint, bigint |
int32, int16, int8, int64 |
| Float, real |
float64, float32 |
| Dziesiętny, numeryczny | decimal128 |
| bit | bool |
| Char, Varchar, Nchar, Nvarchar | utf8 |
| tekst, ntext | large_utf8 |
| binary, varbinary |
binary, large_binary |
| date | date32 |
| time | time64[us] |
| datetime, datetime2, smalldatetime | timestamp[us] |
| datetimeoffset | timestamp[us, tz=UTC] |
| uniqueidentifier |
utf8 (ciąg pisany wielkimi literami) |
| xml | utf8 |
Note
Sterownik konwertuje datetimeoffset typ na UTC, ponieważ kolumny strzałek wymagają stałej strefy czasowej. Sterownik normalizuje informacje o strefach czasowych dla poszczególnych komórek z Microsoft SQL do UTC podczas konwersji.
Typ sql_variant nie jest obsługiwany przez metody pobierania danych Arrow i powoduje zgłoszenie wyjątku informującego o nieobsługiwanym typie danych. Użyj standardowego fetchone(), fetchmany(), lub fetchall() do zapytań zwracających sql_variant kolumny.
Zagadnienia dotyczące wydajności
Metody pobierania strzałek są najszybsze do analiz i operacji z danymi zbiorczymi, natomiast standardowe metody kursora lepiej sprawdzają się w wzorcach transakcyjnych z małymi zbiorami wyników.
Kiedy używać Arrow, a kiedy standardowego fetch
| Scenario | Zalecane podejście |
|---|---|
| Pobierz kilka wierszy do wyświetlenia | fetchone() / fetchall() |
| Ładuj dane do pand lub polarów | cursor.arrow() |
| Przetwarzaj duże zbiory danych w blokach | cursor.arrow_reader() |
| Wyszukiwania w pojedynczym wierszu lub małe zbiory wyników | fetchone() / fetchval() |
| Potoki analityki lub agregacji |
cursor.arrow() + Polars/DuckDB |
| Zapisz wyniki w formacie Parquet lub Arrow IPC |
cursor.arrow_reader() + PyArrow I/O |
Zarządzanie pamięcią dla dużych zbiorów danych
W przypadku zbiorów wyników, które mogą być większe niż dostępna pamięć, użyj arrow_reader(), ustawiając batch_size na rozsądną wartość.
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")
Dostosuj rozmiar partii
Parametr ten batch_size kontroluje, ile wierszy jest pobieranych w każdej partii. Optymalny rozmiar zależy od szerokości wiersza i dostępnej pamięci. Szersze wiersze z dużymi kolumnami, takimi jak nvarchar(max) czy varbinary(max), korzystają z mniejszych rozmiarów partii, podczas gdy wąskie wiersze korzystają z większych.
- Domyślne (8192): Dobra równowaga dla większości obciążeń.
- Mniejsze (1000-5000): Używa się do szerokich tabel z dużymi kolumnami.
- Większe (50000-100000): Zastosowanie do wąskich tabel lub gdy przepustowość ma większe znaczenie niż pamięć.
# 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)