sql >> Base de Datos >  >> RDS >> Mysql

Base de datos Python y MySQL:una introducción práctica

MySQL es uno de los sistemas de gestión de bases de datos (DBMS) más populares del mercado actual. Ocupó el segundo lugar después de Oracle DBMS en el DB-Engines Ranking de este año. Como la mayoría de las aplicaciones de software necesitan interactuar con los datos de alguna forma, los lenguajes de programación como Python brindan herramientas para almacenar y acceder a estas fuentes de datos.

Usando las técnicas discutidas en este tutorial, podrá integrar de manera eficiente una base de datos MySQL con una aplicación de Python. Desarrollará una pequeña base de datos MySQL para un sistema de clasificación de películas y aprenderá a consultarla directamente desde su código de Python.

Al final de este tutorial, podrá:

  • Identificar características únicas de MySQL
  • Conecta tu aplicación a una base de datos MySQL
  • Consulte la base de datos para obtener los datos requeridos
  • Manejar excepciones que ocurren al acceder a la base de datos
  • Usar prácticas recomendadas mientras crea aplicaciones de bases de datos

Para aprovechar al máximo este tutorial, debe tener un conocimiento práctico de los conceptos de Python como for bucles, funciones, manejo de excepciones e instalación de paquetes de Python usando pip . También debe tener una comprensión básica de los sistemas de administración de bases de datos relacionales y consultas SQL como SELECT , DROP , CREATE y JOIN .

Descarga gratuita: Obtenga un capítulo de muestra de Python Tricks:The Book que le muestra las mejores prácticas de Python con ejemplos simples que puede aplicar instantáneamente para escribir un código Pythonic más hermoso.


Comparando MySQL con otras bases de datos SQL

SQL significa lenguaje de consulta estructurado y es un lenguaje de programación ampliamente utilizado para administrar bases de datos relacionales. Es posible que haya oído hablar de los diferentes tipos de DBMS basados ​​en SQL. Los más populares incluyen MySQL, PostgreSQL, SQLite y SQL Server. Todas estas bases de datos cumplen con los estándares SQL pero con diversos grados de cumplimiento.

Ser de código abierto desde su creación en 1995, MySQL se convirtió rápidamente en líder del mercado entre las soluciones SQL. MySQL también es parte del ecosistema de Oracle. Si bien su funcionalidad principal es completamente gratuita, también hay algunos complementos pagos. Actualmente, MySQL es utilizado por todas las principales empresas de tecnología, incluidas Google, LinkedIn, Uber, Netflix, Twitter y otras.

Aparte de una gran comunidad de código abierto para soporte, hay muchas otras razones para el éxito de MySQL:

  1. Facilidad de instalación: MySQL fue diseñado para ser fácil de usar. Es bastante sencillo configurar una base de datos MySQL y varias herramientas de terceros ampliamente disponibles, como phpMyAdmin, agilizan aún más el proceso de configuración. MySQL está disponible para todos los principales sistemas operativos, incluidos Windows, macOS, Linux y Solaris.

  2. Velocidad: MySQL tiene la reputación de ser una solución de base de datos extremadamente rápida. Ocupa un espacio relativamente pequeño y es extremadamente escalable a largo plazo.

  3. Privilegios de usuario y seguridad: MySQL viene con un script que le permite establecer el nivel de seguridad de la contraseña, asignar contraseñas de administrador y agregar y eliminar privilegios de cuenta de usuario. Este script simplifica el proceso de administración de un portal de gestión de usuarios de alojamiento web. Otros DBMS, como PostgreSQL, usan archivos de configuración que son más complicados de usar.

Si bien MySQL es famoso por su velocidad y facilidad de uso, puede obtener funciones más avanzadas con PostgreSQL. Además, MySQL no es totalmente compatible con SQL y tiene ciertas limitaciones funcionales, como no es compatible con FULL JOIN cláusulas.

También puede enfrentar algunos problemas con la lectura y escritura simultáneas en MySQL. Si su software tiene muchos usuarios escribiendo datos a la vez, entonces PostgreSQL podría ser una opción más adecuada.

