Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Banco de dados Python e MySQL:uma introdução prática


O MySQL é um dos sistemas de gerenciamento de banco de dados (DBMSs) mais populares no mercado atualmente. Ele ficou em segundo lugar apenas para o Oracle DBMS no Ranking DB-Engines deste ano. Como a maioria dos aplicativos de software precisa interagir com os dados de alguma forma, linguagens de programação como Python fornecem ferramentas para armazenar e acessar essas fontes de dados.

Usando as técnicas discutidas neste tutorial, você poderá integrar eficientemente um banco de dados MySQL com um aplicativo Python. Você desenvolverá um pequeno banco de dados MySQL para um sistema de classificação de filmes e aprenderá a consultá-lo diretamente do seu código Python.

Ao final deste tutorial, você será capaz de:
  • Identifique recursos exclusivos do MySQL
  • Conecte seu aplicativo para um banco de dados MySQL
  • Consulte o banco de dados para buscar os dados necessários
  • Tratar exceções que ocorrem ao acessar o banco de dados
  • Use as práticas recomendadas ao construir aplicativos de banco de dados

Para tirar o máximo proveito deste tutorial, você deve ter um conhecimento prático dos conceitos do Python, como for loops, funções, tratamento de exceção e instalação de pacotes Python usando pip . Você também deve ter um conhecimento básico de sistemas de gerenciamento de banco de dados relacional e consultas SQL como SELECT , DROP , CREATE e JOIN .

Download gratuito: Obtenha um capítulo de amostra do Python Tricks:The Book que mostra as melhores práticas do Python com exemplos simples que você pode aplicar instantaneamente para escrever um código mais bonito + Pythonico.

Comparando o MySQL com outros bancos de dados SQL


SQL significa Structured Query Language e é uma linguagem de programação amplamente utilizada para gerenciar bancos de dados relacionais. Você já deve ter ouvido falar dos diferentes tipos de DBMSs baseados em SQL. Os mais populares incluem MySQL, PostgreSQL, SQLite e SQL Server. Todos esses bancos de dados são compatíveis com os padrões SQL, mas com graus variados de conformidade.

Ser código aberto desde sua criação em 1995, o MySQL rapidamente se tornou líder de mercado entre as soluções SQL. O MySQL também faz parte do ecossistema Oracle. Embora sua funcionalidade principal seja totalmente gratuita, também existem alguns complementos pagos. Atualmente, o MySQL é usado por todas as principais empresas de tecnologia, incluindo Google, LinkedIn, Uber, Netflix, Twitter e outros.

Além de uma grande comunidade de código aberto para suporte, existem muitas outras razões para o sucesso do MySQL:

  1. Facilidade de instalação: MySQL foi projetado para ser amigável. É bastante simples configurar um banco de dados MySQL e várias ferramentas de terceiros amplamente disponíveis, como o phpMyAdmin, simplificam ainda mais o processo de configuração. O MySQL está disponível para todos os principais sistemas operacionais, incluindo Windows, macOS, Linux e Solaris.

  2. Velocidade: O MySQL tem a reputação de ser uma solução de banco de dados extremamente rápida. Ele tem uma pegada relativamente menor e é extremamente escalável a longo prazo.

  3. Privilégios e segurança do usuário: O MySQL vem com um script que permite definir o nível de segurança da senha, atribuir senhas de administrador e adicionar e remover privilégios de conta de usuário. Esse script descomplica o processo de administração de um portal de gerenciamento de usuários de hospedagem na web. Outros SGBDs, como o PostgreSQL, usam arquivos de configuração que são mais complicados de usar.

Embora o MySQL seja famoso por sua velocidade e facilidade de uso, você pode obter recursos mais avançados com o PostgreSQL. Além disso, o MySQL não é totalmente compatível com SQL e tem certas limitações funcionais, como não há suporte para FULL JOIN cláusulas.

Você também pode enfrentar alguns problemas com leitura e escrita simultâneas no MySQL. Se o seu software tem muitos usuários gravando dados nele de uma só vez, o PostgreSQL pode ser uma escolha mais adequada.

