Outils pour utilisateurs

Outils du site


nsi:terminales:sql_et_python

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
nsi:terminales:sql_et_python [2021/04/13 15:28] – créée goupillwikinsi:terminales:sql_et_python [2022/08/29 21:47] (Version actuelle) goupillwiki
Ligne 1: Ligne 1:
-<markdown> +====== SQL et Python ======
-SQL et Python+
  
-## Requêtes via un langage de programmation+===== Requêtes via un langage de programmation =====
  
-Nous avons étudié le langage SQL qui permet de gérer une base de données par l'intermédiaire de requêtes : `CREATE TABLE`, `INSERT`, `UPDATE`, `SELECT`, etc.+==== Utilisation réelle d'une BDD ====
  
-Nous avons utilisé un logiciel de gestion nous permettant d'ecrire directement les requêtes en langage SQL et de visualiser le contenu de la base un peu comme si nous utilisions un tableur.+Nous avons étudié le langage SQL qui permet de gérer une base de données par l'intermédiaire de requêtes : ''CREATE TABLE'', ''INSERT'', ''UPDATE'', ''SELECT'', etc. 
 + 
 +Nous avons utilisé un logiciel de gestion nous permettant d’écrire directement les requêtes en langage SQL et de visualiser le contenu de la base un peu comme si nous utilisions un tableur.
  
 Mais ceci n'est pas l'utilisation habituelle d'une base de données. Mais ceci n'est pas l'utilisation habituelle d'une base de données.
Ligne 12: Ligne 13:
 Si nous reprenons l'exemple de la base de données de films, l'utilisation habituelle serait plutôt celle ci : Si nous reprenons l'exemple de la base de données de films, l'utilisation habituelle serait plutôt celle ci :
  
-* Une fenêtre - *par exemple une fenêtre web- met à disposition des boutons permettant à un utilisateur de consulter le contenu de la base ou d'en modifier le contenu. +  * Une fenêtre -- //par exemple une fenêtre web// -- met à disposition des boutons permettant à un utilisateur de consulter le contenu de la base ou d'en modifier le contenu. 
- +  * Si l'utilisateur souhaite ajouter un acteur, on lui propose un bouton "Ajouter un acteur" qui l'amène à une page adaptée. Sur cette nouvelle page, l'utilisateur trouve des zones de saisie dont la signification est clairement donnée : nom, prénom, date de naissance, biographie...\\ Cette page peut simplifier la saisie par exemple en proposant un bouton calendrier comme on envoie dans la plupart des sites internet où on doit entrer une date.\\ Un bouton valider permet de conclure l'ajout. 
-* Si l'utilisateur souhaite ajouter un acteur, on lui propose un bouton "Ajouter un acteur" qui l'amène à une page adaptée. Sur cette nouvelle page, l'utilisateur trouve des zones de saisie dont la signification est clairement donnée : nom, prénom, date de naissance, biographie... +  * Si l'utilisateur souhaite faire une recherche de film, on lui propose un champ de recherche dans lequel il écrit le nom du film.
- +
-  Cette page peut simplifier la saisie par exemple en proposant un bouton calendrier comme on envoie dans la plupart des sites internet où on doit entrer une date. +
- +
-  Un bouton valider permet de conclure l'ajout. +
- +
-* Si l'utilisateur souhaite faire une recherche de film, on lui propose un champ de recherche dans lequel il écrit le nom du film.+
  
 Bref, à aucun moment l'utilisateur n'a à entrer une requête SQL. Bref, à aucun moment l'utilisateur n'a à entrer une requête SQL.
  
-Le logiciel (par exemple le site internet) se charge de produire les requêtes SQL en fonction des actions de l'utilisateur. Le logiciel doit donc pouvoir dialoguer directement avec le SGBD base de donnée et lui transmettre des requêtes SQL. Il doit aussi pouvoir recevoir les réponses du SGBD. +==== Dialogue entre le programme et le SGBD ====
- +
-* Sur internet, un usage courant est de passer par le langage PHP. Les reqêtes http venant des clients et arrivant sur le serveur sont pris en charge par un script PHP, exécuté sur le serveur, et PHP intéragit avec un SGBD.+
  
-  Dans ce cas, le SGBD est souvent MySQL, MariaDB ou PostgreSQL+Le logiciel -- par exemple le site internet -- se charge de produire les requêtes SQL en fonction des actions de l'utilisateur. Le logiciel doit donc pouvoir dialoguer directement avec le SGBD et lui transmettre des requêtes SQL. Il doit aussi pouvoir recevoir les réponses du SGBD.
  