Nota: Para obtener una comparación más detallada de MySQL y PostgreSQL en un contexto del mundo real, consulte Por qué Uber Engineering cambió de Postgres a MySQL.

SQL Server también es un DBMS muy popular y es conocido por su confiabilidad, eficiencia y seguridad. Es el preferido por las empresas, especialmente en el ámbito bancario, que regularmente se enfrentan a grandes cargas de trabajo de tráfico. Es una solución comercial y es uno de los sistemas más compatibles con los servicios de Windows.

En 2010, cuando Oracle adquirió Sun Microsystems y MySQL, muchos estaban preocupados por el futuro de MySQL. En ese momento, Oracle era el mayor competidor de MySQL. Los desarrolladores temían que se tratara de una adquisición hostil de Oracle con el objetivo de destruir MySQL.

Varios desarrolladores dirigidos por Michael Widenius, el autor original de MySQL, crearon una bifurcación del código base de MySQL y sentaron las bases de MariaDB. El objetivo era asegurar el acceso a MySQL y mantenerlo gratuito para siempre.

Hasta la fecha, MariaDB mantiene la licencia GPL completa, manteniéndola completamente en el dominio público. Algunas características de MySQL, por otro lado, están disponibles solo con licencias pagas. Además, MariaDB proporciona varias funciones extremadamente útiles que no son compatibles con el servidor MySQL, como SQL distribuido y almacenamiento en columnas. Puede encontrar más diferencias entre MySQL y MariaDB en el sitio web de MariaDB.

MySQL usa una sintaxis muy similar al SQL estándar. Sin embargo, hay algunas diferencias notables mencionadas en la documentación oficial.



Instalación de MySQL Server y MySQL Connector/Python

Ahora, para comenzar a trabajar con este tutorial, debe configurar dos cosas:un servidor MySQL y un conector MySQL . El servidor MySQL proporcionará todos los servicios necesarios para el manejo de su base de datos. Una vez que el servidor esté en funcionamiento, puede conectar su aplicación Python con MySQL Connector/Python.


Instalación del servidor MySQL

La documentación oficial detalla la forma recomendada de descargar e instalar el servidor MySQL. Encontrará instrucciones para todos los sistemas operativos populares, incluidos Windows, macOS, Solaris, Linux y muchos más.

Para Windows, la mejor manera es descargar MySQL Installer y dejar que se encargue de todo el proceso. El administrador de instalación también lo ayuda a configurar los ajustes de seguridad del servidor MySQL. En la página Cuentas y roles, debe ingresar una contraseña para el raíz (administrador) y, opcionalmente, agregar otros usuarios con diferentes privilegios:

Si bien debe especificar las credenciales para la cuenta raíz durante la configuración, puede modificar esta configuración más adelante.

Nota: Recuerde el nombre de host, el nombre de usuario y la contraseña, ya que serán necesarios para establecer una conexión con el servidor MySQL más adelante.

Aunque solo necesita el servidor MySQL para este tutorial, también puede configurar otras herramientas útiles como MySQL Workbench usando estos instaladores. Si no desea instalar MySQL directamente en su sistema operativo, implementar MySQL en Linux con Docker es una alternativa conveniente.



Instalación del conector MySQL/Python

Un controlador de base de datos es una pieza de software que permite que una aplicación se conecte e interactúe con un sistema de base de datos. Los lenguajes de programación como Python necesitan un controlador especial antes de que puedan comunicarse con una base de datos de un proveedor específico.

Estos controladores normalmente se obtienen como módulos de terceros. La API de la base de datos de Python (DB-API) define la interfaz estándar con la que deben cumplir todos los controladores de base de datos de Python. Estos detalles están documentados en PEP 249. Todos los controladores de bases de datos de Python, como sqlite3 para SQLite, psycopg para PostgreSQL y MySQL Connector/Python para MySQL, siguen estas reglas de implementación.

