Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le pilote mssql-python fournit des méthodes de récupération Apache Arrow pour la récupération de données columnaires haute performance depuis Microsoft SQL et Azure SQL Database.
Apache Arrow est une plateforme de développement multi-langages pour les données en colonnes en mémoire. Le pilote convertit directement les ensembles de résultats ODBC en format Arrow en C++, contournant la création d’objets Python pour améliorer les performances.
L’intégration de Arrow permet :
- Transfert de données sans copie vers Polars, pandas et DuckDB. « Zero-copy » signifie que les données restent dans un seul tampon mémoire que le pilote écrit et que les bibliothèques consommantes lisent directement, de sorte qu’aucune ligne n’est dupliquée en objets Python intermédiaires.
- Le résultat de streaming passe
RecordBatchReadersans tout charger en mémoire. - Format de données en colonnes idéal pour les charges de travail analytiques et d’apprentissage automatique.
- Réduction de la consommation de mémoire par rapport à la création d’objets Python ligne par ligne.
Méthodes de Curseur
Le pyarrow package doit utiliser des méthodes de récupération Arrow. Installez-le avec pip install pyarrow. Si pyarrow n’est pas installé, appeler n’importe quelle méthode Arrow génère un ImportError.
Le pilote mssql-python ajoute trois méthodes à l’objet curseur pour l’accès aux données Arrow. Les trois méthodes convertissent les ensembles de résultats ODBC au format Arrow dans la couche C++ du pilote, ce qui évite de créer des objets Python intermédiaires.
-
arrow()renvoie l’ensemble des résultats sous forme d’une seule table en mémoire. Les plus simples à utiliser. -
arrow_batch()renvoie un lot de lignes à la fois, vous donnant le contrôle manuel de la boucle. -
arrow_reader()renvoie un itérateur qui génère automatiquement des lots. Idéal pour diffuser de gros résultats.
Utilisation de cursor.arrow(batch_size=8192)
Récupérez l’ensemble des résultats comme un seul pyarrow.Table. Cette méthode est la plus simple et fonctionne bien lorsque l’ensemble complet des résultats tient en mémoire.
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
Si votre chaîne de connexion utilise Authentication=ActiveDirectoryDefault, le pilote utilise DefaultAzureCredential, ce qui essaie plusieurs fournisseurs d’identifiants en séquence. La première connexion peut être lente car le SDK parcourt la chaîne jusqu’à ce qu’il trouve un fournisseur fonctionnel. En production, si vous savez quel type d’identifiant votre environnement utilise, spécifiez-le directement (par exemple, ActiveDirectoryMSI pour l’identité gérée) afin d’éviter la marche en chaîne. Pour plus d’informations, consultez Authentification Microsoft Entra.
Utilisation de cursor.arrow_batch(batch_size=8192)
Récupérez un seul pyarrow.RecordBatch contenant jusqu’à batch_size lignes. Utilisez cette méthode pour des boucles de traitement batch personnalisées où vous avez besoin d’un contrôle précis sur le nombre de lignes récupérées à la fois.
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")
Utilisation de cursor.arrow_reader(batch_size=8192)
Retourner un pyarrow.RecordBatchReader qui renvoie des objets RecordBatch jusqu’à épuisement du jeu de résultats. Cette méthode est l’option la plus efficace en mémoire pour les grands ensembles de résultats.
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")
Modèles courants
Les tables de flèches s’intègrent directement avec les bibliothèques de données Python populaires. Les exemples suivants montrent comment transmettre les données Arrow aux pandas, Polars, DuckDB et formats de fichiers sans copier les données.
Charger les résultats dans pandas
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
# Convert to pandas with zero-copy where possible
df = table.to_pandas()
print(df.head())
Charger les résultats dans Polars
import polars as pl
cursor.execute("SELECT * FROM Production.Product")
table = cursor.arrow()
df = pl.from_arrow(table)
print(df)
Résultats de requêtes avec DuckDB
DuckDB peut interroger directement les tables de flèches en SQL sans copier les données. Cette fonctionnalité est utile lorsque vous avez besoin d’une analyse de type SQL sur des ensembles de résultats déjà au format Arrow.
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())
Exporter en flux des jeux de résultats volumineux vers Parquet
Pour de grands ensembles de résultats, diffusez des lots Arrow directement vers un fichier Parquet sans charger l’ensemble de données en mémoire. Le ParquetWriter écrit chaque lot de façon incrémentale.
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()
Exportation vers d’autres formats
PyArrow fournit des graveurs intégrés pour CSV et le format de fichier IPC Arrow (également connu sous le nom de Feather V2). Les fichiers Arrow IPC conservent exactement les types Arrow et peuvent être relus rapidement.
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)
Mappages de types de données
Les méthodes de récupération Arrow associent les types SQL Microsoft aux types Arrow au niveau C++.
| type SQL Microsoft | Type de flèche |
|---|---|
| int, smallint, tinyint, bigint |
int32, int16, int8, int64 |
| flottant, réel |
float64, float32 |
| décimal, numérique | decimal128 |
| bit | bool |
| Char, Varchar, Nchar, Nvarchar | utf8 |
| Texte, Ntext | large_utf8 |
| binaire, varbinaire |
binary, large_binary |
| date | date32 |
| time | time64[us] |
| datetime, datetime2, smalldatetime | timestamp[us] |
| datetimeoffset | timestamp[us, tz=UTC] |
| uniqueidentifier |
utf8 (corde majuscule) |
| xml | utf8 |
Note
Le pilote convertit le datetimeoffset type en UTC car les colonnes Arrow nécessitent un fuseau horaire fixe. Le pilote normalise les informations de fuseau horaire pour chaque cellule de Microsoft SQL en UTC lors de la conversion.
Ce sql_variant type n’est pas pris en charge par les méthodes Arrow Fetch et génère une exception de type de données non prise en charge. Utilisez la valeur standard fetchone(), fetchmany() ou fetchall() pour les requêtes qui renvoient sql_variant colonnes.
Considérations relatives aux performances
Les méthodes de récupération de flèches sont les plus rapides pour l’analytique et les opérations de données en masse, tandis que les méthodes de curseur standard conviennent mieux aux modèles transactionnels avec de petits ensembles de résultats.
Quand utiliser Arrow ou la récupération standard
| Scénario | Approche recommandée |
|---|---|
| Récupérez quelques rangées pour les afficher | fetchone() / fetchall() |
| Charger les données dans les pandas ou les Polar | cursor.arrow() |
| Traiter de grands ensembles de données par blocs | cursor.arrow_reader() |
| Recherches à une seule ligne ou petits ensembles de résultats | fetchone() / fetchval() |
| Analyse ou pipelines d’agrégation |
cursor.arrow() + Polars/DuckDB |
| Écrire les résultats sur Parquet ou Arrow IPC |
cursor.arrow_reader() + PyArrow E/S |
Gestion de la mémoire pour de grands ensembles de données
Pour les jeux de résultats susceptibles de dépasser la mémoire disponible, utilisez arrow_reader() avec un batch_size raisonnable.
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")
Ajuster la taille du lot
Le batch_size paramètre contrôle combien de lignes sont récupérées dans chaque lot. La taille optimale dépend de la largeur de votre ligne et de la mémoire disponible. Les rangées plus larges avec de grandes colonnes comme nvarchar(max) ou varbinary(max) bénéficient de tailles de lots plus petites, tandis que les rangées étroites bénéficient de plus grandes.
- Par défaut (8192) : Bon équilibre pour la plupart des charges de travail.
- Plus petits (1000-5000) : À utiliser pour de larges tables avec de grandes colonnes.
- Plus grand (50000-100000) : Utilisation pour des tables étroites ou lorsque le débit compte plus que la mémoire.
# 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)