PySpark a toujours fourni d'excellentes API SQL et Python pour l'interrogation des données. Depuis Databricks Runtime 15.2 et Apache Spark 4.0, les requêtes paramétrées prennent en charge des moyens sûrs et expressifs d'interroger des données avec SQL en utilisant des paradigmes de programmation Pythoniques.
Cet article explique comment créer des requêtes paramétrées avec PySpark et quand il s'agit d'un bon modèle de conception pour votre code.
Les paramètres aident à rendre votre code Spark plus facile à réutiliser et à tester. Ils encouragent également les bonnes pratiques de codage. Cet article présentera deux manières différentes de paramétrer les requêtes PySpark :
Examinons comment utiliser les deux types de requêtes paramétrées PySpark et pourquoi la fonctionnalité intégrée est meilleure que d'autres alternatives.
Les requêtes paramétrées encouragent le modèle « ne vous répétez pas » (DRY), facilitent les tests unitaires et rendent le SQL plus facile à réutiliser. Elles protègent également contre les attaques par injection SQL, qui peuvent présenter des vulnérabilités de sécurité.
Il peut être tentant de copier-coller de grands blocs de SQL lors de l'écriture de requêtes similaires. Les requêtes paramétrées encouragent l'abstraction des modèles et l'écriture de code selon le modèle DRY.
Les requêtes paramétrées sont également plus faciles à tester. Vous pouvez paramétrer une requête pour qu'elle soit facile à exécuter sur des jeux de données de production et de test.
En revanche, paramétrer manuellement les requêtes SQL avec des f-strings Python est une mauvaise alternative. Considérez les inconvénients suivants :
Examinons comment paramétrer les requêtes avec des marqueurs de paramètres, qui protègent votre code contre les vulnérabilités d'injection SQL et prennent en charge la conversion automatique de type des instances PySpark courantes au format chaîne.
Supposons que vous ayez la table de données suivante appelée h20_1e9 avec neuf colonnes :
Vous souhaitez paramétrer la requête SQL suivante :
Vous souhaitez faciliter l'exécution de cette requête avec différentes valeurs de id1. Voici comment paramétrer et exécuter la requête avec différentes valeurs de id1.
Réexécutez maintenant la requête avec un autre argument :
Le formateur de chaînes PySpark vous permet également d'exécuter des requêtes SQL directement sur un DataFrame sans définir explicitement de vues temporaires.
Supposons que vous ayez le DataFrame suivant appelé person_df :
Voici comment interroger le DataFrame avec SQL.
Exécuter des requêtes sur un DataFrame en utilisant la syntaxe SQL sans avoir à enregistrer manuellement une vue temporaire est très pratique !
Voyons maintenant comment paramétrer les requêtes avec des arguments dans des marqueurs de paramètres.
Vous pouvez également utiliser un dictionnaire d'arguments pour formuler une requête SQL paramétrée avec des marqueurs de paramètres.
Supposons que vous ayez la vue suivante nommée some_purchases :
Voici comment créer une requête paramétrée avec des marqueurs de paramètres nommés pour calculer le montant total dépensé pour un article donné.
Calculez le montant total dépensé pour les chaussettes.
Vous pouvez également paramétrer des requêtes avec des marqueurs de paramètres non nommés ; consultez ici pour plus d'informations.
Apache Spark assainit les marqueurs de paramètres, cette approche de paramétrisation vous protège donc également contre les attaques par injection SQL.
Voici une description générale de la manière dont Spark assainit les requêtes paramétrées nommées :
Comme mentionné précédemment, il existe deux types de requêtes paramétrées prises en charge dans PySpark :
La syntaxe {} effectue une substitution de chaîne sur la requête SQL côté client pour plus de facilité d'utilisation et une meilleure programmabilité. Cependant, elle ne protège pas contre les attaques par injection SQL car le texte de la requête est substitué avant d'être envoyé au serveur Spark.
Le paramétrage utilise l'argument args de l'API sql() et transmet le texte SQL et les paramètres séparément au serveur. Le texte SQL est analysé avec les espaces réservés aux paramètres, substituant les valeurs des paramètres spécifiés dans args dans l'arbre de requête analysé.
Il existe deux variantes de requêtes paramétrées côté serveur : les marqueurs de paramètres nommés et les marqueurs de paramètres non nommés. Les marqueurs de paramètres nommés utilisent la syntaxe :<nom_param> pour les espaces réservés. Consultez la documentation pour plus d'informations sur l'utilisation des marqueurs de paramètres non nommés.
Vous pouvez également utiliser l'interpolation de chaînes Python standard pour paramétrer des requêtes, mais ce n'est pas aussi pratique.
Voici comment nous devrions paramétrer notre requête précédente avec des f-strings Python :
Ce n'est pas aussi pratique pour les raisons suivantes :
En résumé, les capacités de paramétrage de requêtes intégrées sont plus sûres et plus efficaces que l'interpolation de chaînes.
Les requêtes paramétrées PySpark vous offrent de nouvelles capacités pour écrire du code propre avec une syntaxe SQL familière. Elles sont pratiques lorsque vous souhaitez interroger un DataFrame Spark avec SQL. Elles vous permettent d'utiliser des types de données Python courants tels que les nombres à virgule flottante, les chaînes de caractères, les dates et les dates-heures, qui sont automatiquement convertis en valeurs SQL en arrière-plan. De cette façon, vous pouvez désormais exploiter les idiomes Python courants et écrire du code élégant.
Commencez à exploiter les requêtes paramétrées PySpark dès aujourd'hui, et vous profiterez immédiatement des avantages d'une base de code de meilleure qualité.
Cette fonctionnalité est officiellement prise en charge à partir de DBR 15.2.
(Cet article de blog a été traduit à l'aide d'outils basés sur l'intelligence artificielle) Article original