Observação: Para uma comparação mais detalhada do MySQL e do PostgreSQL em um contexto do mundo real, confira Por que a Uber Engineering mudou do Postgres para o MySQL.

O SQL Server também é um DBMS muito popular e é conhecido por sua confiabilidade, eficiência e segurança. É preferido por empresas, especialmente no domínio bancário, que lidam regularmente com grandes cargas de trabalho de tráfego. É uma solução comercial e é um dos sistemas mais compatíveis com os serviços do Windows.

Em 2010, quando a Oracle adquiriu a Sun Microsystems e a MySQL, muitos estavam preocupados com o futuro da MySQL. Na época, a Oracle era o maior concorrente do MySQL. Os desenvolvedores temiam que esta fosse uma aquisição hostil da Oracle com o objetivo de destruir o MySQL.

Vários desenvolvedores liderados por Michael Widenius, o autor original do MySQL, criaram uma bifurcação da base de código do MySQL e lançaram as bases do MariaDB. O objetivo era proteger o acesso ao MySQL e mantê-lo livre para sempre.

Até o momento, o MariaDB permanece totalmente licenciado pela GPL, mantendo-o completamente em domínio público. Alguns recursos do MySQL, por outro lado, estão disponíveis apenas com licenças pagas. Além disso, o MariaDB fornece vários recursos extremamente úteis que não são suportados pelo servidor MySQL, como SQL distribuído e armazenamento colunar. Você pode encontrar mais diferenças entre MySQL e MariaDB listadas no site do MariaDB.

O MySQL usa uma sintaxe muito semelhante ao SQL padrão. Existem, no entanto, algumas diferenças notáveis ​​mencionadas na documentação oficial.


Instalando o MySQL Server e o MySQL Connector/Python


Agora, para começar a trabalhar neste tutorial, você precisa configurar duas coisas:um servidor MySQL e um conector MySQL . O servidor MySQL fornecerá todos os serviços necessários para lidar com seu banco de dados. Quando o servidor estiver funcionando, você poderá conectar seu aplicativo Python a ele usando o MySQL Connector/Python.

Instalando o servidor MySQL


A documentação oficial detalha a maneira recomendada de baixar e instalar o servidor MySQL. Você encontrará instruções para todos os sistemas operacionais populares, incluindo Windows, macOS, Solaris, Linux e muitos outros.

Para Windows, a melhor maneira é baixar o MySQL Installer e deixá-lo cuidar de todo o processo. O gerenciador de instalação também ajuda você a configurar as configurações de segurança do servidor MySQL. Na página Contas e Funções, você precisa inserir uma senha para o raiz (admin) e, opcionalmente, adicionar outros usuários com privilégios variados:

Embora você deva especificar credenciais para a conta root durante a configuração, você pode modificar essas configurações posteriormente.

Observação: Lembre-se do nome do host, nome de usuário e senha, pois eles serão necessários para estabelecer uma conexão com o servidor MySQL posteriormente.

Embora você só precise do servidor MySQL para este tutorial, você também pode configurar outras ferramentas úteis, como o MySQL Workbench, usando esses instaladores. Se você não deseja instalar o MySQL diretamente em seu sistema operacional, implantar o MySQL no Linux com o Docker é uma alternativa conveniente.


Instalando o MySQL Connector/Python


Um driver de banco de dados é um software que permite que um aplicativo se conecte e interaja com um sistema de banco de dados. Linguagens de programação como Python precisam de um driver especial antes que possam falar com um banco de dados de um fornecedor específico.

Esses drivers normalmente são obtidos como módulos de terceiros. A API de banco de dados Python (DB-API) define a interface padrão com a qual todos os drivers de banco de dados Python devem estar em conformidade. Esses detalhes estão documentados no PEP 249. Todos os drivers de banco de dados Python, como sqlite3 para SQLite, psycopg para PostgreSQL e MySQL Connector/Python para MySQL, seguem estas regras de implementação.

Observação: A documentação oficial do MySQL usa o termo conector em vez de motorista . Tecnicamente, os conectores estão associados apenas à conexão com um banco de dados, não à interação com ele. No entanto, o termo é frequentemente usado para todo o módulo de acesso ao banco de dados que compreende o conector e o motorista.

