Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
driver mssql-python menyediakan metode pengambilan berbasis Apache Arrow untuk mengambil data kolumnar berperforma tinggi dari Microsoft SQL dan Azure SQL Database.
Apache Arrow adalah platform pengembangan lintas bahasa untuk data kolom dalam memori. Driver ini mengonversi kumpulan hasil kueri ODBC langsung ke format Arrow dalam C++, tanpa perlu membuat objek Python, untuk meningkatkan performa.
Integrasi Arrow memungkinkan:
- Transfer data tanpa salinan ke Polars, pandas, dan DuckDB. "Zero-copy" berarti data tetap berada dalam satu buffer memori yang ditulisi driver dan dibaca langsung oleh pustaka yang menggunakannya, sehingga tidak ada baris yang diduplikasi ke dalam objek Python perantara.
- Mengalirkan kumpulan hasil melalui
RecordBatchReadertanpa memuat semuanya ke dalam memori. - Format data kolom ideal untuk beban kerja analitik dan pembelajaran mesin.
- Mengurangi penggunaan memori dibandingkan dengan pembuatan objek Python baris demi baris.
Metode kursor
Paket pyarrow diperlukan untuk menggunakan metode fetch Arrow. Instal itu dengan pip install pyarrow. Jika pyarrow tidak diinstal, pemanggilan metode apa pun dari Arrow akan menyebabkan ImportError.
Driver mssql-python menambahkan tiga metode ke objek kursor untuk akses data Arrow. Ketiga metode mengonversi result set ODBC ke format Arrow pada lapisan C++ driver, sehingga tidak perlu membuat objek Python perantara.
-
arrow()mengembalikan seluruh kumpulan hasil sebagai satu tabel dalam memori. Mudah untuk digunakan. -
arrow_batch()mengembalikan satu batch baris setiap kali, memberikan Anda kendali manual atas loop. -
arrow_reader()mengembalikan iterator yang menghasilkan batch secara otomatis. Paling cocok untuk streaming hasil dalam jumlah besar.
Menggunakan cursor.arrow(batch_size=8192)
Ambil seluruh kumpulan hasil sebagai satu pyarrow.Table. Metode ini adalah yang paling sederhana dan bekerja dengan baik ketika kumpulan hasil lengkap masuk ke dalam memori.
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
Jika string koneksi Anda menggunakan Authentication=ActiveDirectoryDefault, driver menggunakan DefaultAzureCredential, yang mencoba beberapa penyedia kredensial secara berurutan. Koneksi pertama bisa lambat karena SDK menelusuri rantai hingga menemukan penyedia yang berfungsi. Dalam lingkungan produksi, jika Anda mengetahui jenis kredensial yang digunakan oleh lingkungan Anda, tentukan secara langsung (misalnya, ActiveDirectoryMSI untuk identitas terkelola) agar terhindar dari penelusuran berantai. Untuk informasi selengkapnya, lihat Autentikasi Microsoft Entra.
Menggunakan cursor.arrow_batch(batch_size=8192)
Ambil satu pyarrow.RecordBatch yang berisi hingga batch_size baris. Gunakan metode ini untuk loop pemrosesan batch kustom di mana Anda memerlukan kontrol terperinci atas berapa banyak baris yang diambil sekaligus.
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")
Menggunakan cursor.arrow_reader(batch_size=8192)
Mengembalikan pyarrow.RecordBatchReader yang menghasilkan objek RecordBatch hingga kumpulan hasilnya habis. Metode ini adalah opsi yang paling hemat memori untuk kumpulan hasil yang besar.
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")
Pola umum
Tabel panah terintegrasi langsung dengan pustaka data Python populer. Contoh berikut menunjukkan cara meneruskan data Arrow ke panda, Polars, DuckDB, dan format file tanpa menyalin data.
Muat hasil ke panda
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
# Convert to pandas with zero-copy where possible
df = table.to_pandas()
print(df.head())
Muat hasil ke dalam Polars
import polars as pl
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
df = pl.from_arrow(table)
print(df)
Hasil kueri dengan DuckDB
DuckDB dapat mengkueri tabel Panah langsung di SQL tanpa menyalin data. Kemampuan ini berguna saat Anda memerlukan analisis gaya SQL pada kumpulan hasil yang sudah dalam format Panah.
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())
Alirkan set hasil berukuran besar ke Parquet
Untuk kumpulan hasil besar, alirkan batch Arrow langsung ke file Parquet tanpa memuat seluruh himpunan data ke dalam memori.
ParquetWriter menulis setiap batch secara bertahap.
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()
Ekspor ke format lain
PyArrow menyediakan penulis bawaan untuk CSV dan format file Arrow IPC (juga dikenal sebagai Feather V2). File IPC Arrow mempertahankan tipe Arrow secara persis dan cepat untuk dibaca kembali.
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)
Pemetaan jenis data
Metode pengambilan data Arrow memetakan tipe SQL Microsoft ke tipe Arrow pada level C++.
| Jenis Microsoft SQL | Tipe panah |
|---|---|
| int, smallint, tinyint, bigint |
int32,int16,int8,int64 |
| float, real |
float64, float32 |
| desimal, numerik | decimal128 |
| bit | bool |
| char, varchar, nchar, nvarchar | utf8 |
| teks, nteks | large_utf8 |
| biner, varbiner |
binary, large_binary |
| tanggal | date32 |
| time | time64[us] |
| datetime, datetime2, smalldatetime | timestamp[us] |
| datetimeoffset | timestamp[us, tz=UTC] |
| uniqueidentifier |
utf8 (string huruf besar) |
| xml | utf8 |
Note
Driver ini mengonversi tipe datetimeoffset ke UTC karena kolom Arrow memerlukan zona waktu tetap. Driver menormalkan informasi zona waktu per sel dari Microsoft SQL ke UTC selama konversi.
sql_variant jenis tidak didukung oleh metode fetch Arrow dan menimbulkan pengecualian tipe data yang tidak didukung. Gunakan fetchone(), fetchmany(), atau fetchall() standar untuk kueri yang mengembalikan kolom sql_variant.
Pertimbangan performa
Metode pengambilan panah tercepat untuk analitik dan operasi data massal, sedangkan metode kursor standar lebih cocok untuk pola transaksional dengan kumpulan hasil kecil.
Kapan menggunakan Arrow dibandingkan dengan fetch standar
| Scenario | Pendekatan yang disarankan |
|---|---|
| Ambil beberapa baris untuk ditampilkan | fetchone() / fetchall() |
| Muat data ke panda atau Kutub | cursor.arrow() |
| Memproses himpunan data besar dalam potongan-potongan | cursor.arrow_reader() |
| Pencarian baris tunggal atau kumpulan hasil kecil | fetchone() / fetchval() |
| Pipeline analitik atau agregasi |
cursor.arrow() + Polars/DuckDB |
| Tulis hasil ke Parquet atau Arrow IPC |
cursor.arrow_reader() + PyArrow I/O |
Manajemen memori untuk himpunan data besar
Untuk set hasil yang mungkin melebihi memori yang tersedia, gunakan arrow_reader() dengan batch_size yang wajar.
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")
Sesuaikan ukuran batch
Parameter batch_size mengontrol berapa banyak baris yang diambil dalam setiap batch. Ukuran optimal tergantung pada lebar baris dan memori yang tersedia. Baris yang lebih lebar dengan kolom besar seperti nvarchar (max) atau varbinary (max) mendapat manfaat dari ukuran batch yang lebih kecil, sedangkan baris sempit mendapat manfaat dari yang lebih besar.
- Default (8192): Keseimbangan yang baik untuk sebagian besar beban kerja.
- Lebih kecil (1000-5000): Gunakan untuk tabel lebar dengan kolom besar.
- Lebih besar (50000-100000): Gunakan untuk tabel sempit atau ketika throughput lebih penting daripada memori.
# 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)