Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In questo quickstart, usa i metodi Arrow integrati del driver mssql-python per recuperare i dati di SQL Server come tabelle Apache Arrow in formato colonnare. Il formato di memoria colonnare di Arrow consente analisi ad alte prestazioni, interoperabilità zero-copy con pandas, Polars e DuckDB e un I/O efficiente dei file Parquet senza creare oggetti Python riga per riga.
Il mssql-python driver non richiede dipendenze esterne nei computer Windows. Il driver installa tutto ciò di cui ha bisogno con una sola pip installazione, così puoi usare l'ultima versione del driver per nuovi script senza rompere altri script che non hai tempo di aggiornare e testare.
Documentazione di mssql-python | Codice sorgente di mssql-python | Pacchetto (PyPI) | uv
Prerequisiti
Python 3.10 o versione successiva.
Se Python non è già disponibile, installare il runtime Python e la gestione pacchetti pip da python.org.
Non si vuole usare il proprio ambiente? Segui Container e lo sviluppo locale per creare un devcontainer riproducibile o un ambiente di Codespaces su GitHub.
Visual Studio Code con le seguenti estensioni:
- Estensione di Python per Visual Studio Code
Interfaccia Command-Line di Azure per l'autenticazione senza password in macOS e Linux.
Se non hai già
uv, segui le istruzioni di installazione.Un database su SQL Server, un database SQL di Azure o un database SQL in Fabric con lo
AdventureWorks2025schema di esempio e una stringa di connessione valida.
Prerequisiti per installare il sistema operativo
Installare prerequisiti specifici del sistema operativo monouso. Gli utenti Windows possono saltare questo passaggio. Per dettagli completi sulla piattaforma, vedi Installa mssql-python.
Creare un database SQL
Crea o collegati a un database SQL su una delle seguenti piattaforme:
Creare il progetto ed eseguire il codice
- Crea un nuovo progetto
- Aggiungere dipendenze
- Avviare Visual Studio Code
- Aggiornare pyproject.toml
- Aggiornare main.py
- Salvare la stringa di connessione
- Usare uv run per eseguire lo script
Creare un nuovo progetto
Apri un prompt dei comandi nella directory di sviluppo. Se non ne hai una, crea una nuova directory, come
pythonoscripts. Evita le cartelle sul tuo OneDrive, poiché la sincronizzazione può interferire con la gestione del tuo ambiente virtuale.Crea un nuovo progetto usando
uv.uv init arrow-qs cd arrow-qs
Aggiungere dipendenze
Nella stessa directory, installa i pacchetti mssql-python, python-dotenv, pyarrow e rich.
uv add mssql-python python-dotenv pyarrow rich
Avviare Visual Studio Code
Nella stessa directory eseguire il comando seguente.
code .
Aggiornare pyproject.toml
Aprire il file
pyproject.tomlnell'editor. Questo file contiene i metadati del tuo progetto.Esaminare il contenuto del file. Dovrebbe essere simile a questo esempio. Nota la versione Python e la dipendenza da
mssql-pythonusare>=per definire una versione minima. Se si preferisce una versione esatta, cambiare>=prima del numero di versione in==. Le versioni risolte di ogni pacchetto vengono quindi memorizzate nel uv.lock. Il lockfile garantisce che gli sviluppatori che lavorano sul progetto utilizzino versioni coerenti dei pacchetti. Esegui il commit dipyproject.tomleuv.locked esegui in CI uno scanner delle dipendenze approvato dalla tua organizzazione. Non modificare direttamente iluv.lockfile.[project] name = "arrow-qs" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.11" dependencies = [ "mssql-python>=1.16.0", "pyarrow>=19.0.0", "python-dotenv>=1.1.1", "rich>=14.1.0", ]Aggiorna il
descriptionvalore.description = "Fetch SQL Server data as Apache Arrow tables using mssql-python"Salva e chiudi il file.
Aggiornare main.py
Aprire il file denominato
main.py. Dovrebbe essere simile a questo esempio.def main(): print("Hello from arrow-qs!") if __name__ == "__main__": main()Sostituire l'intero contenuto di
main.pycon il codice seguente."""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: """Stream results with arrow_reader() and combine the batches.""" 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() batches = list(reader) cursor.close() if not batches: return pa.table({}) return pa.Table.from_batches(batches) 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. Stream results with cursor.arrow_reader() console.rule("[bold]cursor.arrow_reader() - Reader streaming[/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()
Salvare la stringa di connessione
Aprire il
.gitignorefile e aggiungere un'esclusione per.envi file. Il tuo file dovrebbe essere simile al seguente esempio.# Python-generated files __pycache__/ *.py[oc] build/ dist/ wheels/ *.egg-info # Virtual environments .venv # Connection strings and secrets .env # Generated data files *.parquetSalvare e chiudere
.gitignore.Nella directory corrente creare un nuovo file denominato
.env.All'interno del
.envfile aggiungere una voce per la stringa di connessione denominataSQL_CONNECTION_STRING. Sostituite i segnaposto con i valori effettivi.SQL_CONNECTION_STRING="Server=<server>;Database=<database>;Encrypt=yes;TrustServerCertificate=no;Authentication=ActiveDirectoryInteractive"Importante
Mantieni
.envin locale e fuori dal controllo del codice sorgente. Per gli ambienti CI e di distribuzione, inserisci la stringa di connessione o i segreti che la compongono dall'archivio segreti della piattaforma invece di copiare.envtra macchine.La stringa di connessione dipende dal tipo di database SQL a cui ti stai collegando. Per database SQL di Azure o SQL database in Fabric, usa la stringa di connessione ODBC dalla scheda stringa di connessiones e regola il tipo di autenticazione per il tuo scenario. Per maggiori informazioni sulla sintassi delle stringa di connessione, vedi Connection strings for mssql-python.
Tip
In macOS, entrambi
ActiveDirectoryInteractiveeActiveDirectoryDefaultfunzionano per l'autenticazione di Microsoft Entra.ActiveDirectoryInteractiverichiede di accedere ogni volta che si esegue lo script. Per evitare ripetuti prompt di accesso, accedi una volta con il comando interfaccia della riga di comando di Azureaz logine usaActiveDirectoryDefault.ActiveDirectoryDefaultRiutilizza la credenziale memorizzata.
Usare uv run per eseguire lo script
Nella finestra del terminale precedente o in una nuova finestra del terminale aperta nella stessa directory eseguire il comando seguente.
uv run main.py
Lo script illustra tre metodi di fetch di Arrow:
cursor.arrow()restituisce un completopyarrow.Tablecon tutte le righe. Usalo per set di risultati piccoli o medi dove hai bisogno dell'intero dataset in memoria.cursor.arrow_batch()restituisce unpyarrow.RecordBatchalla volta. Usalo per grandi set di risultati dove vuoi elaborare i dati in modo incrementale senza caricare tutto in memoria.cursor.arrow_reader()restituisce un reader di flusso che produce oggettipyarrow.RecordBatchdurante l'iterazione. Usalo per l’elaborazione in stile pipeline o per passarlo direttamente a librerie che accettano un reader.
Lo script salva anche i dati del prodotto in un file Parquet e li rilegge per verificare il viaggio di andata e ritorno.
Funzionamento del codice
Connessione: Lo script carica la stringa di connessione da un
.envfile e crea una connessione usandomssql_python.connect().Recupero della tabella completa:
cursor.arrow()esegue la query e restituisce l'intero insieme di risultati come unpyarrow.Table. Il driver converte i dati nel suo livello C++ utilizzando l'interfaccia dati Arrow C, bypassando la creazione di oggetti in Python per migliorare le prestazioni.Streaming in batch:
cursor.arrow_batch()ne restituisce unopyarrow.RecordBatchper chiamata. Il ciclo raccoglie blocchi finché non rimangono più righe, poi li unisce in un'unica tabella. Usa questo approccio per grandi dataset o quando vuoi elaborare ogni batch in modo indipendente.Reader di streaming:
cursor.arrow_reader()restituisce un reader che restituisce oggettipyarrow.RecordBatchdurante l'iterazione. Rispetto alarrow_batch()ciclo, il lettore gestisce il proprio stato di iterazione, così non devi testare tu stesso un set di risultati esaurito.Questa funzione legge il flusso fino al completamento e poi chiude il cursore, quindi non è necessario chiudere il lettore. Chiudi il lettore quando smetti di leggere prima e continua a usare il cursore. Per maggiori informazioni, vedi integrazione con Apache Arrow.
I/O Parquet:
pyarrow.parquet.write_table()salva la tabella Arrow in un file Parquet compresso. Questo formato preserva i tipi di colonne e supporta letture parziali efficienti.