Para manter a consistência com a documentação, você verá o termo conector sempre que o MySQL é mencionado.

Muitas linguagens de programação populares têm sua própria API de banco de dados. Por exemplo, Java tem a API Java Database Connectivity (JDBC). Se você precisar conectar um aplicativo Java a um banco de dados MySQL, precisará usar o conector MySQL JDBC, que segue a API JDBC.

Da mesma forma, em Python você precisa instalar um conector Python MySQL para interagir com um banco de dados MySQL. Muitos pacotes seguem os padrões DB-API, mas o mais popular entre eles é o MySQL Connector/Python. Você pode obtê-lo com pip :
$ pip install mysql-connector-python

pip instala o conector como um módulo de terceiros no ambiente virtual atualmente ativo. É recomendável que você configure um ambiente virtual isolado para o projeto junto com todas as dependências.

Para testar se a instalação foi bem-sucedida, digite o seguinte comando em seu terminal Python:
>>>
>>> import mysql.connector

Se o código acima for executado sem erros, então mysql.connector está instalado e pronto para uso. Se você encontrar algum erro, verifique se está no ambiente virtual correto e se está usando o interpretador Python correto.

Certifique-se de estar instalando o mysql-connector-python correto pacote, que é uma implementação Python pura. Cuidado com conectores com nomes semelhantes, mas agora depreciados, como mysql-connector .



Estabelecer uma conexão com o servidor MySQL


MySQL é um baseado em servidor Sistema de gerenciamento de banco de dados. Um servidor pode conter vários bancos de dados. Para interagir com um banco de dados, você deve primeiro estabelecer uma conexão com o servidor. O fluxo de trabalho geral de um programa Python que interage com um banco de dados baseado em MySQL é o seguinte:
  1. Conecte-se ao servidor MySQL.
  2. Crie um novo banco de dados.
  3. Conecte-se ao banco de dados recém-criado ou existente.
  4. Execute uma consulta SQL e obtenha resultados.
  5. Informe o banco de dados se alguma alteração for feita em uma tabela.
  6. Feche a conexão com o servidor MySQL.

Este é um fluxo de trabalho genérico que pode variar dependendo do aplicativo individual. Mas seja qual for o aplicativo, o primeiro passo é conectar seu banco de dados com seu aplicativo.

Estabelecer uma conexão


O primeiro passo para interagir com um servidor MySQL é estabelecer uma conexão. Para fazer isso, você precisa de connect() do mysql.connector módulo. Esta função recebe parâmetros como host , user e password e retorna um MySQLConnection objeto. Você pode receber essas credenciais como entrada do usuário e passá-las para 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)

O código acima usa as credenciais de login inseridas para estabelecer uma conexão com seu servidor MySQL. Em troca, você recebe um MySQLConnection objeto, que é armazenado na connection variável. A partir de agora, você usará essa variável para acessar seu servidor MySQL.

Há várias coisas importantes a serem observadas no código acima:

  • Você deve sempre lidar com as exceções que podem surgir ao estabelecer uma conexão com o servidor MySQL. É por isso que você usa um tryexcept block para capturar e imprimir quaisquer exceções que você possa encontrar.

  • Você deve sempre fechar a conexão depois de terminar de acessar o banco de dados. Deixar conexões abertas não utilizadas pode levar a vários erros inesperados e problemas de desempenho. O código acima tira proveito de um gerenciador de contexto usando with , que abstrai o processo de limpeza de conexão.

  • Você nunca deve codificar suas credenciais de login , ou seja, seu nome de usuário e senha, diretamente em um script Python. Essa é uma prática ruim para implantação e representa uma séria ameaça à segurança. O código acima solicita ao usuário credenciais de login. Ele usa o getpass embutido módulo para ocultar a senha. Embora isso seja melhor do que codificar, existem outras maneiras mais seguras de armazenar informações confidenciais, como usar variáveis ​​de ambiente.

Você agora estabeleceu uma conexão entre seu programa e seu servidor MySQL, mas ainda precisa criar um novo banco de dados ou conectar-se a um banco de dados existente dentro do servidor.


