Lisez notre article sur

.

Dans le cadre de leurs activités quotidiennes, les analystes Data Engineer et Data sont amenés à améliorer les processus d'ingestion data. Au-delà des tests unitaires habituels, il peut être intéressant de comparer facilement et rapidement deux ensembles data (c'est-à-dire des tables, des vues, des requêtes, etc.) à des fins différentes, telles que l'analyse d'impact ou les tests de non-régression. De même, l'identification des divergences entre deux points de vue d'une table instantanée est très utile pour l'analyse adhoc ou le débogage.

Dans cette optique et pour les praticiens de SQL, un script préconstruit et réutilisable prend tout son sens, d'où l'objet de cet article.

Explication du modèle SQL prêt à l'emploi

Entrons dans le vif du sujet avec la question attendue :

Image

Expliquons-le maintenant :

  • Tout d'abord, nous utilisons CTE - Common Table Expressions (WITH ... ASstatements) pour identifier les deux ensembles data à comparer. Ainsi, les lignes de requête suivantes peuvent rester inchangées.

  • Ensuite, nous construisons deux requêtes similaires appelées dataset_1_only et dataset_2_only afin de conserver les lignes qui ne sont présentes que dans dataset 1 (par rapport à dataset 2) et vice-versa grâce à l'opérateur EXCEPT set.

  • Enfin, un champ complémentaire "flag" est défini afin d'identifier la source des lignes non concordantes provenant des deux requêtes. Celles-ci sont ensuite rassemblées par l'opérateur UNION ALL.

Remarque : il est évident qu'il faut disposer de deux ensembles data avec des champs comparables pour pouvoir utiliser la requête ci-dessus.

Exemple illustré

Finie la théorie, place à la pratique ! Supposons qu'un supermarché veuille récupérer tous les produits éligibles à une promotion dans un seul tableau en fonction de la semaine. conditions de promotion.

Dans un premier temps, nous considérons que les produits ci-dessous sont en stock :

Image

Selon les conditions de promotion de la semaine 1 :

  • 10% réduction sur les étagères de fruits, légumes et herbes aromatiques

le dataset_1 est :

Image

Au cours de la deuxième semaine, les conditions de promotion évoluent :

  • 10% réduction sur les rayons fruits et glaces

  • 20% réduction sur le rayon des légumes

  • pas de remise sur le rayon des herbes

L'évolution du pipeline data génère le dataset_2 :

Image

Mais... sommes-nous vraiment sûrs des résultats ? Les questions les plus fréquentes sont les suivantes :

  • Y a-t-il des lignes manquantes ou supplémentaires ?

  • Les évolutions mises en œuvre sont-elles correctes sur les terrains impactés ?

  • Y a-t-il une régression dans les champs non touchés ?

Note : même s'il semble facile de répondre intuitivement aux questions ci-dessus grâce à un exemple trivial sur un petit ensemble data, dans les cas d'utilisation réels, nous sommes généralement confrontés à de nombreuses lignes et colonnes provenant de requêtes complexes (transformations, jointures, agrégats, fonctions de fenêtres, ...), ce qui donne tout son sens à cette requête.

Essayons de répondre aux 3 questions en interprétant les résultats de la requête de comparaison :

Image

Observations :

  • Pas de rangée avec des produits de l'étagère des fruits : amende en tant que “10% réduction sur les fruits”est restée inchangée de la semaine 1 à la semaine 2

  • Le Product_ID #50 (étagère à herbes) est absent de dataset_2 (seulement dans dataset_1) : amende en tant que “réduction sur les herbes”a été arrêtée la semaine 2

  • Le Product_ID #60 (étagère à glaces) est manquant dans dataset_1 (seulement dans dataset_2) : amende en tant que “réduction sur les glaces”a été introduite la semaine 2

  • Les lignes concernant les Product_ID #30 et #40 (rayon légumes) divergent sur le champ prix_réduit : amende en tant que “réduction sur les légumes”Le nombre d'heures de travail est passé de 10% la semaine 1 à 20% la semaine 2.

Finalement, tout se présente bien :

  • Y a-t-il des lignes manquantes ou supplémentaires ? Non !

  • Les évolutions mises en œuvre sont-elles correctes sur les terrains impactés ? Oui !

  • Y a-t-il une régression dans les champs non touchés ? Non !

Conseils et astuces

Dans le CTE, même si vous pouvez copier-coller votre requête SQL d'ingestion avant/après l'évolution, il peut être judicieux de stocker les résultats dans des tables temporaires pour simplifier la comparaison, améliorer les performances de la requête et bénéficier de la mise en cache si vous l'exécutez plusieurs fois.

Dans le monde réel, les divergences entre deux ensembles data peuvent être désordonnées. Dans ce cas, tri des résultats par clé (la granularité des datasets) et par drapeau peut grandement aider à interpréter et à comparer des lignes équivalentes provenant des deux datasets.

Afin de faciliter les enquêtes et d'identifier l'origine de la lacune, les suspicieux datasets champs communs peuvent être supprimés (c'est-à-dire commentés dans l'ETC) de la comparaison : s'il n'y a pas de résultat, cela signifie que tous les champs comparés sont égaux. Vous pouvez alors vous concentrer sur les champs suspects restants pour la prochaine comparaison et l'effectuer étape par étape.

Note : une analyse équivalente aurait pu être effectuée en utilisant la stratégie LEFT JOIN mais elle aurait été beaucoup plus difficile à maintenir (gestion des NULLs et des comparaisons de champs) et moins efficace car les opérateurs de set sont plus puissants que les jointures.

Résumé

Cette requête modélisée permet donc aux développeurs de valider rapidement les changements apportés aux pipelines data complexes. Elle est utile en complément des tests unitaires plus traditionnels, et peut même être considérée de manière plus générale lors de la comparaison de deux ensembles data ayant des structures similaires. Enfin, la logique de cette requête est même facile à apprendre par cœur !

Merci d'avoir lu, j'espère que c'était clair et je serais heureux d'entendre vos commentaires :)

Moyen Blog par Artefact.

Cet article a été initialement publié sur Medium.com.
Suivez-nous sur notre Medium Blog !