Python en entreprise avec la rétro-ingénierie

article data engineering etl python sql Apr 15, 2024

 La rétro-ingénierie a pour but d’expliquer le fonctionnement d’un système et de la documenter. Dans le contexte de la donnée, elle a plusieurs objectifs :

  • Faciliter le transfert de connaissance en mettant à jour les spécifications techniques,
  • Constituer un référentiel permettant de mieux estimer la charge de travail à venir sur les projets d’évolution,
  • Commenter le code utilisé pour préparer à son intégration ou son évolution
  •  etc.

Nous allons voir dans cet article comment Python est utilisé comme outil de rétro- ingénierie, et contribue à documenter les développements et l'architecture des projets IT.

 
Recenser les tables sources utilisées pour alimenter le Datamart

Lors d’un projet de migration comme lors d’un déménagement c’est l’occasion de faire le tri et d’identifier tous les tables obsolètes qui prennent de l’espace de stockage.

Python s’avère pratique pour analyser les flux ETL qui s’opère dans une base de données SQL, grâce à l’extraction des procédures stockés dans lesquelles sont contenues ces informations. En effet actuellement il n’existe pas de fonctionnalité native « intelligente » dans les SGBD permettant de lister les tables manipulées dans des blocs de code SQL.

Avec Python l’approche est la suivante :

  • Extraire le code SQL de la base de données
  • Le « nettoyer » en supprimant le code obsolète et les commentaires
  • Récupérer le nom des tables

Ces étapes sont détaillées dans la suite de l’article.

 
Extraire le code SQL de la base de données

Une des librairies utilisées pour interagir avec une instance SQL est pyodbc. Son utilisation est assez simple et commence par la saisie des informations de connexion comme ci-dessous :

import pyodbc
nom_server = '760YFX3'
database = 'BI_DW_ParchAndPosey'
cnxn = pyodbc.connect(r'Driver={SQL Server};Server='+nom_server+';Database='+database+';Trusted_connection=yes;')
cursor = cnxn.cursor()
cursor.execute("SELECT OBJECT_DEFINITION(object_id) as ma_procedure FROM sys.procedures")

Puis récupérer le code sous forme de liste de chaîne decaractère (String) grâce à une boucle with():

procs=[] while 1: row = cursor.fetchone() if not row: break # pour chaque ligne on assemble 
procs.append(row.ma_procedure)

Ainsi chaque élément de la liste correspondra à une ligne retournée par la requête SQL de type SELECT.

En procédant de cette manière, on pourra travailler en local sans passer par le système de gestion de base de données. On pourra vérifier la bonne intégration avec l’instruction suivante :

len(procs)

Et en comparant le résultats en python avec le nombre de ligne en sortie de la requête SQL.

 
Préparation des données

Cette étape fait référence à plusieurs transformations permettant d’identifier les tables sources et uniquement celles-ci avec une expression régulière.

  • La 1ère transformation concerne le découpage des éléments dans la liste. En effet actuellement chaque élément correspond à une procédure alors qu’il est plus naturel d’utiliser le format d’origine : ligne par ligne. Pour cela il nous faut lier l’ensemble des éléments puis de nouveau les séparer avec les instructions suivantes Python :
# lier chaque élément de la liste en un seul élement de type String
concat = ''.join(procs)
# séparer chaque élément lors d'un retour à la ligne
lines= concat.split('\r\n')
  • Ensuite il va nous falloir différencier les lignes commentaires des lignes de codes, afin de ne pas prendre en compte dans le recensement des tables le code obsolète ou « dead code ».
requete_sans_commentaires=[]
for line in lines:
        if ("--" not in line):
            w = line
requete_sans_commentaires.append(w)
  • Enfin nous devons retirer les caractères qui risquent de faire des doublons lors du recensement comme la virgule (« , » ) et le point-virgule (« ; » )
# Parcours de la liste pour supprimer la virgule puis redécouper
requete_finale = [ligne.replace(",", "").replace(";", "") for ligne in requete_sans_commentaires]
 
Récupération du nom des tables

Pour identifier le nom des tables nous devons choisir l’expression régulière qui couvre l’ensemble des chaînes de caractère contenant l’information indiquant une table. Les valeurs concernées sont sous la forme :

 [Schema].[table] ou   [Schema].[table].[colonne]

Donc si nous utilisons la chaîne de caractère « [Schema]. » pour identifier les éléments.

i = 0
Schema = 'ParchAndPosey.dbo.'
liste_table = []
while i<len(requete_finale):
    # Si une partie de la chaîne de caractère commence par '[ParchAndPosey.dbo.].', alors on récupère cette ligne
    if (Schema in requete_finale[i]):        
liste_table.append(requete_finale[i].split(Schema,1)[1].split(' ',1)[0]) i=i+1

La fonction « split() » suivie des crochets (« [ ] ») permet de ne pas récupérer les éléments avant et après le noms de la tables.

Enfin il est possible d’utiliser la fonction native set() afin de supprimer les doublons

# suppression des doublons
sam_list = list(set(liste_table))
print('\n'.join(sam_list))

Ainsi toutes les tables listées en sortie de ce script sont celles utilisés dans les procédures de la base 'ParchAndPosey’.

 
Comparaison entre l’utilisation d’SQL et de python

Certains concepts de programmation comme l'approche procédural sont similaires entre Python et SQL, donc libre à vous de chercher à obtenir le même résultat sur un SGBD comme SQL server. Nous avons choisis Python dans cet article pour la simplicité de ce langage et sa large utilisation dans les domaines de la data (machine learning, datavisualisation, etc.).

En effet traiter des informations de type texte en utilisant python offre plus de simplicité que SQL sur les points suivant:

  • Manipuler les données texte, grâce aux fonctions s’appliquant aux listes de chaîne de caractère,
  • Incrémenter des boucles comme for() ou with() dont l’implémentation est similaire aux autres langages de programmation,
  • Appliquer la récursivité en prenant en compte les différentes couches de bases de données,
  • Travailler en local sans solliciter la base de données SQL

Pour conclure : au-delà de la praticité du langage python pour récupérer dynamiquement une information, l’approche rétro-ingénierie est primordiale car elle permet de gagner en efficacité sur les projets IT.

Ne ratez pas nos prochains contenus

Inscrivez vous à notre Newsletter pour recevoir tous nos prochains contenus gratuits : Articles, Webinaires, Podcasts, Astuces vidéos,...

Data AI Lab

Transformez votre quotidien avec des compétences clés en data. Des formations, conseils et défis pour une maîtrise pointue en Data Science et IA.

 

Liens

Accueil
Challenges Data
Consulting

 

Formations

Parcours Data Analyst
Parcours Data Engineer
Voir toutes les formations

 

Ressources

Articles
Webinaires
Tuto vidéos

 

All rights reserved 2024 - Mentions légales - Politique de confidentialité