-* Un autre usage qui se développe est de faire exécuter un script en Javascript sur le serveur (au lieu de PHP). Dans ce cas, le SGBD MongoDB est adapté car il est fait pour fonctionner avec Javascript.+  * Sur internet, un usage courant est de passer par le langage [[langages:php:start|PHP]]. Les requêtes http venant des clients et arrivant sur le serveur sont pris en charge par un script PHP, exécuté sur le serveur, et PHP interagit avec un SGBD.\\ Dans ce cas, le SGBD est souvent MySQL, MariaDB ou PostgreSQL. 
 +  * Un autre usage qui se développe est de faire exécuter un script en [[langages:javascript:start|Javascript]] sur le serveur -- au lieu de PHP. Dans ce cas, le SGBD MongoDB est adapté car il est fait pour fonctionner avec Javascript
 +  * Nous allons étudier le cas de Python.
  
-* Nous allons étudier le cas de Python.+===== sqlite3 =====
  
-## sqlite3+En Python, on peut utiliser le module ''sqlite3'' -- [[https://docs.python.org/fr/3/library/sqlite3.html|Référence]]
  
-En Python, on peut utiliser le module `sqlite3`+==== Importer la bibliothèque ====
  
-```python+<code python linenums>
 import sqlite3 import sqlite3
-```+</code>
  
-### Connexion à la base de données+==== Connexion à la base de données ====
  
 On peut ouvrir ou créer un nouveau fichier base de données : On peut ouvrir ou créer un nouveau fichier base de données :
  
-```python +<code python linenums:2> 
-c = sqlite3.connect('films.db'+c = sqlite3.connect("example.db"
-```+</code>
  
