Tdid-IPS-39-Python et SQLite

ProcédureIntégrer des requêtes SQL dans un programme python

  1. Le fichier Base de données bdnotes.db

    Dans le dossier 0800, vous devez uploader le fichier bdnotes.db dans un dossier app/notes de votre espace pythonanywhere.

  2. Interaction de Python et la base de données

    Exemple

    1
    # fonctions python pour travailler avec une base de données SQLite
    2
    import sqlite3 
    3
    4
    # l'objet db sera utilisé pour se connecter à la base de données
    5
    db = sqlite3.connect('bdnotes.db')
    6
    7
    # définir l'objet curseur mat qui permet de mémoriser les actions (requêtes) sur la base de données (objet db)
    8
    mat = db.cursor() #nommer ce curseur avec le nom mat est censé nous aider à affecter les ations sur la base qui concernent les matièrs
    9

    Ces 3 instructions permettent :

    • de préparer des requêtes SQL à faire exécuter à l'intérieur d'un programme python.
    • d'ouvrir la base de données (bdnotes.db) et de lui affecter un objet nommé db ici.
    • de disposer d'un objet (mat ici) pour travailler avec l'objet db sur la table matière et surtout récupérer les données.
  3. Afficher le contenu des tuples d'une requête 1 par 1

    Truc & astuceMéthode execute et fetchone

    • execute va permettre d'exécuter une requête SQL et de transmettre les données au curseur (ici mat).
    • fetchone va transférer le premier tuple à une liste nommée mat1.
    1
    # exécuter une requête simple
    2
    print("-------lecture séquentielle des tuples")
    3
    mat.execute("SELECT * FROM tbMat")
    4
    # lire la premier tuple
    5
    mat1 = mat.fetchone()
    6
    # lire le suivant
    7
    mat2 = mat.fetchone()
    8
    # lire le suivant
    9
    mat3 = mat.fetchone()
    10
    print(mat1,mat2,mat3)
  4. Utiliser une boucle while

    La solution précédente extrait les données en mémoire tuple par tuple, ce qui optimise la gestion de la mémoire vive dans le cas d'une requête contenant de nombreux attributs et tuples.

    On ne procède jamais ainsi pour lire les tuples d'une requête puisque par principe, on ne connaît pas le nombre de tuples à lire, sauf si on écrit une requête dont les conditions testées font que l'on est assuré qu'il y a un nombre fixe de tuples résultants.

    Lorsque l'on tente de lire un tuple qui n'existe pas, la fonction fetchone() retourne None.

    ExempleA tester à la suite du code de l'étape précédente

    1
    mat4 = mat.fetchone()
    2
    if (mat4 == None) :
    3
        print("Plus d'enregistrements")
    4
    else:
    5
        print (mat4)

    On va donc intégrer la méthode fetchone() dans une boucle while qui se poursuivra tant que le résultat est différent du mot-clé None.

    Exemple

    1
    # Utiliser une boucle while pour lire le contenu des tuples de la requête
    2
    print("-------lecture avec une boucle while")
    3
    mat.execute("SELECT * FROM tbMat")
    4
    while True:
    5
        tuple = mat.fetchone()
    6
        if (tuple == None):
    7
            print("Plus d'enregistrements")
    8
            break
    9
        else:
    10
            print (tuple)
  5. Utiliser l'itérateur pour parcourir les tuples

    Si le volume de données à extraire dans la requête n'est pas trop important, on a la possibilité de récupérer l'ingralités des tuples avec la méthode fetchall()

    L'itérateur avec sa boucle va permettre de ne pas être obligé de tester l'existence du tuple suivant à chaque itération et de sortir de la boucle while qui boucle de manière infinie.

    Le code à tester est présent ci-dessous

    Exemple

    1
    # Utiliser un itérateur pour lire le contenu des tuples de la requête
    2
    print("-------lecture avec une boucle --> formattage des données")
    3
    4
    mat.execute("SELECT * FROM tbMat")
    5
    tuples = mat.fetchall()
    6
    for tuple in tuples:
    7
        print('{0} : {1} - {2}'.format(tuple[0], tuple[1], tuple[2]))

    Ici, on en a profité pour extraire les valeurs du tuple et de formater l'affichage d'une manière un peu différente : ce qui revient à lire les colonnes de chaque ligne avec l'indice de la colonne. Vous noterez qu'on se rapproche un peu de la technique que l'on avait utilisé pour lire les fichiers CSV. La différence est qu'avec les fichiers CSV on peut construire le stockage des valeurs en fonction des traitements que l'on va faire ensuite : on pouvait donc construire des listes avec les valeurs de chaque ligne ou des listes avec les valeurs de chaque colonne ou encore des structures 2D.

    Avec SQL, le principe est systématiquement d'extraire des tuples (des lignes vu du tableur) qui vont alimenter une liste de valeurs pour chaque valeur de chaque attribut de la ligne.

    La puissance du langage SQL est de limiter très facilement les colonnes à afficher ainsi que de filtrer les tuples de la requête en construisant des conditions adaptées à ce que l'on veut extraire non pas d'une seule table (ou d'un seul fichier tableur csv), mais de données avec plusieurs tables.

    Truc & astucePour simplifier encore la boule de parcours des tuples

    En fait, l'objet curseur est déjà lui-même un itérateur :