Mysql
 sql >> Base de données >  >> RDS >> Mysql

Base de données Python et MySQL :une introduction pratique

MySQL est l'un des systèmes de gestion de base de données (SGBD) les plus populaires sur le marché aujourd'hui. Il s'est classé deuxième derrière le SGBD Oracle dans le classement DB-Engines de cette année. Comme la plupart des applications logicielles doivent interagir avec les données sous une forme ou une autre, les langages de programmation comme Python fournissent des outils pour stocker et accéder à ces sources de données.

En utilisant les techniques décrites dans ce didacticiel, vous pourrez intégrer efficacement une base de données MySQL à une application Python. Vous développerez une petite base de données MySQL pour un système de classification de films et apprendrez à l'interroger directement à partir de votre code Python.

À la fin de ce didacticiel, vous serez en mesure de :

  • Identifier les fonctionnalités uniques de MySQL
  • Connectez votre application à une base de données MySQL
  • Interroger la base de données pour récupérer les données requises
  • Gérer les exceptions qui se produisent lors de l'accès à la base de données
  • Utiliser les bonnes pratiques lors de la création d'applications de base de données

Pour tirer le meilleur parti de ce didacticiel, vous devez avoir une connaissance pratique des concepts Python tels que for boucles, fonctions, gestion des exceptions et installation de packages Python à l'aide de pip . Vous devez également avoir une compréhension de base des systèmes de gestion de bases de données relationnelles et des requêtes SQL telles que SELECT , DROP , CREATE , et JOIN .

Téléchargement gratuit : Obtenez un exemple de chapitre de Python Tricks :le livre qui vous montre les meilleures pratiques de Python avec des exemples simples que vous pouvez appliquer instantanément pour écrire du code + Pythonic plus beau.


Comparer MySQL à d'autres bases de données SQL

SQL signifie Structured Query Language et est un langage de programmation largement utilisé pour la gestion de bases de données relationnelles. Vous avez peut-être entendu parler des différentes versions des SGBD basés sur SQL. Les plus populaires sont MySQL, PostgreSQL, SQLite et SQL Server. Toutes ces bases de données sont conformes aux normes SQL mais avec des degrés de conformité variables.

Être open source Depuis sa création en 1995, MySQL est rapidement devenu un leader du marché parmi les solutions SQL. MySQL fait également partie de l'écosystème Oracle. Bien que sa fonctionnalité de base soit entièrement gratuite, il existe également des modules complémentaires payants. Actuellement, MySQL est utilisé par toutes les grandes entreprises technologiques, y compris Google, LinkedIn, Uber, Netflix, Twitter et autres.

Outre une grande communauté open source pour le support, il existe de nombreuses autres raisons du succès de MySQL :

  1. Facilité d'installation : MySQL a été conçu pour être convivial. Il est assez simple de configurer une base de données MySQL, et plusieurs outils tiers largement disponibles, comme phpMyAdmin, rationalisent davantage le processus de configuration. MySQL est disponible pour tous les principaux systèmes d'exploitation, y compris Windows, macOS, Linux et Solaris.

  2. Vitesse : MySQL a la réputation d'être une solution de base de données extrêmement rapide. Il a une empreinte relativement plus petite et est extrêmement évolutif à long terme.

  3. Privilèges utilisateur et sécurité : MySQL est livré avec un script qui vous permet de définir le niveau de sécurité du mot de passe, d'attribuer des mots de passe administrateur et d'ajouter et de supprimer des privilèges de compte utilisateur. Ce script simplifie le processus d'administration d'un portail de gestion des utilisateurs d'hébergement Web. D'autres SGBD, comme PostgreSQL, utilisent des fichiers de configuration plus compliqués à utiliser.

Alors que MySQL est réputé pour sa rapidité et sa facilité d'utilisation, vous pouvez obtenir des fonctionnalités plus avancées avec PostgreSQL. De plus, MySQL n'est pas entièrement conforme à SQL et présente certaines limitations fonctionnelles, comme l'absence de prise en charge de FULL JOIN clauses.

Vous pouvez également rencontrer des problèmes de lecture et d'écriture simultanées dans MySQL. Si votre logiciel a de nombreux utilisateurs qui y écrivent des données à la fois, alors PostgreSQL pourrait être un choix plus approprié.

Remarque : Pour une comparaison plus approfondie de MySQL et PostgreSQL dans un contexte réel, consultez Pourquoi Uber Engineering est passé de Postgres à MySQL.

SQL Server est également un SGBD très populaire et est connu pour sa fiabilité, son efficacité et sa sécurité. Il est préféré par les entreprises, en particulier dans le domaine bancaire, qui font régulièrement face à des charges de travail importantes. C'est une solution commerciale et c'est l'un des systèmes les plus compatibles avec les services Windows.

En 2010, lorsqu'Oracle a acquis Sun Microsystems et MySQL, beaucoup s'inquiétaient de l'avenir de MySQL. À l'époque, Oracle était le plus grand concurrent de MySQL. Les développeurs craignaient qu'il s'agisse d'une prise de contrôle hostile d'Oracle dans le but de détruire MySQL.

Plusieurs développeurs dirigés par Michael Widenius, l'auteur original de MySQL, ont créé un fork de la base de code MySQL et jeté les bases de MariaDB. L'objectif était de sécuriser l'accès à MySQL et de le garder gratuit pour toujours.

À ce jour, MariaDB reste entièrement sous licence GPL, la gardant entièrement dans le domaine public. Certaines fonctionnalités de MySQL, en revanche, ne sont disponibles qu'avec des licences payantes. De plus, MariaDB fournit plusieurs fonctionnalités extrêmement utiles qui ne sont pas prises en charge par le serveur MySQL, comme le SQL distribué et le stockage en colonnes. Vous pouvez trouver plus de différences entre MySQL et MariaDB sur le site Web de MariaDB.

MySQL utilise une syntaxe très similaire au SQL standard. Il existe cependant quelques différences notables mentionnées dans la documentation officielle.



Installation du serveur MySQL et du connecteur MySQL/Python

Maintenant, pour commencer à suivre ce didacticiel, vous devez configurer deux choses :un serveur MySQL et un connecteur MySQL . Le serveur MySQL fournira tous les services nécessaires à la gestion de votre base de données. Une fois le serveur opérationnel, vous pouvez y connecter votre application Python à l'aide de MySQL Connector/Python.


Installation du serveur MySQL

La documentation officielle détaille la méthode recommandée pour télécharger et installer le serveur MySQL. Vous trouverez des instructions pour tous les systèmes d'exploitation courants, y compris Windows, macOS, Solaris, Linux et bien d'autres.