Criando um novo banco de dados


Na última seção, você estabeleceu uma conexão com seu servidor MySQL. Para criar um novo banco de dados, você precisa executar uma instrução SQL:
CREATE DATABASE books_db;

A instrução acima criará um novo banco de dados com o nome books_db .

Observação: No MySQL, é obrigatório colocar um ponto e vírgula (; ) no final de uma instrução, que denota o término de uma consulta. No entanto, o MySQL Connector/Python anexa automaticamente um ponto e vírgula no final de suas consultas, portanto, não há necessidade de usá-lo em seu código Python.

Para executar uma consulta SQL em Python, você precisará usar um cursor, que abstrai o acesso aos registros do banco de dados. MySQL Connector/Python fornece o MySQLCursor class, que instancia objetos que podem executar consultas MySQL em Python. Uma instância do MySQLCursor classe também é chamada de cursor .

cursor objetos fazem uso de um MySQLConnection objeto para interagir com seu servidor MySQL. Para criar um cursor , use o .cursor() método de sua connection variável:
cursor = connection.cursor()

O código acima fornece uma instância do MySQLCursor aula.

Uma consulta que precisa ser executada é enviada para cursor.execute() em formato de string. Nesta ocasião específica, você enviará o CREATE DATABASE consulta para 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)

Após executar o código acima, você terá um novo banco de dados chamado online_movie_rating em seu servidor MySQL.

O CREATE DATABASE consulta é armazenada como uma string no create_db_query variável e, em seguida, passada para cursor.execute() para execução. O código usa um gerenciador de contexto com o cursor objeto para lidar com o processo de limpeza.

Você pode receber um erro aqui se um banco de dados com o mesmo nome já existir em seu servidor. Para confirmar isso, você pode exibir o nome de todos os bancos de dados em seu servidor. Usando o mesmo MySQLConnection objeto anterior, execute o SHOW DATABASES demonstração:
>>>
>>> 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',)

O código acima imprime os nomes de todos os bancos de dados atualmente em seu servidor MySQL. O SHOW DATABASES O comando também gera alguns bancos de dados que você não criou em seu servidor, como information_schema , performance_schema , e assim por diante. Esses bancos de dados são gerados automaticamente pelo servidor MySQL e fornecem acesso a uma variedade de metadados de banco de dados e configurações do servidor MySQL.

Você criou um novo banco de dados nesta seção executando o comando CREATE DATABASE demonstração. Na próxima seção, você verá como se conectar a um banco de dados que já existe.


Conectando a um banco de dados existente


Na última seção, você criou um novo banco de dados chamado online_movie_rating . No entanto, você ainda não se conectou a ele. Em muitas situações, você já terá um banco de dados MySQL que deseja conectar ao seu aplicativo Python.

Você pode fazer isso usando o mesmo connect() função que você usou anteriormente enviando um parâmetro adicional chamado 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)

O código acima é muito semelhante ao script de conexão usado anteriormente. A única mudança aqui é um database adicional parâmetro, onde o nome do seu banco de dados é passado para connect() . Depois de executar este script, você será conectado ao online_movie_rating base de dados.



Criando, alterando e descartando uma tabela


Nesta seção, você aprenderá como realizar algumas consultas DDL básicas como CREATE , DROP e ALTER com Python. Você verá rapidamente o banco de dados MySQL que usará no restante deste tutorial. Você também criará todas as tabelas necessárias para o banco de dados e aprenderá a fazer modificações nessas tabelas posteriormente.

Definindo o esquema do banco de dados


Você pode começar criando um esquema de banco de dados para um sistema de classificação de filmes online. O banco de dados será composto por três tabelas:
  1. movies contém informações gerais sobre filmes e possui os seguintes atributos:
    • id
    • title
    • release_year
    • genre
    • collection_in_mil
  2. reviewers contém informações sobre pessoas que postaram avaliações ou classificações e tem os seguintes atributos:
    • id
    • first_name
    • last_name
  3. ratings contém informações sobre avaliações que foram postadas e tem os seguintes atributos:
    • movie_id (chave estrangeira)
    • reviewer_id (chave estrangeira)
    • rating