-Ici, la variable `cest un objet qui consiste en la connexion au fichier base de données dont le nom est `'example.db'`. Si le fichier n'existe pas, la base est créée.+Ici, la variable ''c'' est un objet qui consiste en la connexion au fichier base de données dont le nom est ''%%"example.db"%%''. Si le fichier n'existe pas, la base est créée.
  
 On peut souhaiter travailler sur une base de données temporaire que l'on n'enregistre pas sur le disque dur. Dans ce cas on cette possibilité : On peut souhaiter travailler sur une base de données temporaire que l'on n'enregistre pas sur le disque dur. Dans ce cas on cette possibilité :
  
-```python +<code python linenums:2> 
-c = sqlite3.connect(':memory:'+c = sqlite3.connect(":memory:"
-```+</code>
  
-### Activation des clés étrangères+Dans notre cas, nous reprenons le fichier {{ :nsi:terminales:database:films.db |}} avec mes films et acteurs. Placer ce fichier dans le même répertoire que le script python puis : 
 + 
 +<code python linenums:2> 
 +c = sqlite3.connect("films.db"
 +</code> 
 + 
 +==== Activation des clés étrangères ====
  
 La vérification de la cohérence des clé étrangères peut être une lourde charge pour le système. On est donc libre de l'activer ou pas. Si on ne l'active pas, bien sûr, il faudra être plus vigilant pour éviter les incohérences. La vérification de la cohérence des clé étrangères peut être une lourde charge pour le système. On est donc libre de l'activer ou pas. Si on ne l'active pas, bien sûr, il faudra être plus vigilant pour éviter les incohérences.
Ligne 64: Ligne 65:
 Nous souhaitons l'activer, nous ajoutons alors la commande : Nous souhaitons l'activer, nous ajoutons alors la commande :
  
-```python+<code python linenums:3>
 c.execute("PRAGMA foreign_keys = 1") c.execute("PRAGMA foreign_keys = 1")
-```+</code>
  
-> Vous pouvez voir que `executeest une méthode de l'objet de connexion `c`.+<WRAP tip> Vous pouvez voir que ''execute'' est une méthode de l'objet de connexion ''c''.</WRAP>
  
-### Exécution de requêtes SQL+==== Exécution de requêtes SQL ====
  
-L'exécution des requêtes demande l'utilisation d'un *curseur*. C'est un objet dont le rôle est précisemment d'exécuter les requêtes.+L'exécution des requêtes demande l'utilisation d'un //curseur//. C'est un objet dont le rôle est justement d'exécuter les requêtes.
  
-```python+<code python linenums:4>
 cursor = c.cursor() cursor = c.cursor()
-```+</code>
  
-Le curseur a lui aussi une méthode  `execute`, c'est par elle qu'on lance les requêtes. Exemple :+Le curseur a lui aussi une méthode  ''execute'', c'est par elle qu'on lance les requêtes. Exemple :
  
-```python+<code python linenums:5>
 cursor.execute("CREATE TABLE ARTISTE (idArtiste INTEGER PRIMARY KEY, nom VARCHAR(20), prénom VARCHAR(20), biographie TEXT, naissance DATE);") cursor.execute("CREATE TABLE ARTISTE (idArtiste INTEGER PRIMARY KEY, nom VARCHAR(20), prénom VARCHAR(20), biographie TEXT, naissance DATE);")
-```+</code>
  
 Écrit tout à la suite, ce n'est pas très lisible. On préfère généralement utiliser plusieurs lignes : Écrit tout à la suite, ce n'est pas très lisible. On préfère généralement utiliser plusieurs lignes :
  
-```python+<code python linenums:5>
 cursor.execute("""CREATE TABLE ARTISTE ( cursor.execute("""CREATE TABLE ARTISTE (
                     idArtiste INTEGER PRIMARY KEY,                     idArtiste INTEGER PRIMARY KEY,
Ligne 94: Ligne 95:
                     naissance DATE                     naissance DATE
                  );""")                  );""")
-```+</code>
  
 Les espaces sur la partie gauche n'ont pas d'importance. Ils sont là pour aider la lecture. Les espaces sur la partie gauche n'ont pas d'importance. Ils sont là pour aider la lecture.
  
 **Remarques :** **Remarques :**
 +  * Le '';'' final de la requête sert dans le cas où on souhaite faire plusieurs requêtes. Si on ne fait qu'une seule requête, le '';'' est inutile.
 +  * Avec ''sqlite3'' on ne peut pas faire en une fois plusieurs requête. Si on a 3 requêtes à faire, il faudra appeler 3 fois la méthodes ''cursor.execute''.
  
-* Le `;` final de la requête sert dans le cas où on souhaite faire plusieurs requêtes. Si on ne fait qu'une seule requête, le `;` est inutile. +==== Exemple d'une insertion ====
-* Avec `sqlite3` on ne peut pas faire en une fois plusieurs requête. Si on a 3 requêtes à faire, il faudra appeler 3 fois la méthodes `cursor.execute`. +
- +
-### Exemple d'une insertion+
  
 Une insertion de base ne pose pas de problème : Une insertion de base ne pose pas de problème :
  
-```python+<code python>
 cursor.execute("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES('Bruce', 'Willis', 'blabla.', '1955-03-19');") cursor.execute("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES('Bruce', 'Willis', 'blabla.', '1955-03-19');")
-```+</code>
  
 Mais cette situation n'est pas réaliste. En général on sera plutôt dans un cas où nous avons obtenu les informations par ailleurs, depuis une interface web par exemple. Mais cette situation n'est pas réaliste. En général on sera plutôt dans un cas où nous avons obtenu les informations par ailleurs, depuis une interface web par exemple.
  
-```python+<code python>
 # au moment de faire l'insertion de l'artiste, on nous a fourni # au moment de faire l'insertion de l'artiste, on nous a fourni
 # ces variables avec leur valeur # ces variables avec leur valeur
Ligne 120: Ligne 120:
 biographie = 'blabla.' biographie = 'blabla.'
 naissance = '1955-03-19' naissance = '1955-03-19'
-```+</code>
  
 On sait que la requête voulue est : On sait que la requête voulue est :
  
-```sql+<code sql>
 INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES('Bruce', 'Willis', 'blabla.', '1955-03-19'); INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES('Bruce', 'Willis', 'blabla.', '1955-03-19');
-```+</code> 
 + 
 +=== Fausse bonne idée ===
  
 On se dit que l'on pourrait en Python fabriquer le texte de la requête de cette façon : On se dit que l'on pourrait en Python fabriquer le texte de la requête de cette façon :
  
-```python+<code python>
 texte_requete = "INSERT INTO ARTISTE (prénom, nom, biographie, naissance) VALUES ('{}', '{}', '{}', '{}');".format(prénom, nom, biographie, naissance) texte_requete = "INSERT INTO ARTISTE (prénom, nom, biographie, naissance) VALUES ('{}', '{}', '{}', '{}');".format(prénom, nom, biographie, naissance)
  
 # puis exécution # puis exécution
 cursor.execute(texte_requete) cursor.execute(texte_requete)
-```+</code>
  
-**Il ne faut surtout pas faire cela !!!!!**+<WRAP important>**Il ne faut surtout pas faire cela !!!!!**</WRAP>
  
-C'est logique mais cela pose un gros problème de sécurité appelé **injection SQL** sur lequel on reviendra plus loin.+Il serait naturel de faire cela, mais cela pose un gros problème de sécurité appelé **injection SQL** sur lequel on reviendra plus loin.
  
-**Bonne méthode**+=== Bonne méthode ===
  
-```python+<code python>
 data = (prénom, nom, biographie, naissance) data = (prénom, nom, biographie, naissance)
 cursor.execute("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES(?, ?, ?, ?);", data) cursor.execute("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES(?, ?, ?, ?);", data)
-```+</code>
  
-1. Création du tupple contenant les informations à insérer, dans le bon ordre +  - Création du tupple contenant les informations à insérer, dans le bon ordre 
-2. Lancement de la requête en prévoyant les trous à compléter sous forme de `?`+  Lancement de la requête en prévoyant les trous à compléter sous forme de ''?''
  
-Cette méthode ressemble à l'utilisation de `formatmais il y a une différence : elle faite pour éviter l'injection SQL.+Cette méthode ressemble à l'utilisation de ''format'' mais il y a une différence : elle faite pour éviter l'injection SQL.
  
-**id de l'insertion**+=== id de l'insertion ===
  
 Quand on insère un nouvel item, on ne précise pas son identifiant, on laisse le SGBD le choisir automatiquement. Mais on peut avoir besoin de l'identifiant de ce que l'on vient d'insérer... Quand on insère un nouvel item, on ne précise pas son identifiant, on laisse le SGBD le choisir automatiquement. Mais on peut avoir besoin de l'identifiant de ce que l'on vient d'insérer...
Ligne 159: Ligne 161:
 On peut récupérer cet id directement après l'insertion : On peut récupérer cet id directement après l'insertion :
  
-```python+<code python>
 id_du_dernier_inséré = cursor.lastrowid id_du_dernier_inséré = cursor.lastrowid
-```+</code>
  
-### Exemple d'un insertion multiple+==== Exemple d'un insertion multiple ====
  
 On pourrait décider d'insérer plusieurs artistes en même temps. On pourrait décider d'insérer plusieurs artistes en même temps.
  
-```python +<code python> 
-à_insérer = [+a_inserer = [
     ('Bruce', 'Willis', 'blabla', '1955-03-19'),     ('Bruce', 'Willis', 'blabla', '1955-03-19'),
     ('Rickman','Alan','blabla...','1946-02-21'),     ('Rickman','Alan','blabla...','1946-02-21'),
Ligne 174: Ligne 176:
     ('Gilliam','Terry','blablabla.','1940-11-22')     ('Gilliam','Terry','blablabla.','1940-11-22')
 ] ]
-```+</code>
  
-Comment les insérer ? On pourrait passer par une boucle `for`+Comment les insérer ? On pourrait passer par une boucle ''for''
  
-```python +<code python> 
-for item in à_insérer:+for item in a_inserer:
     cursor.execute("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES(?, ?, ?, ?);", item)     cursor.execute("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES(?, ?, ?, ?);", item)
-```+</code>
  
 Mais on dispose d'une fonction plus adaptée : Mais on dispose d'une fonction plus adaptée :
  
-```python +<code python> 
-cursor.executemany("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES(?, ?, ?, ?);", à_insérer+cursor.executemany("INSERT INTO ARTISTE(prénom, nom, biographie, naissance) VALUES(?, ?, ?, ?);", a_inserer
-```+</code>
  
-### Exemple d'une lecture+==== Exemple d'une lecture ====
  
-Le plus souvent, on consulte le contenu de la base dans la modifier. On utilise pour cela une requête `SELECT`.+Le plus souvent, on consulte le contenu de la base dans la modifier. On utilise pour cela une requête ''SELECT''.
  
-```python+<code python>
 cursor.execute("SELECT * FROM ARTISTE;") cursor.execute("SELECT * FROM ARTISTE;")
-```+</code>
  
 La requête est alors exécutée mais on n'obtient rien. La requête est alors exécutée mais on n'obtient rien.
  
-Les résultats de la sélection sont contenus dans `cursor:+Les résultats de la sélection sont contenus dans ''cursor'' :
  
-```python+<code python>
 premier = cursor.fetchone() # fetch = chercher. On récupère le premier premier = cursor.fetchone() # fetch = chercher. On récupère le premier
 suivant = cursor.fetchone() # récupère le suivant suivant = cursor.fetchone() # récupère le suivant
 suivant = cursor.fetchone() # encore le suivant suivant = cursor.fetchone() # encore le suivant
 # quand on a tout récupéré, fetchone() renvoie None # quand on a tout récupéré, fetchone() renvoie None
-```+</code>
  
 On peut aussi récupérer les résultats tous d'un coup : On peut aussi récupérer les résultats tous d'un coup :
  
-```pyton+<code python>
 resultats = cursor.fetchall() resultats = cursor.fetchall()
-```+</code>
  
-**Attention :** un résultat aura la forme `(1, 'Bruce', 'Willis', 'blabla.', '1955-03-19'). Il n'est pas précisé à quoi correspondent les différents champs. Mais comme nous connaissons la table, nous savons que le premier champ est `idArtiste`, le second est `prénom`, etc.+<WRAP tip>Un résultat aura la forme ''(1, 'Bruce', 'Willis', 'blabla.', '1955-03-19')'' . Il n'est pas précisé à quoi correspondent les différents champs. Mais comme nous connaissons la table, nous savons que le premier champ est ''idArtiste'', le second est ''prénom'', etc.</WRAP>
  
-### Fin des modifications+==== Fin des modifications ====
  
-Pour que les modifications soit pris en compte dans la base de données, on utilise+Pour que les modifications soit prises en compte dans la base de données, on utilise
  
-```python+<code python>
 c.commit() c.commit()
-```+</code>
  
 Et pour refermer la connexion : Et pour refermer la connexion :
  
-```+<code python>
 c.close() c.close()
-``` +</code>
- +
-Attention, la fermeture de la connexion de met pas à jour le fichier base de données et il faut donc penser à faire un `commit` avant la fermeture. +
- +
-## Injection SQL +
- +
-Imaginons que l'utilisateur ait le droit de supprimer certains artistes, pas tous, par exemple ceux qu'il a lui même créé. +
- +
-Par exemple, il demande la suppression de l'artiste `idArtiste = 1`, c'est à dire dans notre cas, Bruce Willis. +
- +
-Le système doit donc fabriquer la requête avec le paramètre `idArtiste = 1`. Supposons que l'on fasse ceci : +
- +
-```python +
-# on sait que idArtiste = 1 +
-requete = "DELETE FROM ARTISTE WHERE idArtiste = {}".format(idArtiste) +
-# on a donc : +
-# requete = "DELETE FROM ARTISTE WHERE idArtiste = 1" +
-cursor.execute(requete) +
-# tout se passe bien +
-``` +
- +
-Maintenant imaginons qu'un hacker s'arrange pour transmettre cette requête : +
- +
-```python +
-idArtiste = '1 OR 1 = 1' +
-``` +
- +
-Le hacker est maître du client sur lequel il exécute sa requête, il peut donc envoyer la requête qu'il veut. Que se passe-t-il si on fait la même chose qu'avant ? +
- +
-```python +
-# on sait que idArtiste = '1 OR 1 = 1' +
-requete = "DELETE FROM ARTISTE WHERE idArtiste = {}".format(idArtiste) +
-# on a donc : +
-# requete = "DELETE FROM ARTISTE WHERE idArtiste = 1 OR 1 = 1" +
-cursor.execute(requete) +
-# aie aie aie ! +
-``` +
- +
-`1 = 1` est toujours vrai, donc la condition du `WHERE` sera toujours vraie et on va donc supprimer tous les artistes de la base !!! +
- +
-Nous devons donc empêcher que de telles situations se produisent. +
- +
-Les langages proposent des fonctions, comme le `execute` de `sqlite` avec le `?`, qui se chargent de filtrer tous les cas à problème. C'est pourquoi on ne doit surtout pas essayer de compléter la requête nous-même, on doit utiliser les fonctions fournies. +
- +
-# Travail +
- +
-Voilà, vous savez tout. Voilà votre travail. +
- +
-Créer une interface simple qui utilisera la base de données `films.db`. Vous trouverez un début de fichier Python dans `interface.py`, pour vous donner des idées (vous êtes libre de faire complètement autrement). +
- +
-Cette interface se comportera comme suit : +
- +
-* Au démarrage, un menu nous donne le choix de  +
- +
-  1. Ajouter une données +
-  2. Afficher les données +
- +
-  L'utilisateur est invité à sélectionner 1 ou 2 +
- +
-* Quand l'utilisateur choisit 1, il a un nouveau choix à faire :+
  
-  1. Ajouter un artiste +<WRAP important>La fermeture de la connexion de met pas à jour le fichier base de données et il faut donc penser à faire un ''commit'' avant la fermeture.</WRAP>
-  2Ajouter un film +
-  3. Ajouter un rôle d'un artiste dans un film+
  
-  * Dans le cas 1) on demande à l'utilisateur à la suite prénom, nom, biographie et naissance. +<WRAP info>==== Injection SQL ====
-  * Dans le cas 2), on demande à l'utilisateur le titreVF, titreVO et l'id du réalisateur +
-  * Dans le cas 3), on demande le rôle, l'id du film et l'id de l'artiste+
  