Pour Windows, le meilleur moyen est de télécharger MySQL Installer et de le laisser s'occuper de l'ensemble du processus. Le gestionnaire d'installation vous aide également à configurer les paramètres de sécurité du serveur MySQL. Sur la page Comptes et rôles, vous devez entrer un mot de passe pour la racine (admin) et éventuellement ajouter d'autres utilisateurs avec différents privilèges :

Bien que vous deviez spécifier les informations d'identification du compte root lors de la configuration, vous pouvez modifier ces paramètres ultérieurement.

Remarque : N'oubliez pas le nom d'hôte, le nom d'utilisateur et le mot de passe, car ils seront nécessaires pour établir une connexion avec le serveur MySQL ultérieurement.

Bien que vous n'ayez besoin que du serveur MySQL pour ce didacticiel, vous pouvez également configurer d'autres outils utiles tels que MySQL Workbench à l'aide de ces programmes d'installation. Si vous ne souhaitez pas installer MySQL directement dans votre système d'exploitation, le déploiement de MySQL sur Linux avec Docker est une alternative pratique.



Installation du connecteur MySQL/Python

Un pilote de base de données est un logiciel qui permet à une application de se connecter et d'interagir avec un système de base de données. Les langages de programmation comme Python ont besoin d'un pilote spécial avant de pouvoir parler à une base de données d'un fournisseur spécifique.

Ces pilotes sont généralement obtenus en tant que modules tiers. L'API de base de données Python (DB-API) définit l'interface standard à laquelle tous les pilotes de base de données Python doivent se conformer. Ces détails sont documentés dans la PEP 249. Tous les pilotes de base de données Python, tels que sqlite3 pour SQLite, psycopg pour PostgreSQL et MySQL Connector/Python pour MySQL, suivent ces règles d'implémentation.

Remarque : La documentation officielle de MySQL utilise le terme connecteur au lieu de pilote . Techniquement, les connecteurs sont uniquement associés à la connexion à une base de données, et non à l'interaction avec elle. Cependant, le terme est souvent utilisé pour l'ensemble du module d'accès à la base de données comprenant le connecteur et le chauffeur.

Pour maintenir la cohérence avec la documentation, vous verrez le terme connecteur chaque fois que MySQL est mentionné.

De nombreux langages de programmation populaires ont leur propre API de base de données. Par exemple, Java dispose de l'API Java Database Connectivity (JDBC). Si vous devez connecter une application Java à une base de données MySQL, vous devez utiliser le connecteur MySQL JDBC, qui suit l'API JDBC.

De même, en Python, vous devez installer un connecteur Python MySQL pour interagir avec une base de données MySQL. De nombreux packages suivent les normes DB-API, mais le plus populaire d'entre eux est MySQL Connector/Python. Vous pouvez l'obtenir avec pip :

$ pip install mysql-connector-python

pip installe le connecteur en tant que module tiers dans l'environnement virtuel actuellement actif. Il est recommandé de configurer un environnement virtuel isolé pour le projet avec toutes les dépendances.

Pour tester si l'installation a réussi, tapez la commande suivante sur votre terminal Python :

>>>
>>> import mysql.connector

Si le code ci-dessus s'exécute sans erreur, alors mysql.connector est installé et prêt à l'emploi. Si vous rencontrez des erreurs, assurez-vous que vous êtes dans le bon environnement virtuel et que vous utilisez le bon interpréteur Python.

Assurez-vous que vous installez le bon mysql-connector-python package, qui est une implémentation purement Python. Méfiez-vous des connecteurs portant le même nom mais maintenant dépréciés comme mysql-connector .




Établir une connexion avec le serveur MySQL

MySQL est un basé sur un serveur système de gestion de base de données. Un serveur peut contenir plusieurs bases de données. Pour interagir avec une base de données, vous devez d'abord établir une connexion avec le serveur. Le flux de travail général d'un programme Python qui interagit avec une base de données basée sur MySQL est le suivant :

  1. Connectez-vous au serveur MySQL.
  2. Créer une nouvelle base de données.
  3. Se connecter à la base de données nouvellement créée ou à une base de données existante.
  4. Exécuter une requête SQL et récupérer les résultats.
  5. Informer la base de données si des modifications sont apportées à une table.
  6. Fermez la connexion au serveur MySQL.

Il s'agit d'un flux de travail générique qui peut varier en fonction de l'application individuelle. Mais quelle que soit l'application, la première étape consiste à connecter votre base de données à votre application.


Établir une connexion

La première étape de l'interaction avec un serveur MySQL consiste à établir une connexion. Pour ce faire, vous avez besoin de connect() depuis le mysql.connector module. Cette fonction prend des paramètres comme host , user , et password et renvoie une MySQLConnection objet. Vous pouvez recevoir ces informations d'identification en tant qu'entrée de l'utilisateur et les transmettre à connect() :

from getpass import getpass
from mysql.connector import connect, Error

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
    ) as connection:
        print(connection)
except Error as e:
    print(e)

Le code ci-dessus utilise les identifiants de connexion saisis pour établir une connexion avec votre serveur MySQL. En retour, vous obtenez une MySQLConnection objet, qui est stocké dans la connection variable. À partir de maintenant, vous utiliserez cette variable pour accéder à votre serveur MySQL.

Il y a plusieurs choses importantes à remarquer dans le code ci-dessus :

  • Vous devez toujours gérer les exceptions qui peuvent survenir lors de l'établissement d'une connexion au serveur MySQL. C'est pourquoi vous utilisez un tryexcept block pour intercepter et imprimer toutes les exceptions que vous pourriez rencontrer.

  • Vous devez toujours fermer la connexion une fois que vous avez terminé d'accéder à la base de données. Laisser des connexions ouvertes inutilisées peut entraîner plusieurs erreurs inattendues et des problèmes de performances. Le code ci-dessus tire parti d'un gestionnaire de contexte utilisant with , qui supprime le processus de nettoyage de la connexion.

  • Vous ne devez jamais coder en dur vos identifiants de connexion , c'est-à-dire votre nom d'utilisateur et votre mot de passe, directement dans un script Python. Il s'agit d'une mauvaise pratique de déploiement et constitue une grave menace pour la sécurité. Le code ci-dessus invite l'utilisateur à entrer ses identifiants de connexion. Il utilise le getpass intégré module pour masquer le mot de passe. Bien que cela soit préférable au codage en dur, il existe d'autres moyens plus sûrs de stocker des informations sensibles, comme l'utilisation de variables d'environnement.

Vous avez maintenant établi une connexion entre votre programme et votre serveur MySQL, mais vous devez toujours créer une nouvelle base de données ou vous connecter à une base de données existante à l'intérieur du serveur.



Création d'une nouvelle base de données

Dans la dernière section, vous avez établi une connexion avec votre serveur MySQL. Pour créer une nouvelle base de données, vous devez exécuter une instruction SQL :