Nota: La documentación oficial de MySQL usa el término conector en lugar de conductor . Técnicamente, los conectores están asociados solo con la conexión a una base de datos, no con la interacción con ella. Sin embargo, el término se usa a menudo para todo el módulo de acceso a la base de datos que comprende el conector y el conductor.

Para mantener la coherencia con la documentación, verá el término conector cada vez que se menciona MySQL.

Muchos lenguajes de programación populares tienen su propia API de base de datos. Por ejemplo, Java tiene la API de conectividad de bases de datos de Java (JDBC). Si necesita conectar una aplicación Java a una base de datos MySQL, debe usar el conector JDBC de MySQL, que sigue a la API de JDBC.

De manera similar, en Python necesita instalar un conector Python MySQL para interactuar con una base de datos MySQL. Muchos paquetes siguen los estándares DB-API, pero el más popular entre ellos es MySQL Connector/Python. Puedes conseguirlo con pip :

$ pip install mysql-connector-python

pip instala el conector como un módulo de terceros en el entorno virtual actualmente activo. Se recomienda configurar un entorno virtual aislado para el proyecto junto con todas las dependencias.

Para probar si la instalación fue exitosa, escriba el siguiente comando en su terminal de Python:

>>>
>>> import mysql.connector

Si el código anterior se ejecuta sin errores, entonces mysql.connector está instalado y listo para usar. Si encuentra algún error, asegúrese de estar en el entorno virtual correcto y de estar utilizando el intérprete de Python adecuado.

Asegúrese de instalar el mysql-connector-python correcto. paquete, que es una implementación pura de Python. Tenga cuidado con los conectores con nombres similares pero ahora despreciados como mysql-connector .




Establecimiento de una conexión con el servidor MySQL

MySQL es un basado en servidor sistema de administración de base de datos. Un servidor puede contener varias bases de datos. Para interactuar con una base de datos, primero debe establecer una conexión con el servidor. El flujo de trabajo general de un programa de Python que interactúa con una base de datos basada en MySQL es el siguiente:

  1. Conéctese al servidor MySQL.
  2. Cree una nueva base de datos.
  3. Conéctese a la base de datos recién creada o existente.
  4. Ejecutar una consulta SQL y obtener resultados.
  5. Informar a la base de datos si se realizan cambios en una tabla.
  6. Cierre la conexión con el servidor MySQL.

Este es un flujo de trabajo genérico que puede variar según la aplicación individual. Pero cualquiera que sea la aplicación, el primer paso es conectar su base de datos con su aplicación.


Establecer una conexión

El primer paso para interactuar con un servidor MySQL es establecer una conexión. Para hacer esto, necesitas connect() desde el mysql.connector módulo. Esta función toma parámetros como host , user y password y devuelve una MySQLConnection objeto. Puede recibir estas credenciales como entrada del usuario y pasarlas a 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)

El código anterior utiliza las credenciales de inicio de sesión ingresadas para establecer una conexión con su servidor MySQL. A cambio, obtienes una MySQLConnection objeto, que se almacena en la connection variable. A partir de ahora, utilizará esta variable para acceder a su servidor MySQL.

Hay varias cosas importantes a tener en cuenta en el código anterior:

  • Siempre debe lidiar con las excepciones que pueden surgir al establecer una conexión con el servidor MySQL. Es por eso que usa un tryexcept block para capturar e imprimir cualquier excepción que pueda encontrar.

  • Siempre debe cerrar la conexión una vez que haya terminado de acceder a la base de datos. Dejar conexiones abiertas sin usar puede provocar varios errores inesperados y problemas de rendimiento. El código anterior aprovecha un administrador de contexto que usa with , que abstrae el proceso de limpieza de la conexión.

  • Nunca debe codificar sus credenciales de inicio de sesión , es decir, tu nombre de usuario y contraseña, directamente en un script de Python. Esta es una mala práctica para la implementación y representa una grave amenaza para la seguridad. El código anterior solicita al usuario las credenciales de inicio de sesión. Utiliza el getpass incorporado módulo para ocultar la contraseña. Si bien esto es mejor que la codificación fija, existen otras formas más seguras de almacenar información confidencial, como usar variables de entorno.