-  À chaque fois, un message indique si l'insertion a bien eu lieu et on retourne au menu de départ.+Il n'est pas obligatoire de comprendre ceci. J'indique l'explication pour les plus avancés d'entre vous.
  
-* Quand l'utilisateur choisit 2il a un nouveau choix :+Imaginons qu'un site permette aux internautes de créer un compte utilisateur. Avec ce compte utilisateur ils peuvent ajouter des items dans la basepar exemple des acteurs. En face chaque acteur qu'ils ont créé, ils voient un bouton avec une poubelle. S'ils appuient dessus, le système  envoie une requête au serveur précisant : 
 +  * que c'est une demande de suppression, 
 +  * l'id de l'item à supprimer, donc l'id de l'artiste.
  
-  1Liste des artistes +Supposons que l'utilisateur clique le bouton à côté de Bruce WillisOn aura ''%%idArtiste = "1"%%''.
-  2Liste des films+
  
-  S'il choisit 1) il voit la liste des noms d'artistes avec leur id. Il est invité à sélectionner un numéro d'artiste. Quand il l'a fait on voit le nomprénom de l'artiste ainsi que sa date de naissance, sa biographie et la liste des films dans lesquels il a joué et ceux qu'il a réalisé.+Côté serveursupposons encore que le script ressemble à :
  