CREATE DATABASE books_db;

L'instruction ci-dessus créera une nouvelle base de données avec le nom books_db .

Remarque : Dans MySQL, il est obligatoire de mettre un point-virgule (; ) à la fin d'une instruction, qui indique la fin d'une requête. Cependant, MySQL Connector/Python ajoute automatiquement un point-virgule à la fin de vos requêtes, il n'est donc pas nécessaire de l'utiliser dans votre code Python.

Pour exécuter une requête SQL en Python, vous devez utiliser un curseur, qui supprime l'accès aux enregistrements de la base de données. MySQL Connector/Python vous fournit le MySQLCursor class, qui instancie des objets capables d'exécuter des requêtes MySQL en Python. Une instance de MySQLCursor la classe est aussi appelée un cursor .

cursor les objets utilisent une MySQLConnection objet pour interagir avec votre serveur MySQL. Pour créer un cursor , utilisez le .cursor() méthode de votre connection variables :

cursor = connection.cursor()

Le code ci-dessus vous donne une instance de MySQLCursor classe.

Une requête qui doit être exécutée est envoyée à cursor.execute() au format chaîne. Dans cette occasion particulière, vous enverrez le CREATE DATABASE requête à cursor.execute() :

from getpass import getpass
from mysql.connector import connect, Error

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
    ) as connection:
        create_db_query = "CREATE DATABASE online_movie_rating"
        with connection.cursor() as cursor:
            cursor.execute(create_db_query)
except Error as e:
    print(e)

Après avoir exécuté le code ci-dessus, vous aurez une nouvelle base de données appelée online_movie_rating dans votre serveur MySQL.

Le CREATE DATABASE la requête est stockée sous forme de chaîne dans le create_db_query variable puis transmise à cursor.execute() pour exécution. Le code utilise un gestionnaire de contexte avec le cursor objet pour gérer le processus de nettoyage.

Vous pouvez recevoir une erreur ici si une base de données portant le même nom existe déjà sur votre serveur. Pour le confirmer, vous pouvez afficher le nom de toutes les bases de données de votre serveur. Utiliser le même MySQLConnection objet précédent, exécutez le SHOW DATABASES déclaration :

>>>
>>> show_db_query = "SHOW DATABASES"
>>> with connection.cursor() as cursor:
...     cursor.execute(show_db_query)
...     for db in cursor:
...         print(db)
...
('information_schema',)
('mysql',)
('online_movie_rating',)
('performance_schema',)
('sys',)

Le code ci-dessus imprime les noms de toutes les bases de données actuellement sur votre serveur MySQL. Le SHOW DATABASES La commande génère également certaines bases de données que vous n'avez pas créées sur votre serveur, comme information_schema , performance_schema , etc. Ces bases de données sont générées automatiquement par le serveur MySQL et donnent accès à une variété de métadonnées de base de données et de paramètres de serveur MySQL.

Vous avez créé une nouvelle base de données dans cette section en exécutant le CREATE DATABASE déclaration. Dans la section suivante, vous verrez comment vous connecter à une base de données qui existe déjà.



Connexion à une base de données existante

Dans la dernière section, vous avez créé une nouvelle base de données appelée online_movie_rating . Cependant, vous ne vous y êtes toujours pas connecté. Dans de nombreuses situations, vous aurez déjà une base de données MySQL que vous souhaitez connecter à votre application Python.

Vous pouvez le faire en utilisant le même connect() fonction que vous avez utilisée précédemment en envoyant un paramètre supplémentaire appelé database :

from getpass import getpass
from mysql.connector import connect, Error

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
        database="online_movie_rating",
    ) as connection:
        print(connection)
except Error as e:
    print(e)

Le code ci-dessus est très similaire au script de connexion que vous avez utilisé précédemment. Le seul changement ici est une database supplémentaire paramètre, où le nom de votre base de données est passé à connect() . Une fois ce script exécuté, vous serez connecté au online_movie_rating base de données.




Créer, modifier et supprimer un tableau

Dans cette section, vous apprendrez à effectuer certaines requêtes DDL de base telles que CREATE , DROP , et ALTER avec Python. Vous aurez un aperçu rapide de la base de données MySQL que vous utiliserez dans le reste de ce didacticiel. Vous créerez également toutes les tables requises pour la base de données et apprendrez comment effectuer des modifications sur ces tables ultérieurement.


Définir le schéma de la base de données

Vous pouvez commencer par créer un schéma de base de données pour un système de classification de films en ligne. La base de données sera composée de trois tables :

  1. movies contient des informations générales sur les films et possède les attributs suivants :
    • id
    • title
    • release_year
    • genre
    • collection_in_mil
  2. reviewers contient des informations sur les personnes qui ont publié des avis ou des notes et possède les attributs suivants :
    • id
    • first_name
    • last_name
  3. ratings contient des informations sur les notes qui ont été publiées et possède les attributs suivants :
    • movie_id (clé étrangère)
    • reviewer_id (clé étrangère)
    • rating

Un système de classement de films du monde réel, comme IMDb, aurait besoin de stocker un tas d'autres attributs, comme les e-mails, les listes de distribution de films, etc. Si vous le souhaitez, vous pouvez ajouter d'autres tables et attributs à cette base de données. Mais ces trois tableaux suffiront pour les besoins de ce tutoriel.

L'image ci-dessous illustre le schéma de la base de données :

Les tables de cette base de données sont liées les unes aux autres. movies et reviewers aura un plusieurs à plusieurs relation car un film peut être revu par plusieurs critiques et un critique peut revoir plusieurs films. Les ratings table relie les movies tableau avec les reviewers tableau.



Création de tableaux à l'aide de CREATE TABLE Déclaration

Maintenant, pour créer une nouvelle table dans MySQL, vous devez utiliser le CREATE TABLE déclaration. La requête MySQL suivante créera les movies table pour votre online_movie_rating base de données :

CREATE TABLE movies(
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(100),
    release_year YEAR(4),
    genre VARCHAR(100),
    collection_in_mil INT
);

Si vous avez déjà examiné les instructions SQL, la plupart des requêtes ci-dessus peuvent avoir un sens. Mais il existe certaines différences dans la syntaxe MySQL dont vous devez être conscient.

Par exemple, MySQL a une grande variété de types de données pour votre lecture, y compris YEAR , INT , BIGINT , etc. De plus, MySQL utilise le AUTO_INCREMENT mot-clé lorsqu'une valeur de colonne doit être incrémentée automatiquement lors de l'insertion de nouveaux enregistrements.

Pour créer une nouvelle table, vous devez passer cette requête à cursor.execute() , qui accepte une requête MySQL et exécute la requête sur la base de données MySQL connectée :

