Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste guia de início rápido, use os métodos internos de busca do Arrow do driver mssql-python para recuperar dados do SQL Server como tabelas colunares em 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, além de entrada/saída eficiente de arquivos Parquet sem criar objetos Python linha por linha.
O mssql-python driver não requer nenhuma dependência externa em computadores Windows. O driver instala tudo o que precisa com uma única pip instalação, então você pode usar a versão mais recente do driver para novos scripts sem quebrar outros scripts que não tem tempo de atualizar e testar.
Pré-requisitos
Python 3.10 ou posterior
Se você ainda não tiver o Python, instale o runtime do Python e o gerenciador de pacotes pip de python.org.
Não quer usar seu próprio ambiente? Siga o Container e o desenvolvimento local para criar um devcontainer reproduzível ou um ambiente de Codespaces no GitHub.
Visual Studio Code com as seguintes extensões:
- extensão Python para Visual Studio Code
CLI (Interface Command-Line) do Azure para autenticação sem senha no macOS e linux.
Se você ainda não tiver
uv, siga as instruções de instalação.Um banco de dados no SQL Server, no Banco de Dados SQL do Azure ou no Banco de Dados SQL no Fabric com o
AdventureWorks2025esquema de exemplo e uma cadeia de conexão válida.
Instale pré-requisitos específicos do sistema operacional uma vez. Usuários do Windows podem pular essa etapa. Para detalhes completos da plataforma, veja Instalar mssql-python.
Criar um banco de dados SQL
Crie ou conecte-se a um banco de dados SQL em uma das seguintes plataformas:
Criar o projeto e executar o código
- Criar um novo projeto
- Adicionar dependências
- Iniciar Visual Studio Code
- Atualizar pyproject.toml
- Atualizar main.py
- Salvar a cadeia de conexão
- Use o comando uv run para executar o script
Criar um novo projeto
Abra um prompt de comando no diretório de desenvolvimento. Se você não tiver um, crie um novo diretório, como
pythonouscripts. Evite pastas no seu OneDrive, pois a sincronização pode interferir no gerenciamento 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
Iniciar o Visual Studio Code
No mesmo diretório, execute o comando a seguir.
code .
Atualizar pyproject.toml
O arquivo pyproject.toml contém os metadados do seu projeto. Abra o arquivo em seu editor favorito.
Examine o conteúdo do arquivo. Deve ser semelhante a este exemplo. Observe a versão do Python e a dependência 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 armazenadas no uv.lock. O lockfile garante que os desenvolvedores que trabalham no projeto utilizem versões consistentes de pacotes. Faça commit depyproject.tomleuv.locke execute um scanner de dependências aprovado pela organização no CI. Não edite ouv.lockarquivo 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. Salve-o e feche-o 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.No arquivo
.env, adicione uma entrada para sua string 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 controle de versão. Para ambientes de CI e implantação, injete a cadeia de conexão ou os segredos de seus componentes do armazenamento de segredos da sua plataforma, em vez de copiar.envde uma máquina para outra.Tip
A cadeia de conexão que você usa depende muito do tipo de banco de dados SQL ao qual você está se conectando. Se você estiver se conectando a um Banco de Dados SQL do Azure ou a um banco de dados SQL no Fabric, 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 seu cenário. Para obter mais informações sobre cadeias de conexão e sua sintaxe, consulte a referência de sintaxe da cadeia de conexão.
Use o comando uv run para executar o script
Tip
No macOS, tanto ActiveDirectoryInteractive quanto ActiveDirectoryDefault funcionam para autenticação do Microsoft Entra.
ActiveDirectoryInteractive solicita que você faça login toda vez que executar o script. Para evitar repetidos prompts de login, faça login uma vez pela CLI do Azure executando az login, depois use ActiveDirectoryDefault, que reutiliza a credencial em cache.
Na janela do terminal de antes ou em uma nova janela de terminal aberta para o mesmo diretório, execute o comando a seguir.
uv run main.pyO script demonstra três métodos de busca do Arrow:
cursor.arrow()retorna umpyarrow.Tablecompleto com todas as linhas. Ideal para conjuntos de resultados pequenos a médios, onde você precisa do conjunto de dados completo na memória.cursor.arrow_batch()retorna umpyarrow.RecordBatchde cada vez. Ideal para grandes conjuntos de resultados, onde você quer processar dados de forma incremental sem carregar tudo na memória.cursor.arrow_reader()retornapyarrow.RecordBatchReaderpara streaming. Ideal para processamento em estilo pipeline ou para passar diretamente para bibliotecas que aceitam um leitor.
O script também salva os dados do produto em um arquivo Parquet e os lê para verificar a viagem de ida e volta.
Como o código funciona
Conexão: O script carrega a cadeia de conexão a partir de um
.envarquivo e cria uma conexão usandomssql_python.connect().Busca de tabela cheia:
cursor.arrow()executa a consulta e retorna todo o conjunto de resultados como umpyarrow.Table. O driver converte dados em sua camada C++ usando a Interface de Dados Arrow C, pulando a criação de objetos em Python para melhorar o desempenho.Transmissão em lote:
cursor.arrow_batch()retorna umpyarrow.RecordBatchpor chamada. O loop coleta lotes até que não restem mais linhas, depois os combina em uma única tabela. Use essa abordagem para grandes conjuntos de dados ou quando quiser processar cada lote de forma independente.RecordBatchReader:
cursor.arrow_reader()retorna umpyarrow.RecordBatchReader, uma interface padrão do Arrow que muitas bibliotecas aceitam diretamente. Chamarreader.read_all()consome todo o fluxo em uma tabela.I/O de Parquet:
pyarrow.parquet.write_table()salva a tabela Arrow em um arquivo Parquet comprimido. Esse formato preserva os tipos de colunas e suporta leituras parciais eficientes.
Próximas Etapas
Use estes artigos para continuar construindo:
- Integração com Arrow para padrões avançados do Arrow, incluindo processamento em lote, gerenciamento de memória e interoperabilidade de bibliotecas.
- Integração com pandas para carregar os resultados das consultas diretamente no DataFrame.
- Integração com Polars para criar DataFrames do Polars a partir de consultas nativas em Arrow.