Aller au contenu

Jointure de tables

Lorsque les données à traiter sont en très grand nombre, elles sont généralement réparties dans plusieurs tables. On peut donc être amené à devoir regrouper ces données dans une seule table pour ensuite les exploiter.

Définition

L'opération de fusion de plusieurs tables s'appelle jointure.

Pour fusionner deux tables différentes, c'est-à-dire obtenir une unique table à partir de deux, il faut qu'elles aient au moins un attribut commun.

Exemple avec le module fonctions_csv.py

On considère :

  • la table Personnes :

    id_client nom prénom
    1 Labrosse Adam
    2 Gemlamorte Adèle
    3 Auboisdormant Abel
    4 Etpan Ahmed
    5 Térieur Alain

  • la table Commandes :

    id_commande id_client descriptif
    1 2 bouilloire
    2 5 couverture
    3 4 VTT
    4 4 smartphone
    5 1 cahiers

Le numéro d'identification du client id_client est un attribut commun à ces deux tables, on peut donc les fusionner, c'est-à-dire construire un tableau de dictionnaires dans lequel chaque dictionnaire se présente sous la forme suivante :

{'id_client': ..., 'nom': ..., 'prenom': ..., 'id_commande': ..., 'descriptif': ...}

  1. Ouvrez un éditeur Python puis copiez/collez les tables de données suivantes :

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    from fonctions_csv import *
    
    personnes = [{'id_client': 1, 'nom': 'Labrosse', 'prenom': 'Adam'},
                    {'id_client': 2, 'nom': 'Gemlamorte', 'prenom': 'Adèle'},
                    {'id_client': 3, 'nom': 'Auboisdormant', 'prenom': 'Abel'},
                    {'id_client': 4, 'nom': 'Etpan', 'prenom': 'Ahmed'},
                    {'id_client': 5, 'nom': 'Térieur', 'prenom': 'Alain'}]
    
    commandes = [{'id_commande': 1, 'id_client': 2, 'descriptif': 'bouilloire'},
                 {'id_commande': 2, 'id_client': 5, 'descriptif': 'couverture'},
                 {'id_commande': 3, 'id_client': 4, 'descriptif': 'VTT'},
                 {'id_commande': 4, 'id_client': 4, 'descriptif': 'smartphone'},
                 {'id_commande': 5, 'id_client': 1, 'descriptif': 'cahiers'}]
    
    personnes_commandes = ...
    

  2. Pour fusionner les deux tables, le module fonctions.csv contient la fonction jointure() dont l'utilisation est décrite ci-dessous :

    1
    Table_Resultat = jointure(Nom_Table1, Nom_Table2, attribut_commun)
    
    En utilisant cette fonction, réaliser la jointure (en ligne 15) entre les tables personnes et commandes. Cette jointure sera stockée dans la variable personnes_commandes.

    Fonction jointure()

    Cette fonction est définie dans le module fonctions_csv.py.
    Il est inutile de recopier le code ci-dessous, importer ce module permettra d'utiliser la fonction jointure(). Toutefois, à ce stade de l'année, il faut être capable de comprendre ce code :

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    from copy import deepcopy
    
    def jointure(table1, table2, attribut1, attribut2=None):
        if attribut2 is None:
            attribut2 = attribut1
        new_table = []
        for dico1 in table1:
            for dico2 in table2:
                if dico1[attribut1] == dico2[attribut2]:
                    new_dico = deepcopy(dico1)
                    for attribut in dico2:
                        if attribut != attribut2:
                             new_dico[attribut] = dico2[attribut]
                    new_table.append(new_dico)
        return new_table
    
    1. Ligne 1 : on importe le module deepcopy afin d'éviter les problème de recopie de tableau de dictionnaires et les effets de bord (rappelez-vous le chapitre Portée des variables).
    2. Ligne 3 : L'attribut2 a une valeur par défaut : None, c'est-à-dire qu'il peut ne pas être présent.
    3. Lignes 4 et 5 : Quand l'attribut2 n'est pas présent, cela signifie que les attributs de jointure portent le même nom.
    4. Ligne 6 : La future table, qui est au départ un tableau vide.
    5. Ligne 9 : On ne considère que les dictionnaires de table1 et table2 qui ont des valeurs identiques pour les attribut1 et attribut2.
    6. Ligne 10 : On recopie entièrement le dictionnaire de la table1 dans un nouveau dictionnaire.
    7. Lignes 11 à 13 : On ajoute dans ce nouveau dictionnaire les attributs de chaque dictionnaire correspondant de table2 sans accepter à nouveau la valeur de l'attribut de jointure.

    Tests dans la console

    Vérifiez que vous obtenez les résultats suivants lors de l'appel dans la console :

    >>> personnes_commandes
    [{'id_client': 1, 'nom': 'Labrosse', 'prenom': 'Adam', 'id_commande': 5, 'descriptif': 'cahiers'},
     {'id_client': 2, 'nom': 'Gemlamorte', 'prenom': 'Adèle', 'id_commande': 1, 'descriptif': 'bouilloire'},
     {'id_client': 4, 'nom': 'Etpan', 'prenom': 'Ahmed', 'id_commande': 3, 'descriptif': 'VTT'},
     {'id_client': 4, 'nom': 'Etpan', 'prenom': 'Ahmed', 'id_commande': 4, 'descriptif': 'smartphone'},
     {'id_client': 5, 'nom': 'Térieur', 'prenom': 'Alain', 'id_commande': 2, 'descriptif': 'couverture'}]
    

    Une solution
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    from fonctions_csv import *
    
    personnes = [{'id_client': 1, 'nom': 'Labrosse', 'prenom': 'Adam'},
                    {'id_client': 2, 'nom': 'Gemlamorte', 'prenom': 'Adèle'},
                    {'id_client': 3, 'nom': 'Auboisdormant', 'prenom': 'Abel'},
                    {'id_client': 4, 'nom': 'Etpan', 'prenom': 'Ahmed'},
                    {'id_client': 5, 'nom': 'Térieur', 'prenom': 'Alain'}]
    
    commandes = [{'id_commande': 1, 'id_client': 2, 'descriptif': 'bouilloire'},
                 {'id_commande': 2, 'id_client': 5, 'descriptif': 'couverture'},
                 {'id_commande': 3, 'id_client': 4, 'descriptif': 'VTT'},
                 {'id_commande': 4, 'id_client': 4, 'descriptif': 'smartphone'},
                 {'id_commande': 5, 'id_client': 1, 'descriptif': 'cahiers'}]
    
    personnes_commandes = jointure(personnes, commandes, 'id_client')
    
  3. Quelle remarque pouvez-vous faire sur la table personnes_commandes obtenue ? Est-ce cohérent ?

    Une réponse

    On peu remarquer que le client numéro '3' n'apparaît pas dans la table personnes_commandes. Cela semble cohérent puisqu'il n'a effectué aucun commande...

Cas particulier

Dans certaines tables, l'attribut commun peut avoir une autre appellation mais le même champs de valeurs.
C'est le cas de la table Commandes2 par exemple :

ident_commande ident_client descriptif
1 5 switch
2 2 chocolat

La fonction jointure() présente dans le module fonctions_csv permet de préciser l'attribut de la seconde table pour les mettre en relation :

1
Table_Resultat = jointure(Nom_Table1, Nom_Table2, attribut_Table1, attribut_Table2)

Ce qui donne pour notre exemple :

1
personnes_commandes2 = jointure(personnes, commandes2, 'id_client', 'ident_client')