create_movies_table_query = """
CREATE TABLE movies(
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(100),
    release_year YEAR(4),
    genre VARCHAR(100),
    collection_in_mil INT
)
"""
with connection.cursor() as cursor:
    cursor.execute(create_movies_table_query)
    connection.commit()

Vous avez maintenant les movies table dans votre base de données. Vous passez create_movies_table_query à cursor.execute() , qui effectue l'exécution requise.

Remarque : La connection la variable fait référence à MySQLConnection objet qui a été renvoyé lorsque vous vous êtes connecté à votre base de données.

Notez également le connection.commit() déclaration à la fin du code. Par défaut, votre connecteur MySQL ne valide pas automatiquement les transactions. Dans MySQL, les modifications mentionnées dans une transaction se produisent uniquement lorsque vous utilisez un COMMIT commande à la fin. Appelez toujours cette méthode après chaque transaction pour effectuer des modifications dans la table réelle.

Comme vous l'avez fait avec les movies table, exécutez le script suivant pour créer les reviewers tableau :

create_reviewers_table_query = """
CREATE TABLE reviewers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(100),
    last_name VARCHAR(100)
)
"""
with connection.cursor() as cursor:
    cursor.execute(create_reviewers_table_query)
    connection.commit()

Si nécessaire, vous pouvez ajouter plus d'informations sur un évaluateur, telles que son identifiant de messagerie ou des informations démographiques. Mais first_name et last_name servira votre objectif pour le moment.

Enfin, vous pouvez créer les ratings table en utilisant le script suivant :

create_ratings_table_query = """
CREATE TABLE ratings (
    movie_id INT,
    reviewer_id INT,
    rating DECIMAL(2,1),
    FOREIGN KEY(movie_id) REFERENCES movies(id),
    FOREIGN KEY(reviewer_id) REFERENCES reviewers(id),
    PRIMARY KEY(movie_id, reviewer_id)
)
"""
with connection.cursor() as cursor:
    cursor.execute(create_ratings_table_query)
    connection.commit()

L'implémentation des relations de clé étrangère dans MySQL est légèrement différente et limitée par rapport au SQL standard. Dans MySQL, le parent et l'enfant dans la contrainte de clé étrangère doivent utiliser le même moteur de stockage .

Un moteur de stockage est le composant logiciel sous-jacent utilisé par un système de gestion de base de données pour effectuer des opérations SQL. Dans MySQL, les moteurs de stockage se présentent sous deux formes différentes :

  1. Moteurs de stockage transactionnels sont sécurisés pour les transactions et vous permettent d'annuler les transactions à l'aide de commandes simples telles que rollback . De nombreux moteurs MySQL populaires, dont InnoDB et NDB, appartiennent à cette catégorie.

  2. Moteurs de stockage non transactionnels dépendent d'un code manuel élaboré pour annuler les instructions validées sur une base de données. MyISAM, MEMORY et de nombreux autres moteurs MySQL ne sont pas transactionnels.

InnoDB est le moteur de stockage par défaut et le plus populaire. Il aide à maintenir l'intégrité des données en prenant en charge les contraintes de clé étrangère. Cela signifie que toute opération CRUD sur une clé étrangère est vérifiée pour s'assurer qu'elle n'entraîne pas d'incohérences entre différentes tables.

Notez également que les ratings table utilise les colonnes movie_id et reviewer_id , les deux clés étrangères, conjointement comme clé primaire . Cette étape garantit qu'un critique ne peut pas noter deux fois le même film.

Vous pouvez choisir de réutiliser le même curseur pour plusieurs exécutions. Dans ce cas, toutes les exécutions deviendraient une transaction atomique plutôt que plusieurs transactions distinctes. Par exemple, vous pouvez exécuter tous les CREATE TABLE instructions avec un seul curseur, puis ne validez votre transaction qu'une seule fois :

with connection.cursor() as cursor:
    cursor.execute(create_movies_table_query)
    cursor.execute(create_reviewers_table_query)
    cursor.execute(create_ratings_table_query)
    connection.commit()

Le code ci-dessus exécutera d'abord les trois CREATE déclarations. Ensuite, il enverra un COMMIT commande au serveur MySQL qui valide votre transaction. Vous pouvez également utiliser .rollback() pour envoyer un ROLLBACK commande au serveur MySQL et supprime toutes les modifications de données de la transaction.



Afficher un schéma de table à l'aide de DESCRIBE Déclaration

Maintenant que vous avez créé les trois tables, vous pouvez consulter leur schéma à l'aide de l'instruction SQL suivante :

DESCRIBE <table_name>;

Pour obtenir des résultats du cursor objet, vous devez utiliser cursor.fetchall() . Cette méthode récupère toutes les lignes de la dernière instruction exécutée. En supposant que vous ayez déjà le MySQLConnection objet dans la connection variable, vous pouvez imprimer tous les résultats récupérés par cursor.fetchall() :

>>>
>>> show_table_query = "DESCRIBE movies"
>>> with connection.cursor() as cursor:
...     cursor.execute(show_table_query)
...     # Fetch rows from last executed query
...     result = cursor.fetchall()
...     for row in result:
...         print(row)
...
('id', 'int(11)', 'NO', 'PRI', None, 'auto_increment')
('title', 'varchar(100)', 'YES', '', None, '')
('release_year', 'year(4)', 'YES', '', None, '')
('genre', 'varchar(100)', 'YES', '', None, '')
('collection_in_mil', 'int(11)', 'YES', '', None, '')

Une fois que vous avez exécuté le code ci-dessus, vous devriez recevoir un tableau contenant des informations sur toutes les colonnes de movies table. Pour chaque colonne, vous recevrez des détails tels que le type de données de la colonne, si la colonne est une clé primaire, etc.



Modification d'un schéma de table à l'aide de ALTER Déclaration

Dans les movies table, vous avez une colonne appelée collection_in_mil , qui contient la collection au box-office d'un film en millions de dollars. Vous pouvez écrire l'instruction MySQL suivante pour modifier le type de données de collection_in_mil attribut de INT à DECIMAL :

ALTER TABLE movies MODIFY COLUMN collection_in_mil DECIMAL(4,1);

DECIMAL(4,1) signifie un nombre décimal qui peut avoir un maximum de 4 chiffres, dont 1 est décimal, tel que 120.1 , 3.4 , 38.0 , etc. Après avoir exécuté ALTER TABLE déclaration, vous pouvez afficher le schéma de table mis à jour en utilisant DESCRIBE :

