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.
Dalam panduan singkat ini, gunakan metode pengambilan Arrow bawaan driver mssql-python untuk mengambil data SQL Server sebagai tabel Apache Arrow berformat kolom. Format memori berbasis kolom dari Arrow memungkinkan analitik berkinerja tinggi, interoperabilitas tanpa penyalinan data dengan pandas, Polars, dan DuckDB, serta I/O file Parquet yang efisien tanpa perlu membuat objek Python untuk setiap baris.
Driver mssql-python tidak memerlukan dependensi eksternal apa pun pada komputer Windows. Driver menginstal semua yang dibutuhkannya dengan satu pip instalasi, sehingga Anda dapat menggunakan driver versi terbaru untuk skrip baru tanpa merusak skrip lain yang tidak sempat Anda tingkatkan dan uji.
dokumentasi mssql-python
Prasyarat
Python 3.10 atau yang lebih baru
Jika Anda belum memiliki Python, instal runtime Python dan manajer paket pip dari python.org.
Tidak ingin menggunakan lingkungan Anda sendiri? Ikuti Kontainer dan pengembangan lokal untuk membuat lingkungan devcontainer atau GitHub Codespaces yang dapat direproduksi.
Visual Studio Code dengan ekstensi berikut:
Azure Command-Line Interface (CLI) untuk autentikasi tanpa kata sandi di macOS dan Linux.
Jika Anda belum memiliki
uv, ikuti instruksi penginstalan.Database di SQL Server, Azure SQL Database, atau database SQL di Fabric dengan
AdventureWorks2025skema sampel dan string koneksi yang valid.
Instal prasyarat khusus sistem operasi satu kali. Pengguna Windows dapat melewati langkah ini. Untuk detail platform lengkap, lihat Menginstal mssql-python.
Membuat database SQL
Buat atau sambungkan ke database SQL di salah satu platform berikut:
Membuat proyek dan menjalankan kode
- Membuat proyek baru
- Menambahkan dependensi
- Luncurkan Visual Studio Code
- Memperbarui pyproject.toml
- Memperbarui main.py
- Simpan string koneksi
- Menggunakan uv run untuk menjalankan skrip
Membuat proyek baru
Buka jendela perintah di direktori pengembangan Anda. Jika Anda tidak memilikinya, buat direktori baru, seperti
pythonatauscripts. Hindari folder di OneDrive Anda, karena sinkronisasi dapat mengganggu pengelolaan lingkungan virtual Anda.Membuat proyek baru dengan menggunakan
uv.uv init arrow-qs cd arrow-qs
Tambah dependensi
Di direktori yang sama, instal mssql-pythonpaket , python-dotenv, pyarrow, dan rich .
uv add mssql-python python-dotenv pyarrow rich
Luncurkan Visual Studio Code
Di direktori yang sama, jalankan perintah berikut.
code .
Memperbarui pyproject.toml
File pyproject.toml berisi metadata untuk proyek Anda. Buka file di editor favorit Anda.
Tinjau isi dari file tersebut. Ini harus mirip dengan contoh ini. Perhatikan versi Python dan dependensi; untuk
mssql-python, gunakan>=guna menentukan versi minimum. Jika Anda lebih suka versi yang tepat, ubah>=sebelum nomor versi menjadi==. Versi yang diselesaikan dari setiap paket kemudian disimpan di uv.lock. Lockfile memastikan bahwa pengembang yang mengerjakan proyek menggunakan versi paket yang konsisten. Terapkan keduapyproject.tomldanuv.lock, dan jalankan pemindai dependensi yang disetujui organisasi di CI. Jangan mengedituv.lockfile secara langsung.[project] name = "arrow-qs" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.11" dependencies = [ "mssql-python>=1.5.0", "pyarrow>=19.0.0", "python-dotenv>=1.1.1", "rich>=14.1.0", ]Perbarui deskripsi agar lebih deskriptif.
description = "Fetch SQL Server data as Apache Arrow tables using mssql-python"Simpan dan tutup file.
Memperbarui main.py
Buka file bernama
main.py. Ini harus mirip dengan contoh ini.def main(): print("Hello from arrow-qs!") if __name__ == "__main__": main()Ganti seluruh konten
main.pydengan kode berikut."""Fetch SQL Server data as Apache Arrow tables using mssql-python.""" from os import getenv import pyarrow as pa import pyarrow.parquet as pq from dotenv import load_dotenv from mssql_python import connect, Connection from rich.console import Console from rich.table import Table console = Console() def get_connection() -> Connection: """Create a connection using the connection string from .env.""" load_dotenv() conn_str = getenv("SQL_CONNECTION_STRING") if not conn_str: raise ValueError("SQL_CONNECTION_STRING not set in .env file") return connect(conn_str) def fetch_arrow_table(conn: Connection) -> pa.Table: """Run a query and return the full result as an Arrow Table.""" cursor = conn.cursor() cursor.execute(""" SELECT p.ProductID, p.Name, p.ProductNumber, p.Color, p.StandardCost, p.ListPrice, p.Size, p.Weight, p.SellStartDate, pc.Name AS Category FROM SalesLT.Product AS p INNER JOIN SalesLT.ProductCategory AS pc ON p.ProductCategoryID = pc.ProductCategoryID ORDER BY p.ListPrice DESC """) arrow_table = cursor.arrow() cursor.close() return arrow_table def fetch_arrow_batches(conn: Connection) -> pa.Table: """Stream results one batch at a time using arrow_batch().""" cursor = conn.cursor() cursor.execute(""" SELECT c.CustomerID, c.CompanyName, c.EmailAddress, COUNT(soh.SalesOrderID) AS OrderCount, SUM(soh.SubTotal + soh.TaxAmt + soh.Freight) AS TotalSpent FROM SalesLT.Customer AS c LEFT OUTER JOIN SalesLT.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID GROUP BY c.CustomerID, c.CompanyName, c.EmailAddress ORDER BY TotalSpent DESC """) batches = [] while True: batch = cursor.arrow_batch() if batch is None or batch.num_rows == 0: break batches.append(batch) cursor.close() if not batches: return pa.table({}) return pa.Table.from_batches(batches) def fetch_with_reader(conn: Connection) -> pa.Table: """Use arrow_reader() to stream results as a RecordBatchReader.""" cursor = conn.cursor() cursor.execute(""" SELECT soh.SalesOrderID, soh.OrderDate, (soh.SubTotal + soh.TaxAmt + soh.Freight) AS TotalDue, c.CompanyName FROM SalesLT.SalesOrderHeader AS soh INNER JOIN SalesLT.Customer AS c ON soh.CustomerID = c.CustomerID ORDER BY soh.OrderDate DESC """) reader = cursor.arrow_reader() arrow_table = reader.read_all() cursor.close() return arrow_table def display_arrow_table(arrow_table: pa.Table, title: str, max_rows: int = 10) -> None: """Display an Arrow table using rich formatting.""" rich_table = Table(title=title) for name in arrow_table.column_names: rich_table.add_column(name, style="bright_white") for i in range(min(max_rows, arrow_table.num_rows)): row = [str(arrow_table.column(col)[i].as_py()) for col in range(arrow_table.num_columns)] rich_table.add_row(*row) if arrow_table.num_rows > max_rows: rich_table.add_row(*[f"... ({arrow_table.num_rows - max_rows} more rows)" if col == 0 else "" for col in range(arrow_table.num_columns)]) console.print(rich_table) console.print(f"\n[dim]Schema: {arrow_table.num_columns} columns, {arrow_table.num_rows} rows[/dim]\n") def save_to_parquet(arrow_table: pa.Table, file_path: str) -> None: """Save an Arrow table to a Parquet file.""" pq.write_table(arrow_table, file_path) console.print(f"[green]Saved {arrow_table.num_rows} rows to {file_path}[/green]\n") def main() -> None: conn = get_connection() # 1. Fetch entire result as an Arrow Table with cursor.arrow() console.rule("[bold]cursor.arrow() - Full table fetch[/bold]") products = fetch_arrow_table(conn) display_arrow_table(products, "Products (Top 10 by List Price)") # 2. Stream results in batches with cursor.arrow_batch() console.rule("[bold]cursor.arrow_batch() - Batch streaming[/bold]") customers = fetch_arrow_batches(conn) display_arrow_table(customers, "Customers by Total Spent") # 3. Use RecordBatchReader with cursor.arrow_reader() console.rule("[bold]cursor.arrow_reader() - RecordBatchReader[/bold]") orders = fetch_with_reader(conn) display_arrow_table(orders, "Recent Orders") # 4. Save to Parquet console.rule("[bold]Save to Parquet[/bold]") save_to_parquet(products, "products.parquet") # 5. Read back from Parquet and verify loaded = pq.read_table("products.parquet") console.print(f"[green]Read back {loaded.num_rows} rows from products.parquet[/green]") console.print(f"[dim]Schema: {loaded.schema}[/dim]\n") conn.close() if __name__ == "__main__": main()
Simpan string koneksi
.gitignoreBuka file dan tambahkan pengecualian untuk.envfile. File Anda harus mirip dengan contoh ini. Pastikan untuk menyimpan dan menutupnya setelah selesai.# Python-generated files __pycache__/ *.py[oc] build/ dist/ wheels/ *.egg-info # Virtual environments .venv # Connection strings and secrets .env # Generated data files *.parquetDi direktori saat ini, buat file baru bernama
.env.Di dalam file
.env, tambahkan entri untuk string koneksi Anda yang bernamaSQL_CONNECTION_STRING. Ganti contoh di sini dengan nilai string koneksi Anda yang sebenarnya.SQL_CONNECTION_STRING="Server=<server_name>;Database=<database_name>;Encrypt=yes;TrustServerCertificate=no;Authentication=ActiveDirectoryInteractive"Penting
Jaga
.envlokal dan di luar kendali sumber. Untuk CI dan lingkungan yang disebarkan, injeksikan string koneksi atau rahasia komponennya dari penyimpanan rahasia platform Anda alih-alih menyalin.envantar mesin.Tip
string koneksi yang Anda gunakan sangat bergantung pada jenis database SQL yang Anda sambungkan. Jika Anda menyambungkan ke Azure SQL Database atau database SQL di Fabric, gunakan string koneksi ODBC dari tab string koneksi. Anda mungkin perlu menyesuaikan jenis autentikasi tergantung pada skenario Anda. Untuk informasi selengkapnya tentang string koneksi dan sintaksnya, lihat referensi sintaks string koneksi.
Menggunakan uv run untuk menjalankan skrip
Tip
Di macOS, baik ActiveDirectoryInteractive dan ActiveDirectoryDefault berfungsi untuk autentikasi Microsoft Entra.
ActiveDirectoryInteractive meminta Anda untuk masuk setiap kali Anda menjalankan skrip. Untuk menghindari permintaan masuk berulang, masuk sekali melalui Azure CLI dengan menjalankan az login, lalu gunakan ActiveDirectoryDefault, yang menggunakan kembali kredensial yang di-cache.
Di jendela terminal dari sebelumnya, atau jendela terminal baru terbuka ke direktori yang sama, jalankan perintah berikut.
uv run main.pySkrip menunjukkan tiga metode pengambilan data Arrow:
cursor.arrow()mengembalikanpyarrow.Tablelengkap dengan semua baris. Terbaik untuk kumpulan hasil kecil hingga menengah di mana Anda memerlukan himpunan data lengkap dalam memori.cursor.arrow_batch()mengembalikanpyarrow.RecordBatchsatu per satu. Terbaik untuk kumpulan hasil besar di mana Anda ingin memproses data secara bertahap tanpa memuat semuanya ke dalam memori.cursor.arrow_reader()mengembalikan sebuahpyarrow.RecordBatchReaderuntuk streaming. Terbaik untuk pemrosesan gaya alur atau meneruskan langsung ke pustaka yang menerima pembaca.
Skrip juga menyimpan data produk ke file Parquet dan membacanya kembali untuk memverifikasi perjalanan pulang-pergi.
Cara kerja kode
Koneksi: Skrip memuat string koneksi dari file
.envdan membuat koneksi menggunakanmssql_python.connect().Pengambilan tabel penuh:
cursor.arrow()menjalankan kueri dan mengembalikan seluruh kumpulan hasil sebagai .pyarrow.TableDriver mengonversi data di lapisan C++ menggunakan Arrow C Data Interface, tanpa membuat objek Python untuk meningkatkan kinerja.Batch streaming:
cursor.arrow_batch()mengembalikan satupyarrow.RecordBatchsetiap panggilan. Loop mengumpulkan batch hingga tidak ada lagi baris yang tersisa, lalu menggabungkannya menjadi satu tabel. Gunakan pendekatan ini untuk himpunan data besar atau saat Anda ingin memproses setiap batch secara independen.RecordBatchReader:
cursor.arrow_reader()mengembalikan sebuahpyarrow.RecordBatchReader, antarmuka Arrow standar yang dapat langsung diterima oleh banyak pustaka. Memanggilreader.read_all()akan membaca seluruh stream dan mengubahnya menjadi tabel.Parquet I/O:
pyarrow.parquet.write_table()menyimpan tabel Arrow sebagai file Parquet terkompresi. Format ini mempertahankan jenis kolom dan mendukung pembacaan parsial yang efisien.
Langkah berikutnya
Gunakan artikel ini untuk terus membangun:
- Integrasi Arrow untuk pola Arrow tingkat lanjut yang mencakup pemrosesan batch, pengelolaan memori, dan interoperabilitas pustaka.
- integrasi pandas untuk memuat hasil kueri langsung ke DataFrames.
- Integrasi Polars untuk membangun Polars DataFrames dari kueri asli Arrow.