-  S'il choisit 2il voit les infos sur le film avec la liste des noms d'acteurs avec leur identifiant, leur rôle dans le film, et le réalisateur avec son identifiant.+<code python> 
 +def suppression_artiste(idArtiste)
 +    requete = "DELETE FROM ARTISTE WHERE idArtiste = {}".format(idArtiste) 
 +    cursor.execute(requete) 
 +</code>
  
-  Dans les deux cas, on propose à l'utilisateur de choisir un nombre. Si c'est un nombre correspondant à un des identifiants afficheril affiche le contenu correspondant, sinon retour au menu initial.+Si l'utilisateur fait les choses normalementla requête sera bien ''%%"DELETE FROM ARTISTE WHERE idArtiste = 1"%%'' et tout se passera bien.
  
-Cela fait beaucoup de choses. Allez progressivement. Si vous n'arrivez pas à tout fairece n'est pas grave.+Supposons maintenant qu'un utilisateur mal intentionné se crée lui aussi un compte. Puiscomme il est maître de sa propre machine, il force l'envoie d'une requête de suppression mais avec un ''idArtiste'' anormal : il donne ''%%idArtiste = "1 OR 1 = 1"%%''.
  
-Vous pouvez commencer par :+Le programme côté serveur fait la même chose et on obtient ''%%"DELETE FROM ARTISTE WHERE idArtiste = 1 OR 1 = 1"%%''. **Aïe, aïe, aïe !**. La condition de //WHERE// est toujours vraie. **Tous les artistes sont supprimés !**
  
-1Permettre l'ajout d'artistes +Et encore c'est un cas simpleL'utilisateur pourrait écrire pourrait écrire toute une requête, par exemple en envoyant ''%%idArtiste = "1; DELETE FROM FILM WHERE 1 = 1"%%''.
-2. Permettre l'affichage de la liste d'artistes.+
  
-</markdown>+Nous devons donc empêcher que de telles situations se produisent. L'idée est d'empêcher d'insérer des éléments contenant des commandes SQL. On pourrait le faire manuellement bien sûr, en prévoyant tout un tas de tests pour éliminer tous les exemples de commandes dangereuses. Mais le module fournit déjà toutes les fonctionnalités pour cela. Par exemple, le ''execute'' de ''sqlite'' se charge de filtrer tous les cas à problème. C'est pourquoi on ne doit surtout pas essayer de compléter la requête nous-même, on doit utiliser les fonctions fournies. 
 +</WRAP>
nsi/terminales/sql_et_python.1618320488.txt.gz · Dernière modification : de goupillwiki