>>>
>>> alter_table_query = """
... ALTER TABLE movies
... MODIFY COLUMN collection_in_mil DECIMAL(4,1)
... """
>>> show_table_query = "DESCRIBE movies"
>>> with connection.cursor() as cursor:
...     cursor.execute(alter_table_query)
...     cursor.execute(show_table_query)
...     # Fetch rows from last executed query
...     result = cursor.fetchall()
...     print("Movie Table Schema after alteration:")
...     for row in result:
...         print(row)
...
Movie Table Schema after alteration
('id', 'int(11)', 'NO', 'PRI', None, 'auto_increment')
('title', 'varchar(100)', 'YES', '', None, '')
('release_year', 'year(4)', 'YES', '', None, '')
('genre', 'varchar(100)', 'YES', '', None, '')
('collection_in_mil', 'decimal(4,1)', 'YES', '', None, '')

Comme indiqué dans la sortie, le collection_in_mil l'attribut est maintenant de type DECIMAL(4,1) . Notez également que dans le code ci-dessus, vous appelez cursor.execute() à deux reprises. Mais cursor.fetchall() récupère uniquement les lignes de la dernière requête exécutée, qui est le show_table_query .



Suppression de tableaux à l'aide de DROP Déclaration

Pour supprimer une table, vous devez exécuter le DROP TABLE déclaration dans MySQL. La suppression d'un tableau est irréversible processus. Si vous exécutez le code ci-dessous, vous devrez appeler le CREATE TABLE interrogez à nouveau pour utiliser les ratings tableau dans les sections à venir.

Pour supprimer les ratings table, envoyez drop_table_query à cursor.execute() :

drop_table_query = "DROP TABLE ratings"
with connection.cursor() as cursor:
    cursor.execute(drop_table_query)

Si vous exécutez le code ci-dessus, vous aurez supprimé avec succès les ratings tableau.




Insérer des enregistrements dans des tableaux

Dans la dernière section, vous avez créé trois tables dans votre base de données :movies , reviewers , et ratings . Vous devez maintenant remplir ces tables avec des données. Cette section couvrira deux manières différentes d'insérer des enregistrements dans le connecteur MySQL pour Python.

La première méthode, .execute() , fonctionne bien lorsque le nombre d'enregistrements est faible et que les enregistrements peuvent être codés en dur. La deuxième méthode, .executemany() , est plus populaire et convient mieux aux scénarios réels.


Utiliser .execute()

La première approche utilise le même cursor.execute() méthode que vous avez utilisée jusqu'à présent. Vous écrivez le INSERT INTO requête dans une chaîne et transmettez-la à cursor.execute() . Vous pouvez utiliser cette méthode pour insérer des données dans les movies tableau.

Pour référence, les movies table a cinq attributs :

  1. id
  2. title
  3. release_year
  4. genre
  5. collection_in_mil

Vous n'avez pas besoin d'ajouter de données pour id comme AUTO_INCREMENT calcule automatiquement id pour toi. Le script suivant insère des enregistrements dans les movies tableau :

insert_movies_query = """
INSERT INTO movies (title, release_year, genre, collection_in_mil)
VALUES
    ("Forrest Gump", 1994, "Drama", 330.2),
    ("3 Idiots", 2009, "Drama", 2.4),
    ("Eternal Sunshine of the Spotless Mind", 2004, "Drama", 34.5),
    ("Good Will Hunting", 1997, "Drama", 138.1),
    ("Skyfall", 2012, "Action", 304.6),
    ("Gladiator", 2000, "Action", 188.7),
    ("Black", 2005, "Drama", 3.0),
    ("Titanic", 1997, "Romance", 659.2),
    ("The Shawshank Redemption", 1994, "Drama",28.4),
    ("Udaan", 2010, "Drama", 1.5),
    ("Home Alone", 1990, "Comedy", 286.9),
    ("Casablanca", 1942, "Romance", 1.0),
    ("Avengers: Endgame", 2019, "Action", 858.8),
    ("Night of the Living Dead", 1968, "Horror", 2.5),
    ("The Godfather", 1972, "Crime", 135.6),
    ("Haider", 2014, "Action", 4.2),
    ("Inception", 2010, "Adventure", 293.7),
    ("Evil", 2003, "Horror", 1.3),
    ("Toy Story 4", 2019, "Animation", 434.9),
    ("Air Force One", 1997, "Drama", 138.1),
    ("The Dark Knight", 2008, "Action",535.4),
    ("Bhaag Milkha Bhaag", 2013, "Sport", 4.1),
    ("The Lion King", 1994, "Animation", 423.6),
    ("Pulp Fiction", 1994, "Crime", 108.8),
    ("Kai Po Che", 2013, "Sport", 6.0),
    ("Beasts of No Nation", 2015, "War", 1.4),
    ("Andadhun", 2018, "Thriller", 2.9),
    ("The Silence of the Lambs", 1991, "Crime", 68.2),
    ("Deadpool", 2016, "Action", 363.6),
    ("Drishyam", 2015, "Mystery", 3.0)
"""
with connection.cursor() as cursor:
    cursor.execute(insert_movies_query)
    connection.commit()

The movies table is now loaded with thirty records. The code calls connection.commit() at the end. It’s crucial to call .commit() after preforming any modifications to a table.



Using .executemany()

The previous approach is more suitable when the number of records is fairly small and you can write these records directly into the code. But this is rarely true. You’ll often have this data stored in some other file, or the data will be generated by a different script and will need to be added to the MySQL database.

This is where .executemany() comes in handy. It accepts two parameters:

  1. A query that contains placeholders for the records that need to be inserted
  2. A list that contains all records that you wish to insert

The following example inserts records for the reviewers tableau :

insert_reviewers_query = """
INSERT INTO reviewers
(first_name, last_name)
VALUES ( %s, %s )
"""
reviewers_records = [
    ("Chaitanya", "Baweja"),
    ("Mary", "Cooper"),
    ("John", "Wayne"),
    ("Thomas", "Stoneman"),
    ("Penny", "Hofstadter"),
    ("Mitchell", "Marsh"),
    ("Wyatt", "Skaggs"),
    ("Andre", "Veiga"),
    ("Sheldon", "Cooper"),
    ("Kimbra", "Masters"),
    ("Kat", "Dennings"),
    ("Bruce", "Wayne"),
    ("Domingo", "Cortes"),
    ("Rajesh", "Koothrappali"),
    ("Ben", "Glocker"),
    ("Mahinder", "Dhoni"),
    ("Akbar", "Khan"),
    ("Howard", "Wolowitz"),
    ("Pinkie", "Petit"),
    ("Gurkaran", "Singh"),
    ("Amy", "Farah Fowler"),
    ("Marlon", "Crafford"),
]
with connection.cursor() as cursor:
    cursor.executemany(insert_reviewers_query, reviewers_records)
    connection.commit()

In the script above, you pass both the query and the list of records as arguments to .executemany() . These records could have been fetched from a file or from the user and stored in the reviewers_records liste.

