Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste guia de início rápido, utilize os métodos incorporados de obtenção do Arrow do controlador mssql-python para recuperar dados do SQL Server na forma de tabelas colunares do Apache Arrow. O formato de memória colunar do Arrow permite análises de alto desempenho, interoperabilidade sem cópia com pandas, Polars e DuckDB, e entrada/saída eficiente de ficheiros Parquet sem criar objetos Python linha a linha.
O mssql-python driver não requer nenhuma dependência externa em máquinas Windows. O driver instala tudo o que precisa com uma única pip instalação, por isso podes usar a versão mais recente do driver para novos scripts sem estragar outros scripts que não tens tempo de atualizar e testar.
Documentação | Código-fonte | Pacote (PyPI) | UV
Pré-requisitos
Python 3.10 ou posterior
Se ainda não tens o Python, instala o runtime do Python e o gestor de pacotes pip a partir de python.org.
Não quer usar o seu próprio ambiente? Consulte Container and local development para criar um ambiente devcontainer reproduzível ou um ambiente do GitHub Codespaces.
Visual Studio Code com as seguintes extensões:
Azure Command-Line Interface (CLI) para autenticação sem palavra-passe no macOS e Linux.
Se ainda não tiver
uv, siga as instruções de instalação.Um banco de dados no SQL Server, Banco de Dados SQL do Azure ou Banco de Dados SQL no Fabric com o
AdventureWorks2025esquema de exemplo e uma cadeia de conexão válida.
Instale pré-requisitos que devem ser instalados uma única vez específicos do sistema operacional. Os utilizadores do Windows podem saltar este passo. Para detalhes completos da plataforma, consulte Instalar mssql-python.
Criar um banco de dados SQL
Criar ou ligar-se a uma base de dados SQL numa das seguintes plataformas:
Crie o projeto e execute o código
- Criar um novo projeto
- Adicionar dependências
- Iniciar o Visual Studio Code
- Atualizar pyproject.toml
- Atualizar main.py
- Salvar a cadeia de conexão
- Use uv run para executar o script
Criar um novo projeto
Abra um prompt de comando no diretório de desenvolvimento. Se não tiver um, crie um novo diretório, como
pythonouscripts. Evite pastas no seu OneDrive, pois a sincronização pode interferir na gestão do seu ambiente virtual.Crie um novo projeto usando
uv.uv init arrow-qs cd arrow-qs
Adicionar dependências
No mesmo diretório, instale os pacotes mssql-python, python-dotenv, pyarrow e rich.
uv add mssql-python python-dotenv pyarrow rich
Abra o Visual Studio Code.
No mesmo diretório, execute o seguinte comando.
code .
Atualizar pyproject.toml
O ficheiro pyproject.toml contém os metadados do seu projeto. Abra o arquivo em seu editor favorito.
Revise o conteúdo do arquivo. Deve ser semelhante a este exemplo. Tenha em atenção a versão e a dependência do Python; para
mssql-python, use>=para definir uma versão mínima. Se preferir uma versão exata, altere o>=para==antes do número da versão. As versões resolvidas de cada pacote são então armazenadas no uv.lock. O ficheiro de bloqueio garante que os programadores que trabalham no projeto utilizam versões consistentes dos pacotes. Registe ambospyproject.tomleuv.locke execute um analisador de dependências aprovado pela organização em CI. Não edites ouv.lockficheiro diretamente.[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", ]Atualize a descrição para ser mais descritiva.
description = "Fetch SQL Server data as Apache Arrow tables using mssql-python"Salve e feche o arquivo.
Atualizar main.py
Abra o arquivo chamado
main.py. Deve ser semelhante a este exemplo.def main(): print("Hello from arrow-qs!") if __name__ == "__main__": main()Substitua todo o conteúdo de
main.pypelo seguinte código."""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()
Salvar a cadeia de conexão
Abra o
.gitignorearquivo e adicione uma exclusão para.envarquivos. Seu arquivo deve ser semelhante a este exemplo. Certifique-se de salvá-lo e fechá-lo quando terminar.# Python-generated files __pycache__/ *.py[oc] build/ dist/ wheels/ *.egg-info # Virtual environments .venv # Connection strings and secrets .env # Generated data files *.parquetNo diretório atual, crie um novo arquivo chamado
.env.Dentro do
.envarquivo, adicione uma entrada para sua cadeia de conexão chamadaSQL_CONNECTION_STRING. Substitua o exemplo aqui pelo valor real da cadeia de conexão.SQL_CONNECTION_STRING="Server=<server_name>;Database=<database_name>;Encrypt=yes;TrustServerCertificate=no;Authentication=ActiveDirectoryInteractive"Importante
Mantenha
.envlocalmente e fora do controlo de código-fonte. Para CI e ambientes de implementação, injete a cadeia de ligação ou os segredos que a compõem a partir do repositório de segredos da sua plataforma, em vez de copiar.envde uma máquina para outra.Sugestão
A cadeia de ligação que usas depende em grande parte do tipo de base de dados SQL a que te estás a ligar. Se você estiver se conectando a um Banco de Dados SQL do Azure ou a um banco de dados SQL na Malha, use a cadeia de conexão ODBC na guia Cadeias de conexão. Talvez seja necessário ajustar o tipo de autenticação dependendo do cenário. Para obter mais informações sobre cadeias de conexão e sua sintaxe, consulte Referência de sintaxe de cadeia de conexão.
Use uv run para executar o script
Sugestão
No macOS, tanto ActiveDirectoryInteractive como ActiveDirectoryDefault funcionam para a autenticação do Microsoft Entra.
ActiveDirectoryInteractive Solicita-te para iniciar sessão sempre que executas o script. Para evitar pedidos repetidos para iniciar sessão, inicie sessão uma vez através da CLI do Azure ao executar az login, e depois utilize ActiveDirectoryDefault, que reutiliza a credencial em cache.
Na janela do terminal anterior ou em uma nova janela do terminal aberta no mesmo diretório, execute o seguinte comando.
uv run main.pyO script demonstra três métodos de obtenção do Arrow:
cursor.arrow()devolve umpyarrow.Tablecompleto com todas as linhas. É melhor para conjuntos de resultados pequenos a médios onde precisas do conjunto de dados completo na memória.cursor.arrow_batch()devolve umpyarrow.RecordBatchde cada vez. É ideal para grandes conjuntos de resultados, onde se quer processar dados de forma incremental sem carregar tudo na memória.cursor.arrow_reader()devolve umpyarrow.RecordBatchReaderpara transmissão em fluxo. Mais indicado para processamento em pipeline ou para ser passado diretamente a bibliotecas que aceitam um leitor.
O script também guarda os dados do produto num ficheiro Parquet e lê-los para verificar a viagem de ida e volta.
Como funciona o código
Ligação: O script carrega a cadeia de ligação a partir de um
.envficheiro e cria uma ligação usandomssql_python.connect().Busca da tabela completa:
cursor.arrow()executa a consulta e devolve todo o conjunto de resultados como umpyarrow.Table. O driver converte dados na sua camada C++ usando a Arrow C Data Interface, contornando a criação de objetos em Python para melhorar o desempenho.Transmissão em lote:
cursor.arrow_batch()retorna umpyarrow.RecordBatchpor chamada. O ciclo recolhe lotes até não restar mais linhas, depois junta-os numa única tabela. Use esta abordagem para conjuntos de dados grandes ou quando quiser processar cada lote de forma independente.RecordBatchReader:
cursor.arrow_reader()devolve umpyarrow.RecordBatchReader, uma interface Arrow padrão que muitas bibliotecas aceitam diretamente. A chamadareader.read_all()consome todo o fluxo numa tabela.Parquet I/O:
pyarrow.parquet.write_table()guarda a tabela Arrow num ficheiro Parquet comprimido. Este formato preserva os tipos de colunas e suporta leituras parciais eficientes.
Passos seguintes
Use estes artigos para continuar a construir:
- Integração Arrow para padrões Arrow avançados, incluindo processamento em lote, gestão de memória e interoperabilidade de bibliotecas.
- integração com pandas para carregar os resultados das consultas diretamente em DataFrames.
- Integração com o Polars para criar DataFrames do Polars a partir de consultas nativas de Arrow.