Um sistema de classificação de filmes do mundo real, como o IMDb, precisaria armazenar vários outros atributos, como e-mails, listas de elenco de filmes e assim por diante. Se desejar, você pode adicionar mais tabelas e atributos a este banco de dados. Mas essas três tabelas serão suficientes para o propósito deste tutorial.

A imagem abaixo mostra o esquema do banco de dados:

As tabelas neste banco de dados estão relacionadas entre si. movies e reviewers terá um muitos-para-muitos uma vez que um filme pode ser revisado por vários revisores e um revisor pode revisar vários filmes. As ratings tabela conecta os movies tabela com os reviewers tabela.


Criando tabelas usando o CREATE TABLE Declaração


Agora, para criar uma nova tabela no MySQL, você precisa usar o CREATE TABLE demonstração. A seguinte consulta MySQL criará os movies tabela para seu online_movie_rating base de dados:
CREATE TABLE movies(
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(100),
    release_year YEAR(4),
    genre VARCHAR(100),
    collection_in_mil INT
);

Se você já olhou para instruções SQL antes, então a maior parte da consulta acima pode fazer sentido. Mas existem algumas diferenças na sintaxe do MySQL que você deve estar ciente.

Por exemplo, o MySQL tem uma grande variedade de tipos de dados para sua leitura, incluindo YEAR , INT , BIGINT , e assim por diante. Além disso, o MySQL usa o AUTO_INCREMENT palavra-chave quando um valor de coluna deve ser incrementado automaticamente na inserção de novos registros.

Para criar uma nova tabela, você precisa passar esta consulta para cursor.execute() , que aceita uma consulta MySQL e executa a consulta no banco de dados MySQL conectado:
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()

Agora você tem os movies tabela em seu banco de dados. Você passa create_movies_table_query para cursor.execute() , que executa a execução necessária.

Observação: A connection variável refere-se ao MySQLConnection objeto que foi retornado quando você se conectou ao seu banco de dados.

Além disso, observe o connection.commit() declaração no final do código. Por padrão, seu conector MySQL não confirma transações automaticamente. No MySQL, as modificações mencionadas em uma transação ocorrem apenas quando você usa um COMMIT comando no final. Sempre chame esse método após cada transação para realizar alterações na tabela real.

Como você fez com os movies table, execute o seguinte script para criar os reviewers tabela:
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()

Se necessário, você pode adicionar mais informações sobre um revisor, como ID de e-mail ou informações demográficas. Mas first_name e last_name servirá ao seu propósito por enquanto.

Finalmente, você pode criar as ratings tabela usando o seguinte 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()

A implementação de relacionamentos de chave estrangeira no MySQL é um pouco diferente e limitada em comparação com o SQL padrão. No MySQL, tanto o pai quanto o filho na restrição de chave estrangeira devem usar o mesmo mecanismo de armazenamento .

Um mecanismo de armazenamento é o componente de software subjacente que um sistema de gerenciamento de banco de dados usa para executar operações SQL. No MySQL, os mecanismos de armazenamento vêm em dois sabores diferentes:

  1. Mecanismos de armazenamento transacional são transações seguras e permitem reverter transações usando comandos simples como rollback . Muitos mecanismos MySQL populares, incluindo InnoDB e NDB, pertencem a esta categoria.

  2. Mecanismos de armazenamento não transacionais dependem de código manual elaborado para desfazer declarações confirmadas em um banco de dados. MyISAM, MEMORY e muitos outros mecanismos MySQL não são transacionais.

O InnoDB é o mecanismo de armazenamento padrão e mais popular. Ele ajuda a manter a integridade dos dados suportando restrições de chave estrangeira. Isso significa que qualquer operação CRUD em uma chave estrangeira é verificada para garantir que não leve a inconsistências em diferentes tabelas.

Além disso, observe que as ratings tabela usa as colunas movie_id e reviewer_id , ambas as chaves estrangeiras, em conjunto como a chave primária . Essa etapa garante que um revisor não possa avaliar o mesmo filme duas vezes.