The code uses %s as a placeholder for the two strings that had to be inserted in the insert_reviewers_query . Placeholders act as format specifiers and help reserve a spot for a variable inside a string. The specified variable is then added to this spot during execution.

You can similarly use .executemany() to insert records in the ratings tableau :

insert_ratings_query = """
INSERT INTO ratings
(rating, movie_id, reviewer_id)
VALUES ( %s, %s, %s)
"""
ratings_records = [
    (6.4, 17, 5), (5.6, 19, 1), (6.3, 22, 14), (5.1, 21, 17),
    (5.0, 5, 5), (6.5, 21, 5), (8.5, 30, 13), (9.7, 6, 4),
    (8.5, 24, 12), (9.9, 14, 9), (8.7, 26, 14), (9.9, 6, 10),
    (5.1, 30, 6), (5.4, 18, 16), (6.2, 6, 20), (7.3, 21, 19),
    (8.1, 17, 18), (5.0, 7, 2), (9.8, 23, 3), (8.0, 22, 9),
    (8.5, 11, 13), (5.0, 5, 11), (5.7, 8, 2), (7.6, 25, 19),
    (5.2, 18, 15), (9.7, 13, 3), (5.8, 18, 8), (5.8, 30, 15),
    (8.4, 21, 18), (6.2, 23, 16), (7.0, 10, 18), (9.5, 30, 20),
    (8.9, 3, 19), (6.4, 12, 2), (7.8, 12, 22), (9.9, 15, 13),
    (7.5, 20, 17), (9.0, 25, 6), (8.5, 23, 2), (5.3, 30, 17),
    (6.4, 5, 10), (8.1, 5, 21), (5.7, 22, 1), (6.3, 28, 4),
    (9.8, 13, 1)
]
with connection.cursor() as cursor:
    cursor.executemany(insert_ratings_query, ratings_records)
    connection.commit()

All three tables are now populated with data. You now have a fully functional online movie rating database. The next step is to understand how to interact with this database.




Reading Records From the Database

Until now, you’ve been building your database. Now it’s time to perform some queries on it and find some interesting properties from this dataset. In this section, you’ll learn how to read records from database tables using the SELECT déclaration.


Reading Records Using the SELECT Statement

To retrieve records, you need to send a SELECT query to cursor.execute() . Then you use cursor.fetchall() to extract the retrieved table in the form of a list of rows or records.

Try writing a MySQL query to select all records from the movies table and send it to .execute() :

>>>
>>> select_movies_query = "SELECT * FROM movies LIMIT 5"
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     result = cursor.fetchall()
...     for row in result:
...         print(row)
...
(1, 'Forrest Gump', 1994, 'Drama', Decimal('330.2'))
(2, '3 Idiots', 2009, 'Drama', Decimal('2.4'))
(3, 'Eternal Sunshine of the Spotless Mind', 2004, 'Drama', Decimal('34.5'))
(4, 'Good Will Hunting', 1997, 'Drama', Decimal('138.1'))
(5, 'Skyfall', 2012, 'Action', Decimal('304.6'))

The result variable holds the records returned from using .fetchall() . It’s a list of tuples representing individual records from the table.

In the query above, you use the LIMIT clause to constrain the number of rows that are received from the SELECT déclaration. Developers often use LIMIT to perform pagination when handling large volumes of data.

In MySQL, the LIMIT clause takes one or two nonnegative numeric arguments. When using one argument, you specify the maximum number of rows to return. Since your query includes LIMIT 5 , only the first 5 records are fetched. When using both arguments, you can also specify the offset of the first row to return:

SELECT * FROM movies LIMIT 2,5;

The first argument specifies an offset of 2 , and the second argument constrains the number of returned rows to 5 . The above query will return rows 3 to 7.

You can also query for selected columns:

>>>
>>> select_movies_query = "SELECT title, release_year FROM movies LIMIT 5"
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for row in cursor.fetchall():
...         print(row)
...
('Forrest Gump', 1994)
('3 Idiots', 2009)
('Eternal Sunshine of the Spotless Mind', 2004)
('Good Will Hunting', 1997)
('Skyfall', 2012)

Now, the code outputs values only from the two specified columns:title and release_year .



Filtering Results Using the WHERE Clause

You can filter table records by specific criteria using the WHERE clause. For example, to retrieve all movies with a box office collection greater than $300 million, you could run the following query:

SELECT title, collection_in_mil
FROM movies
WHERE collection_in_mil > 300;

You can also use ORDER BY clause in the last query to sort the results from the highest to the lowest earner:

>>>
>>> select_movies_query = """
... SELECT title, collection_in_mil
... FROM movies
... WHERE collection_in_mil > 300
... ORDER BY collection_in_mil DESC
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Avengers: Endgame', Decimal('858.8'))
('Titanic', Decimal('659.2'))
('The Dark Knight', Decimal('535.4'))
('Toy Story 4', Decimal('434.9'))
('The Lion King', Decimal('423.6'))
('Deadpool', Decimal('363.6'))
('Forrest Gump', Decimal('330.2'))
('Skyfall', Decimal('304.6'))

MySQL offers a plethora of string formatting operations like CONCAT for concatenating strings. Often, websites will show the movie title along with its release year to avoid confusion. To retrieve the titles of the top five grossing movies, concatenated with their release years, you can write the following query:

>>>
>>> select_movies_query = """
... SELECT CONCAT(title, " (", release_year, ")"),
...       collection_in_mil
... FROM movies
... ORDER BY collection_in_mil DESC
... LIMIT 5
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Avengers: Endgame (2019)', Decimal('858.8'))
('Titanic (1997)', Decimal('659.2'))
('The Dark Knight (2008)', Decimal('535.4'))
('Toy Story 4 (2019)', Decimal('434.9'))
('The Lion King (1994)', Decimal('423.6'))

If you don’t want to use the LIMIT clause and you don’t need to fetch all the records, then the cursor object has .fetchone() and .fetchmany() methods as well:

  • .fetchone() retrieves either the next row of the result, as a tuple, or None if no more rows are available.
  • .fetchmany() retrieves the next set of rows from the result as a list of tuples. It has a size argument, which defaults to 1 , that you can use to specify the number of rows you need to fetch. If no more rows are available, then the method returns an empty list.

Try retrieving the titles of the five highest-grossing movies concatenated with their release years again, but this time use .fetchmany() :