Ahora ha establecido una conexión entre su programa y su servidor MySQL, pero aún necesita crear una nueva base de datos o conectarse a una base de datos existente dentro del servidor.



Crear una nueva base de datos

En la última sección, estableció una conexión con su servidor MySQL. Para crear una nueva base de datos, debe ejecutar una instrucción SQL:

CREATE DATABASE books_db;

La declaración anterior creará una nueva base de datos con el nombre books_db .

Nota: En MySQL, es obligatorio poner un punto y coma (; ) al final de una declaración, lo que denota la finalización de una consulta. Sin embargo, MySQL Connector/Python agrega automáticamente un punto y coma al final de sus consultas, por lo que no es necesario usarlo en su código de Python.

Para ejecutar una consulta SQL en Python, deberá usar un cursor, que abstrae el acceso a los registros de la base de datos. MySQL Connector/Python le proporciona el MySQLCursor class, que crea instancias de objetos que pueden ejecutar consultas MySQL en Python. Una instancia de MySQLCursor la clase también se denomina cursor .

cursor los objetos hacen uso de una MySQLConnection objeto para interactuar con su servidor MySQL. Para crear un cursor , usa el .cursor() método de su connection variables:

cursor = connection.cursor()

El código anterior le brinda una instancia de MySQLCursor clase.

Una consulta que debe ejecutarse se envía a cursor.execute() en formato de cadena. En esta ocasión en particular, enviarás el CREATE DATABASE consulta a 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)

Después de ejecutar el código anterior, tendrá una nueva base de datos llamada online_movie_rating en su servidor MySQL.

El CREATE DATABASE la consulta se almacena como una cadena en create_db_query variable y luego se pasa a cursor.execute() para la ejecución. El código usa un administrador de contexto con el cursor objeto para manejar el proceso de limpieza.

Es posible que reciba un error aquí si ya existe una base de datos con el mismo nombre en su servidor. Para confirmar esto, puede mostrar el nombre de todas las bases de datos en su servidor. Usando la misma MySQLConnection objeto anterior, ejecute SHOW DATABASES declaración:

>>>
>>> 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',)

El código anterior imprime los nombres de todas las bases de datos actualmente en su servidor MySQL. El SHOW DATABASES El comando también genera algunas bases de datos que no creó en su servidor, como information_schema , performance_schema , y así. Estas bases de datos son generadas automáticamente por el servidor MySQL y brindan acceso a una variedad de metadatos de bases de datos y configuraciones del servidor MySQL.

Creó una nueva base de datos en esta sección ejecutando CREATE DATABASE declaración. En la siguiente sección, verá cómo conectarse a una base de datos que ya existe.



Conexión a una base de datos existente

En la última sección, creó una nueva base de datos llamada online_movie_rating . Sin embargo, todavía no te has conectado a él. En muchas situaciones, ya tendrá una base de datos MySQL que desea conectar con su aplicación Python.

Puedes hacer esto usando el mismo connect() función que usó anteriormente enviando un parámetro adicional llamado 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)

El código anterior es muy similar al script de conexión que usó anteriormente. El único cambio aquí es una database adicional parámetro, donde el nombre de su base de datos se pasa a connect() . Una vez que ejecute este script, estará conectado a online_movie_rating base de datos.




Creación, modificación y eliminación de una tabla

En esta sección, aprenderá cómo realizar algunas consultas DDL básicas como CREATE , DROP y ALTER con Pitón. Obtendrá un vistazo rápido a la base de datos MySQL que usará en el resto de este tutorial. También creará todas las tablas necesarias para la base de datos y aprenderá a realizar modificaciones en estas tablas más adelante.


Definir el esquema de la base de datos

Puede comenzar creando un esquema de base de datos para un sistema de calificación de películas en línea. La base de datos constará de tres tablas:

  1. movies contiene información general sobre películas y tiene los siguientes atributos:
    • id
    • title
    • release_year
    • genre
    • collection_in_mil
  2. reviewers contiene información sobre personas que publicaron reseñas o calificaciones y tiene los siguientes atributos:
    • id
    • first_name
    • last_name
  3. ratings contiene información sobre las calificaciones que se han publicado y tiene los siguientes atributos:
    • movie_id (clave externa)
    • reviewer_id (clave externa)
    • rating