Você pode optar por reutilizar o mesmo cursor para várias execuções. Nesse caso, todas as execuções se tornariam uma transação atômica em vez de várias transações separadas. Por exemplo, você pode executar todos os comandos CREATE TABLE instruções com um cursor e, em seguida, confirme sua transação apenas uma 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()

O código acima executará primeiro todos os três CREATE declarações. Em seguida, ele enviará um COMMIT comando para o servidor MySQL que confirma sua transação. Você também pode usar .rollback() para enviar um ROLLBACK comando para o servidor MySQL e remova todas as alterações de dados da transação.


Mostrando um esquema de tabela usando o DESCRIBE Declaração


Agora que você criou todas as três tabelas, você pode ver o esquema delas usando a seguinte instrução SQL:
DESCRIBE <table_name>;

Para obter alguns resultados do cursor objeto, você precisa usar cursor.fetchall() . Este método busca todas as linhas da última instrução executada. Supondo que você já tenha o MySQLConnection objeto na connection variável, você pode imprimir todos os resultados obtidos 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, '')

Depois de executar o código acima, você deve receber uma tabela contendo informações sobre todas as colunas em movies tabela. Para cada coluna, você receberá detalhes como o tipo de dados da coluna, se a coluna é uma chave primária e assim por diante.


Modificando um esquema de tabela usando o ALTER Declaração


Nos movies tabela, você tem uma coluna chamada collection_in_mil , que contém a coleção de bilheteria de um filme em milhões de dólares. Você pode escrever a seguinte instrução MySQL para modificar o tipo de dados de collection_in_mil atributo de INT para DECIMAL :
ALTER TABLE movies MODIFY COLUMN collection_in_mil DECIMAL(4,1);

DECIMAL(4,1) significa um número decimal que pode ter no máximo 4 dígitos, dos quais 1 é decimal, como 120.1 , 3.4 , 38.0 , e assim por diante. Após executar o ALTER TABLE instrução, você pode mostrar o esquema de tabela atualizado 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, '')

Conforme mostrado na saída, a collection_in_mil atributo agora é do tipo DECIMAL(4,1) . Observe também que no código acima, você chama cursor.execute() duas vezes. Mas cursor.fetchall() busca linhas apenas da última consulta executada, que é a show_table_query .


Excluindo tabelas usando o DROP Declaração


Para deletar uma tabela, você precisa executar o comando DROP TABLE declaração no MySQL. A exclusão de uma tabela é um irreversível processo. Se você executar o código abaixo, precisará chamar o método CREATE TABLE consulte novamente para usar as ratings tabela nas próximas seções.

Para excluir as ratings tabela, envie drop_table_query para cursor.execute() :
drop_table_query = "DROP TABLE ratings"
with connection.cursor() as cursor:
    cursor.execute(drop_table_query)

Se você executar o código acima, você excluirá com sucesso as ratings tabela.



Inserindo registros em tabelas


Na última seção, você criou três tabelas em seu banco de dados:movies , reviewers e ratings . Agora você precisa preencher essas tabelas com dados. Esta seção abordará duas maneiras diferentes de inserir registros no MySQL Connector for Python.

O primeiro método, .execute() , funciona bem quando o número de registros é pequeno e os registros podem ser codificados permanentemente. O segundo método, .executemany() , é mais popular e mais adequado para cenários do mundo real.

Usando .execute()


A primeira abordagem usa o mesmo cursor.execute() método que você tem usado até agora. Você escreve o INSERT INTO query em uma string e passe para cursor.execute() . Você pode usar este método para inserir dados nos movies tabela.

Para referência, os movies tabela tem cinco atributos:
  1. id
  2. title
  3. release_year
  4. genre
  5. collection_in_mil

Você não precisa adicionar dados para id como o AUTO_INCREMENT calcula automaticamente id para você. O script a seguir insere registros nos movies tabela:
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 tabela:
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 Lista.

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 tabela:
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 demonstração.

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 demonstração. 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 dados.

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.

Observação: 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 fragmento. 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 objeto.

Observação: 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 tabela:
>>>
>>> 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 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.

Observação: 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 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.