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:
-
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.
-
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.
-
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:
- Conecte-se ao servidor MySQL.
- Crie um novo banco de dados.
- Conecte-se ao banco de dados recém-criado ou existente.
- Execute uma consulta SQL e obtenha resultados.
- Informe o banco de dados se alguma alteração for feita em uma tabela.
- 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 umtry
…except
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 usandowith
, 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 ogetpass
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:
movies
contém informações gerais sobre filmes e possui os seguintes atributos:id
title
release_year
genre
collection_in_mil
reviewers
contém informações sobre pessoas que postaram avaliações ou classificações e tem os seguintes atributos:id
first_name
last_name
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:
-
Mecanismos de armazenamento transacional são transações seguras e permitem reverter transações usando comandos simples comorollback
. Muitos mecanismos MySQL populares, incluindo InnoDB e NDB, pertencem a esta categoria.
-
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:id
title
release_year
genre
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:- A query that contains placeholders for the records that need to be inserted
- 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, orNone
if no more rows are available..fetchmany()
retrieves the next set of rows from the result as a list of tuples. It has asize
argument, which defaults to1
, 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:
-
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.
-
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:
-
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.
-
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.
-
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.