Un sistema de calificación de películas del mundo real, como IMDb, necesitaría almacenar muchos otros atributos, como correos electrónicos, listas de actores de películas, etc. Si lo desea, puede agregar más tablas y atributos a esta base de datos. Pero estas tres tablas serán suficientes para el propósito de este tutorial.

La siguiente imagen muestra el esquema de la base de datos:

Las tablas de esta base de datos están relacionadas entre sí. movies y reviewers tendrá un muchos a muchos relación ya que una película puede ser revisada por varios revisores y un revisor puede revisar varias películas. Las ratings tabla conecta las movies mesa con los reviewers mesa.



Creación de tablas usando CREATE TABLE Declaración

Ahora, para crear una nueva tabla en MySQL, debe usar CREATE TABLE declaración. La siguiente consulta de MySQL creará las movies tabla para su online_movie_rating base de datos:

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

Si ha visto declaraciones SQL antes, entonces la mayoría de las consultas anteriores podrían tener sentido. Pero hay algunas diferencias en la sintaxis de MySQL que debe tener en cuenta.

Por ejemplo, MySQL tiene una amplia variedad de tipos de datos para su lectura, incluido YEAR , INT , BIGINT , y así. Además, MySQL usa el AUTO_INCREMENT palabra clave cuando el valor de una columna debe incrementarse automáticamente al insertar nuevos registros.

Para crear una nueva tabla, debe pasar esta consulta a cursor.execute() , que acepta una consulta MySQL y ejecuta la consulta en la base de datos MySQL conectada:

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()

Ahora tienes las movies tabla en su base de datos. Pasas create_movies_table_query a cursor.execute() , que realiza la ejecución requerida.

Nota: La connection variable se refiere a MySQLConnection objeto que se devolvió cuando se conectó a su base de datos.

Además, observe el connection.commit() declaración al final del código. De forma predeterminada, su conector MySQL no confirma automáticamente las transacciones. En MySQL, las modificaciones mencionadas en una transacción ocurren solo cuando usa un COMMIT mando al final. Siempre llame a este método después de cada transacción para realizar cambios en la tabla real.

Como hiciste con las movies table, ejecute el siguiente script para crear los reviewers tabla:

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 es necesario, puede agregar más información sobre un revisor, como su ID de correo electrónico o información demográfica. Pero first_name y last_name servirá a su propósito por ahora.

Finalmente, puedes crear las ratings tabla usando el siguiente script:

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()

La implementación de relaciones de clave externa en MySQL es ligeramente diferente y limitada en comparación con SQL estándar. En MySQL, tanto el padre como el hijo en la restricción de clave externa deben usar el mismo motor de almacenamiento .

Un motor de almacenamiento es el componente de software subyacente que utiliza un sistema de gestión de bases de datos para realizar operaciones de SQL. En MySQL, los motores de almacenamiento vienen en dos sabores diferentes:

  1. Motores de almacenamiento transaccional son transacciones seguras y le permiten revertir transacciones usando comandos simples como rollback . Muchos motores populares de MySQL, incluidos InnoDB y NDB, pertenecen a esta categoría.

  2. Motores de almacenamiento no transaccional dependen de un código manual elaborado para deshacer las declaraciones confirmadas en una base de datos. MyISAM, MEMORY y muchos otros motores de MySQL no son transaccionales.

InnoDB es el motor de almacenamiento predeterminado y más popular. Ayuda a mantener la integridad de los datos al admitir restricciones de clave externa. Esto significa que cualquier operación CRUD en una clave externa se verifica para garantizar que no genere inconsistencias en diferentes tablas.

Además, tenga en cuenta que las ratings la tabla usa las columnas movie_id y reviewer_id , ambas claves foráneas, conjuntamente como la clave principal . Este paso garantiza que un revisor no pueda calificar la misma película dos veces.