>>>
>>> select_movies_query = """
... SELECT CONCAT(title, " (", release_year, ")"),
...       collection_in_mil
... FROM movies
... ORDER BY collection_in_mil DESC
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchmany(size=5):
...         print(movie)
...     cursor.fetchall()
...
('Avengers: Endgame (2019)', Decimal('858.8'))
('Titanic (1997)', Decimal('659.2'))
('The Dark Knight (2008)', Decimal('535.4'))
('Toy Story 4 (2019)', Decimal('434.9'))
('The Lion King (1994)', Decimal('423.6'))

The output with .fetchmany() is similar to what you received when you used the LIMIT clause. You might have noticed the additional cursor.fetchall() call at the end. You do this to clean all the remaining results that weren’t read by .fetchmany() .

It’s necessary to clean all unread results before executing any other statements on the same connection. Otherwise, an InternalError: Unread result found exception will be raised.




Handling Multiple Tables Using the JOIN Statement

If you found the queries in the last section to be quite straightforward, don’t worry. You can make your SELECT queries as complex as you want using the same methods from the last section.

Let’s look at some slightly more complex JOIN requêtes. If you want to find out the name of the top five highest-rated movies in your database, then you can run the following query:

>>>
>>> select_movies_query = """
... SELECT title, AVG(rating) as average_rating
... FROM ratings
... INNER JOIN movies
...     ON movies.id = ratings.movie_id
... GROUP BY movie_id
... ORDER BY average_rating DESC
... LIMIT 5
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Night of the Living Dead', Decimal('9.90000'))
('The Godfather', Decimal('9.90000'))
('Avengers: Endgame', Decimal('9.75000'))
('Eternal Sunshine of the Spotless Mind', Decimal('8.90000'))
('Beasts of No Nation', Decimal('8.70000'))

As shown above, Night of the Living Dead and The Godfather are tied as the highest-rated movies in your online_movie_rating base de données.

To find the name of the reviewer who gave the most ratings, write the following query:

>>>
>>> select_movies_query = """
... SELECT CONCAT(first_name, " ", last_name), COUNT(*) as num
... FROM reviewers
... INNER JOIN ratings
...     ON reviewers.id = ratings.reviewer_id
... GROUP BY reviewer_id
... ORDER BY num DESC
... LIMIT 1
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
('Mary Cooper', 4)

Mary Cooper is the most frequent reviewer in this database. As seen above, it doesn’t matter how complicated the query is because it’s ultimately handled by the MySQL server. Your process for executing a query will always remain the same:pass the query to cursor.execute() and fetch the results using .fetchall() .



Updating and Deleting Records From the Database

In this section, you’ll be updating and deleting records from the database. Both of these operations can be performed on either a single record or multiple records in the table. You’ll select the rows that need to be modified using the WHERE clause.


UPDATE Command

One of the reviewers in your database, Amy Farah Fowler , is now married to Sheldon Cooper . Her last name has now changed to Cooper , so you need to update your database accordingly. For updating records, MySQL uses the UPDATE déclaration :

update_query = """
UPDATE
    reviewers
SET
    last_name = "Cooper"
WHERE
    first_name = "Amy"
"""
with connection.cursor() as cursor:
    cursor.execute(update_query)
    connection.commit()

The code passes the update query to cursor.execute() , and .commit() brings the required changes to the reviewers tableau.

Remarque : In the UPDATE query, the WHERE clause helps specify the records that need to be updated. If you don’t use WHERE , then all records will be updated!

Suppose you need to provide an option that allows reviewers to modify ratings. A reviewer will provide three values, movie_id , reviewer_id , and the new rating . The code will display the record after performing the specified modification.

Assuming that movie_id = 18 , reviewer_id = 15 , and the new rating = 5.0 , you can use the following MySQL queries to perform the required modification:

UPDATE
    ratings
SET
    rating = 5.0
WHERE
    movie_id = 18 AND reviewer_id = 15;

SELECT *
FROM ratings
WHERE
    movie_id = 18 AND reviewer_id = 15;

The above queries first update the rating and then display it. You can create a complete Python script that establises a connection with the database and allows the reviewer to modify a rating:

from getpass import getpass
from mysql.connector import connect, Error

movie_id = input("Enter movie id: ")
reviewer_id = input("Enter reviewer id: ")
new_rating = input("Enter new rating: ")
update_query = """
UPDATE
    ratings
SET
    rating = "%s"
WHERE
    movie_id = "%s" AND reviewer_id = "%s";

SELECT *
FROM ratings
WHERE
    movie_id = "%s" AND reviewer_id = "%s"
""" % (
    new_rating,
    movie_id,
    reviewer_id,
    movie_id,
    reviewer_id,
)

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
        database="online_movie_rating",
    ) as connection:
        with connection.cursor() as cursor:
            for result in cursor.execute(update_query, multi=True):
                if result.with_rows:
                    print(result.fetchall())
            connection.commit()
except Error as e:
    print(e)

Save this code to a file named modify_ratings.py . The above code uses %s placeholders to insert the received input in the update_query corde. For the first time in this tutorial, you have multiple queries inside a single string. To pass multiple queries to a single cursor.execute() , you need to set the method’s multi argument to True .

If multi is True , then cursor.execute() returns an iterator. Each item in the iterator corresponds to a cursor object that executes a statement passed in the query. The above code runs a for loop on this iterator and then calls .fetchall() on each cursor objet.

Remarque : Running .fetchall() on all cursor objects is important. To execute a new statement on the same connection, you must ensure that there are no unread results from previous executions. If there are unread results, then you’ll receive an exception.

If no result set is fetched on an operation, then .fetchall() raises an exception. To avoid this error, in the code above you use the cursor.with_rows property, which indicates whether the most recently executed operation produced rows.

While this code should solve your purpose, the WHERE clause is a prime target for web hackers in its current state. It’s vulnerable to what is called a SQL injection attack, which can allow malicious actors to either corrupt or misuse your database.

Avertissement :Don’t try the below inputs on your database! They will corrupt your table and you’ll need to recreate it.

For example, if a user sends movie_id=18 , reviewer_id=15 , and the new rating=5.0 as input, then the output looks like this:

$ python modify_ratings.py
Enter movie id: 18
Enter reviewer id: 15
Enter new rating: 5.0
Enter username: <user_name>
Enter password:
[(18, 15, Decimal('5.0'))]

The rating with movie_id=18 and reviewer_id=15 has been changed to 5.0 . But if you were hacker, then you might send a hidden command in your input:

$ python modify_ratings.py
Enter movie id: 18
Enter reviewer id: 15"; UPDATE reviewers SET last_name = "A
Enter new rating: 5.0
Enter username: <user_name>
Enter password:
[(18, 15, Decimal('5.0'))]

Again, the output shows that the specified rating has been changed to 5.0 . What’s changed?

The hacker sneaked in an update query while entering the reviewer_id . The update query, update reviewers set last_name = "A , changes the last_name of all records in the reviewers table to "A" . You can see this change if you print out the reviewers tableau :

>>>
>>> select_query = """
... SELECT first_name, last_name
... FROM reviewers
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_query)
...     for reviewer in cursor.fetchall():
...         print(reviewer)
...
('Chaitanya', 'A')
('Mary', 'A')
('John', 'A')
('Thomas', 'A')
('Penny', 'A')
('Mitchell', 'A')
('Wyatt', 'A')
('Andre', 'A')
('Sheldon', 'A')
('Kimbra', 'A')
('Kat', 'A')
('Bruce', 'A')
('Domingo', 'A')
('Rajesh', 'A')
('Ben', 'A')
('Mahinder', 'A')
('Akbar', 'A')
('Howard', 'A')
('Pinkie', 'A')
('Gurkaran', 'A')
('Amy', 'A')
('Marlon', 'A')