Puede elegir reutilizar el mismo cursor para múltiples ejecuciones. En ese caso, todas las ejecuciones se convertirían en una transacción atómica en lugar de múltiples transacciones separadas. Por ejemplo, puede ejecutar todos los CREATE TABLE declaraciones con un cursor y luego confirme su transacción solo una vez:

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()

El código anterior ejecutará primero los tres CREATE declaraciones. Luego enviará un COMMIT comando al servidor MySQL que confirma su transacción. También puede usar .rollback() para enviar un ROLLBACK comando al servidor MySQL y eliminar todos los cambios de datos de la transacción.



Mostrar un esquema de tabla usando DESCRIBE Declaración

Ahora que ha creado las tres tablas, puede ver su esquema usando la siguiente instrucción SQL:

DESCRIBE <table_name>;

Para obtener algunos resultados del cursor objeto, necesita usar cursor.fetchall() . Este método obtiene todas las filas de la última declaración ejecutada. Suponiendo que ya tiene la MySQLConnection objeto en la connection variable, puede imprimir todos los resultados obtenidos por 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, '')

Una vez que ejecute el código anterior, debería recibir una tabla que contiene información sobre todas las columnas en movies mesa. Para cada columna, recibirá detalles como el tipo de datos de la columna, si la columna es una clave principal, etc.



Modificar un esquema de tabla usando ALTER Declaración

En las movies tabla, tiene una columna llamada collection_in_mil , que contiene la recaudación de taquilla de una película en millones de dólares. Puede escribir la siguiente instrucción MySQL para modificar el tipo de datos de collection_in_mil atributo de INT a DECIMAL :

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

DECIMAL(4,1) significa un número decimal que puede tener un máximo de 4 dígitos, de los cuales 1 es decimal, como 120.1 , 3.4 , 38.0 , y así. Después de ejecutar ALTER TABLE instrucción, puede mostrar el esquema de tabla actualizado usando 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, '')

Como se muestra en el resultado, collection_in_mil el atributo ahora es de tipo DECIMAL(4,1) . También tenga en cuenta que en el código anterior, llama a cursor.execute() dos veces. Pero cursor.fetchall() obtiene filas solo de la última consulta ejecutada, que es show_table_query .



Eliminar tablas usando DROP Declaración

Para eliminar una tabla, debe ejecutar DROP TABLE declaración en MySQL. Eliminar una tabla es un irreversible proceso. Si ejecuta el código a continuación, deberá llamar a CREATE TABLE consulta de nuevo para usar las ratings tabla en las próximas secciones.

Para borrar las ratings tabla, envíe drop_table_query a cursor.execute() :

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

Si ejecuta el código anterior, habrá eliminado con éxito las ratings mesa.




Inserción de registros en tablas

En la última sección, creó tres tablas en su base de datos:movies , reviewers y ratings . Ahora necesita llenar estas tablas con datos. Esta sección cubrirá dos formas diferentes de insertar registros en MySQL Connector para Python.

El primer método, .execute() , funciona bien cuando el número de registros es pequeño y los registros se pueden codificar de forma rígida. El segundo método, .executemany() , es más popular y se adapta mejor a los escenarios del mundo real.


Usando .execute()

El primer enfoque usa el mismo cursor.execute() método que has estado usando hasta ahora. Escribes el INSERT INTO consulta en una cadena y pásala a cursor.execute() . Puede usar este método para insertar datos en las movies mesa.

Como referencia, las movies la tabla tiene cinco atributos:

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

No necesita agregar datos para id como AUTO_INCREMENT calcula automáticamente id para usted. El siguiente script inserta registros en las movies tabla:

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 table:

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 list.

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 table:

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 statement.


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 statement. 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 queries. 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 datos.

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 statement:

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 table.

Nota: 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 string. 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 object.

Nota: 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.

Warning :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 table:

>>>
>>> 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 and last_name for all records in the reviewers mesa. 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.

Nota: Deleting is an irreversible proceso. 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 table.




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.