The above code displays the first_name et last_name for all records in the reviewers table. The SQL injection attack corrupted this table by changing the last_name of all records to "A" .

There’s a quick fix to prevent such attacks. Don’t add the query values provided by the user directly to your query string. Instead, update the modify_ratings.py script to send these query values as arguments to .execute() :

from getpass import getpass
from mysql.connector import connect, Error

movie_id = input("Enter movie id: ")
reviewer_id = input("Enter reviewer id: ")
new_rating = input("Enter new rating: ")
update_query = """
UPDATE
    ratings
SET
    rating = %s
WHERE
    movie_id = %s AND reviewer_id = %s;

SELECT *
FROM ratings
WHERE
    movie_id = %s AND reviewer_id = %s
"""
val_tuple = (
    new_rating,
    movie_id,
    reviewer_id,
    movie_id,
    reviewer_id,
)

try:
    with connect(
        host="localhost",
        user=input("Enter username: "),
        password=getpass("Enter password: "),
        database="online_movie_rating",
    ) as connection:
        with connection.cursor() as cursor:
            for result in cursor.execute(update_query, val_tuple, multi=True):
                if result.with_rows:
                    print(result.fetchall())
            connection.commit()
except Error as e:
    print(e)

Notice that the %s placeholders are no longer in string quotes. Strings passed to the placeholders might contain some special characters. If necessary, these can be correctly escaped by the underlying library.

cursor.execute() makes sure that the values in the tuple received as argument are of the required data type. If a user tries to sneak in some problematic characters, then the code will raise an exception:

$ python modify_ratings.py
Enter movie id: 18
Enter reviewer id: 15"; UPDATE reviewers SET last_name = "A
Enter new rating: 5.0
Enter username: <user_name>
Enter password:
1292 (22007): Truncated incorrect DOUBLE value: '15";
UPDATE reviewers SET last_name = "A'

cursor.execute() will raise an exception if it finds any unwanted characters in the user input. You should use this approach whenever you incorporate user input in a query. There are other ways of preventing SQL injection attacks as well.



DELETE Command

Deleting records works very similarly to updating records. You use the DELETE statement to remove selected records.

Remarque : Deleting is an irreversible process. If you don’t use the WHERE clause, then all records from the specified table will be deleted. You’ll need to run the INSERT INTO query again to get back the deleted records.

It’s recommended that you first run a SELECT query with the same filter to make sure that you’re deleting the right records. For example, to remove all ratings given by reviewer_id = 2 , you should first run the corresponding SELECT query:

>>>
>>> select_movies_query = """
... SELECT reviewer_id, movie_id FROM ratings
... WHERE reviewer_id = 2
... """
>>> with connection.cursor() as cursor:
...     cursor.execute(select_movies_query)
...     for movie in cursor.fetchall():
...         print(movie)
...
(2, 7)
(2, 8)
(2, 12)
(2, 23)

The above code snippet outputs the reviewer_id and movie_id for records in the ratings table where reviewer_id = 2 . Once you’ve confirmed that these are the records that you need to delete, you can run a DELETE query with the same filter:

delete_query = "DELETE FROM ratings WHERE reviewer_id = 2"
with connection.cursor() as cursor:
    cursor.execute(delete_query)
    connection.commit()

With this query, you remove all ratings given by the reviewer with reviewer_id = 2 from the ratings tableau.




Other Ways to Connect Python and MySQL

In this tutorial, you saw MySQL Connector/Python, which is the officially recommended means of interacting with a MySQL database from a Python application. There are two other popular connectors:

  1. mysqlclient is a library that is a close competitor to the official connector and is actively updated with new features. Because its core is written in C, it has better performance than the pure-Python official connector. A big drawback is that it’s fairly difficult to set up and install, especially on Windows.

  2. MySQLdb is a legacy software that’s still used in commercial applications. It’s written in C and is faster than MySQL Connector/Python but is available only for Python 2.

These connectors act as interfaces between your program and a MySQL database, and you send your SQL queries through them. But many developers prefer using an object-oriented paradigm rather than SQL queries to manipulate data.

Object-relational mapping (ORM) is a technique that allows you to query and manipulate data from a database directly using an object-oriented language. An ORM library encapsulates the code needed to manipulate data, which eliminates the need to use even a tiny bit of SQL. Here are the most popular Python ORMs for SQL-based databases:

  1. SQLAlchemy is an ORM that facilitates communication between Python and other SQL databases. You can create different engines for different databases like MySQL, PostgreSQL, SQLite, and so on. SQLAlchemy is commonly used alongside the pandas library to provide complete data-handling functionality.

  2. peewee is a lightweight and fast ORM that’s quick to set up. This is quite useful when your interaction with the database is limited to extracting a few records. For example, if you need to copy selected records from a MySQL database into a CSV file, then peewee might be your best choice.

  3. Django ORM is one of the most powerful features of Django and is supplied alongside the Django web framework. It can interact with a variety of databases such as SQLite, PostgreSQL, and MySQL. Many Django-based applications use the Django ORM for data modeling and basic queries but often switch to SQLAlchemy for more complex requirements.

You might find one of these approaches to be more suitable for your application. If you’re not sure which one to use, then it’s best to go with the officially recommended MySQL Connector/Python that you saw in action in this tutorial.



Conclusion

In this tutorial, you saw how to use MySQL Connector/Python to integrate a MySQL database with your Python application. You also saw some unique features of a MySQL database that differentiate it from other SQL databases.

Along the way, you learned some programming best practices that are worth considering when it comes to establishing a connection, creating tables, and inserting and updating records in a database application. You also developed a sample MySQL database for an online movie rating system and interacted with it directly from your Python application.

In this tutorial, you learned how to:

  • Connect your Python app with a MySQL database
  • Bring data from a MySQL database into Python for further analysis
  • Execute SQL queries from your Python application
  • Handle exceptions while accessing the database
  • Prevent SQL injection attacks on your application

If you’re interested, Python also has connectors for other DBMSs like MongoDB and PostgreSQL. For more information, check out Python Database Tutorials.