15 Banco de Dados SQL com Python
De pilha de papéis para biblioteca organizada: estruturando seus dados!
15.1 O que você vai aprender neste capítulo?
- Por que usar bancos de dados em vez de arquivos simples
- SQL básico: comandos essenciais (CREATE, INSERT, SELECT, UPDATE, DELETE)
- SQLite com Python: como usar a biblioteca
sqlite3integrada - Operações CRUD: criar, ler, atualizar e deletar dados
- Consultas avançadas: WHERE, ORDER BY, LIMIT e JOINs básicos
- Projeto prático: sistema completo de cadastro de clientes
- Boas práticas: prevenção de SQL Injection e gerenciamento de conexões
- Integração: conectar bancos de dados com APIs e web scraping
🎓 Vindo do Capítulo 14? Perfeito! Agora que você sabe coletar dados da web, vamos organizar esses dados!
🎯 Meta: Ao final deste capítulo, você vai conseguir criar e gerenciar bancos de dados SQL, executar consultas e integrar dados com aplicações Python.
⚠️ Por que isso importa: Bancos de dados são fundamentais para aplicações reais! Sem eles, você perderia dados toda vez que fechasse o programa. Aqui você aprende a criar sistemas persistentes!
15.2 De Pilha de Papéis para Biblioteca Organizada
15.2.1 Analogia Perfeita: Biblioteca vs. Pilha de Papéis
Problema - Pilha de Papéis:
- 📄 Todos os documentos em uma pilha
- 🔍 Difícil encontrar algo específico
- 📊 Impossível fazer análises
- 💥 Fácil perder ou danificar
- 👥 Muitas pessoas não conseguem usar
Solução - Biblioteca Organizada:
- 📚 Livros organizados por categoria
- 🔍 Sistema de busca eficiente
- 📊 Relatórios e estatísticas
- 🛡️ Proteção contra perda
- 👥 Muitas pessoas podem usar simultaneamente
15.2.2 Por que usar Bancos de Dados?
Sem banco de dados (problema):
Com banco de dados (solução):
15.2.3 O que é SQL?
SQL (Structured Query Language) é a linguagem para conversar com bancos de dados.
É como falar com o bibliotecário:
- 📖 “Mostre todos os livros de Python”
- ➕ “Adicione um novo livro”
- ✏️ “Atualize o preço deste livro”
- 🗑️ “Remova este livro antigo”
15.2.4 SQLite - Banco de Dados Simples
SQLite é perfeito para aprender:
- ✅ Simples: Um arquivo = um banco
- ✅ Integrado: Já vem com Python
- ✅ Rápido: Ideal para aplicações pequenas/médias
- ✅ Portável: Funciona em qualquer lugar
💡 Exemplo: WhatsApp, Instagram e muitos apps usam SQLite para armazenar dados localmente!
15.3 Seu Primeiro Banco de Dados
15.3.1 Criando e Conectando ao Banco
15.3.2 Criando sua Primeira Tabela
import sqlite3
def criar_tabela_clientes():
"""Cria tabela de clientes"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
# Criar tabela
cursor.execute('''
CREATE TABLE IF NOT EXISTS clientes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
email TEXT UNIQUE,
idade INTEGER,
cidade TEXT
)
''')
# Salvar mudanças
conn.commit()
conn.close()
print("✅ Tabela 'clientes' criada!")
# Executar
criar_tabela_clientes()15.3.3 Inserindo Dados (INSERT)
def inserir_cliente(nome, email, idade, cidade):
"""Insere um novo cliente"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO clientes (nome, email, idade, cidade)
VALUES (?, ?, ?, ?)
''', (nome, email, idade, cidade))
conn.commit()
print(f"✅ Cliente '{nome}' inserido com sucesso!")
except sqlite3.IntegrityError:
print(f"❌ Email '{email}' já existe!")
finally:
conn.close()
# Testando
inserir_cliente('João Silva', 'joao@email.com', 30, 'São Paulo')
inserir_cliente('Maria Santos', 'maria@email.com', 25, 'Rio de Janeiro')
inserir_cliente('Pedro Costa', 'pedro@email.com', 35, 'Belo Horizonte')15.3.4 Consultando Dados (SELECT)
def listar_clientes():
"""Lista todos os clientes"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
cursor.execute('SELECT * FROM clientes')
clientes = cursor.fetchall()
print("📋 Lista de Clientes:")
print("-" * 50)
for cliente in clientes:
print(f"ID: {cliente[0]} | Nome: {cliente[1]} | Email: {cliente[2]} | Idade: {cliente[3]} | Cidade: {cliente[4]}")
conn.close()
return clientes
# Testando
listar_clientes()15.3.5 Consultas com Filtros (WHERE)
def buscar_cliente_por_cidade(cidade):
"""Busca clientes por cidade"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
cursor.execute('SELECT * FROM clientes WHERE cidade = ?', (cidade,))
clientes = cursor.fetchall()
print(f"🏙️ Clientes de {cidade}:")
for cliente in clientes:
print(f"- {cliente[1]} ({cliente[2]})")
conn.close()
return clientes
def buscar_clientes_maiores_que(idade_minima):
"""Busca clientes maiores que uma idade"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
cursor.execute('SELECT nome, idade FROM clientes WHERE idade > ?', (idade_minima,))
clientes = cursor.fetchall()
print(f"👴 Clientes maiores que {idade_minima} anos:")
for cliente in clientes:
print(f"- {cliente[0]} ({cliente[1]} anos)")
conn.close()
return clientes
# Testando
buscar_cliente_por_cidade('São Paulo')
buscar_clientes_maiores_que(30)💡 Dica: Use
?placeholders para evitar SQL Injection! Nunca concatene strings diretamente no SQL.
15.4 Atualizando e Deletando Dados
15.4.1 Atualizando Dados (UPDATE)
def atualizar_cliente(cliente_id, novo_nome=None, novo_email=None, nova_idade=None, nova_cidade=None):
"""Atualiza dados de um cliente"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
# Construir query dinamicamente
campos = []
valores = []
if novo_nome:
campos.append('nome = ?')
valores.append(novo_nome)
if novo_email:
campos.append('email = ?')
valores.append(novo_email)
if nova_idade:
campos.append('idade = ?')
valores.append(nova_idade)
if nova_cidade:
campos.append('cidade = ?')
valores.append(nova_cidade)
if campos:
valores.append(cliente_id)
query = f"UPDATE clientes SET {', '.join(campos)} WHERE id = ?"
cursor.execute(query, valores)
conn.commit()
print(f"✅ Cliente ID {cliente_id} atualizado!")
else:
print("❌ Nenhum campo para atualizar!")
conn.close()
# Testando
atualizar_cliente(1, novo_nome='João Silva Santos', nova_idade=31)15.4.2 Deletando Dados (DELETE)
def deletar_cliente(cliente_id):
"""Deleta um cliente pelo ID"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
# Verificar se cliente existe
cursor.execute('SELECT nome FROM clientes WHERE id = ?', (cliente_id,))
cliente = cursor.fetchone()
if cliente:
cursor.execute('DELETE FROM clientes WHERE id = ?', (cliente_id,))
conn.commit()
print(f"✅ Cliente '{cliente[0]}' deletado!")
else:
print(f"❌ Cliente ID {cliente_id} não encontrado!")
conn.close()
# Testando
deletar_cliente(3) # Deletar Pedro Costa15.4.3 Sistema Completo de Gerenciamento
class GerenciadorClientes:
"""Classe para gerenciar clientes no banco de dados"""
def __init__(self, nome_banco='loja.db'):
self.nome_banco = nome_banco
self.criar_tabela()
def conectar(self):
"""Conecta ao banco de dados"""
return sqlite3.connect(self.nome_banco)
def criar_tabela(self):
"""Cria tabela se não existir"""
conn = self.conectar()
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS clientes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
email TEXT UNIQUE,
idade INTEGER,
cidade TEXT,
data_cadastro TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
def adicionar_cliente(self, nome, email, idade, cidade):
"""Adiciona novo cliente"""
conn = self.conectar()
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO clientes (nome, email, idade, cidade)
VALUES (?, ?, ?, ?)
''', (nome, email, idade, cidade))
conn.commit()
print(f"✅ Cliente '{nome}' adicionado!")
return True
except sqlite3.IntegrityError:
print(f"❌ Email '{email}' já existe!")
return False
finally:
conn.close()
def listar_clientes(self):
"""Lista todos os clientes"""
conn = self.conectar()
cursor = conn.cursor()
cursor.execute('SELECT * FROM clientes ORDER BY nome')
clientes = cursor.fetchall()
print("📋 Lista de Clientes:")
print("-" * 80)
for cliente in clientes:
print(f"ID: {cliente[0]:2} | Nome: {cliente[1]:20} | Email: {cliente[2]:25} | Idade: {cliente[3]:2} | Cidade: {cliente[4]}")
conn.close()
return clientes
def buscar_cliente(self, termo):
"""Busca cliente por nome ou email"""
conn = self.conectar()
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM clientes
WHERE nome LIKE ? OR email LIKE ?
''', (f'%{termo}%', f'%{termo}%'))
clientes = cursor.fetchall()
if clientes:
print(f"🔍 Resultados para '{termo}':")
for cliente in clientes:
print(f"- {cliente[1]} ({cliente[2]}) - {cliente[4]}")
else:
print(f"❌ Nenhum cliente encontrado para '{termo}'")
conn.close()
return clientes
def estatisticas(self):
"""Mostra estatísticas dos clientes"""
conn = self.conectar()
cursor = conn.cursor()
# Total de clientes
cursor.execute('SELECT COUNT(*) FROM clientes')
total = cursor.fetchone()[0]
# Média de idade
cursor.execute('SELECT AVG(idade) FROM clientes WHERE idade IS NOT NULL')
media_idade = cursor.fetchone()[0]
# Clientes por cidade
cursor.execute('SELECT cidade, COUNT(*) FROM clientes GROUP BY cidade ORDER BY COUNT(*) DESC')
cidades = cursor.fetchall()
print("📊 Estatísticas dos Clientes:")
print("-" * 40)
print(f"Total de clientes: {total}")
if media_idade:
print(f"Média de idade: {media_idade:.1f} anos")
print("\nClientes por cidade:")
for cidade, count in cidades:
print(f"- {cidade}: {count} clientes")
conn.close()
# Testando o sistema completo
gerenciador = GerenciadorClientes()
# Adicionar alguns clientes
gerenciador.adicionar_cliente('Ana Costa', 'ana@email.com', 28, 'São Paulo')
gerenciador.adicionar_cliente('Carlos Lima', 'carlos@email.com', 42, 'Rio de Janeiro')
gerenciador.adicionar_cliente('Fernanda Silva', 'fernanda@email.com', 33, 'São Paulo')
# Listar clientes
gerenciador.listar_clientes()
# Buscar cliente
gerenciador.buscar_cliente('Ana')
# Mostrar estatísticas
gerenciador.estatisticas()💡 Parabéns! Você criou um sistema completo de gerenciamento de dados com banco de dados SQL!
15.5 Exercícios Práticos
15.5.1 MUITO FÁCIL (Nível 1)
1. Crie uma tabela livros com campos: id, titulo, autor, ano, preco.
2. Insira 3 livros na tabela criada no exercício anterior.
3. Liste todos os livros da tabela.
4. Busque livros de um autor específico.
5. Conte quantos livros existem na tabela.
15.5.2 FÁCIL (Nível 2)
6. Crie um sistema de cadastro de alunos com nome, matrícula, curso e nota.
7. Implemente funções para adicionar, listar e buscar alunos.
8. Crie uma tabela de produtos com nome, categoria, preço e estoque.
9. Implemente um sistema de vendas que registra produtos vendidos.
10. Crie consultas para encontrar produtos com estoque baixo (< 10).
15.5.3 MÉDIO (Nível 3)
11. Crie um sistema de biblioteca com livros, usuários e empréstimos.
12. Implemente um sistema de notas escolares com alunos, disciplinas e notas.
13. Crie um sistema de e-commerce com produtos, clientes e pedidos.
14. Implemente um sistema de agenda com contatos e categorias.
15. Crie um sistema de controle de estoque com produtos e movimentações.
15.5.4 DIFÍCIL (Nível 4)
16. Crie um sistema de rede social com usuários, posts e comentários.
17. Implemente um sistema bancário com contas, transações e extratos.
18. Crie um sistema de hotel com quartos, hóspedes e reservas.
19. Implemente um sistema de escola com alunos, professores e disciplinas.
20. Crie um sistema de delivery com restaurantes, pedidos e entregadores.
15.5.5 MUITO DIFÍCIL (Nível 5)
21. Crie um sistema completo de marketplace com vendedores e compradores.
22. Implemente um sistema de streaming com usuários, conteúdo e assinaturas.
23. Crie um sistema de saúde com pacientes, médicos e consultas.
24. Implemente um sistema de transporte com rotas, passageiros e viagens.
25. Crie um sistema de IoT que armazena dados de sensores em tempo real.
🎯 Dica: Comece com tabelas simples e vá adicionando complexidade gradualmente. Sempre teste suas consultas SQL!
15.6 Respostas dos Exercícios
15.6.1 MUITO FÁCIL (Nível 1)
1. Criar tabela livros
import sqlite3
def criar_tabela_livros():
"""Cria tabela de livros"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS livros (
id INTEGER PRIMARY KEY AUTOINCREMENT,
titulo TEXT NOT NULL,
autor TEXT NOT NULL,
ano INTEGER,
preco REAL
)
''')
conn.commit()
conn.close()
print("✅ Tabela 'livros' criada com sucesso!")
criar_tabela_livros()Explicação linha por linha:
- Linha 1:
import sqlite3- Importa módulo SQLite3 - Linha 3:
def criar_tabela_livros():- Define função para criar tabela - Linha 4:
"""Cria tabela de livros"""- Docstring explicando função - Linha 5:
conn = sqlite3.connect('biblioteca.db')- Conecta ao banco de dados - Linha 6:
cursor = conn.cursor()- Cria cursor para executar comandos SQL - Linha 8:
cursor.execute('''- Inicia execução de comando SQL - Linha 9:
CREATE TABLE IF NOT EXISTS livros (- Cria tabela se não existir - Linha 10:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 11:
titulo TEXT NOT NULL,- Campo título obrigatório - Linha 12:
autor TEXT NOT NULL,- Campo autor obrigatório - Linha 13:
ano INTEGER,- Campo ano como número inteiro - Linha 14:
preco REAL- Campo preço como número decimal - Linha 15:
)- Fecha definição da tabela - Linha 16:
''')- Fecha string SQL - Linha 18:
conn.commit()- Confirma mudanças no banco - Linha 19:
conn.close()- Fecha conexão com banco - Linha 20:
print("✅ Tabela 'livros' criada com sucesso!")- Mostra mensagem de sucesso
2. Inserir 3 livros
def inserir_livros():
"""Insere 3 livros na tabela"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
livros = [
('Python para Iniciantes', 'João Silva', 2023, 45.90),
('SQL Avançado', 'Maria Santos', 2022, 67.50),
('Banco de Dados', 'Pedro Costa', 2024, 52.30)
]
for livro in livros:
cursor.execute('''
INSERT INTO livros (titulo, autor, ano, preco)
VALUES (?, ?, ?, ?)
''', livro)
conn.commit()
conn.close()
print("✅ 3 livros inseridos com sucesso!")
inserir_livros()Explicação linha por linha:
- Linha 1:
def inserir_livros():- Define função para inserir livros - Linha 2:
"""Insere 3 livros na tabela"""- Docstring explicando função - Linha 3:
conn = sqlite3.connect('biblioteca.db')- Conecta ao banco - Linha 4:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 6:
livros = [- Inicia lista com dados dos livros - Linha 7:
('Python para Iniciantes', 'João Silva', 2023, 45.90),- Dados do primeiro livro - Linha 8:
('SQL Avançado', 'Maria Santos', 2022, 67.50),- Dados do segundo livro - Linha 9:
('Banco de Dados', 'Pedro Costa', 2024, 52.30)- Dados do terceiro livro - Linha 10:
]- Fecha lista de livros - Linha 12:
for livro in livros:- Percorre cada livro na lista - Linha 13:
cursor.execute('''- Inicia comando SQL - Linha 14:
INSERT INTO livros (titulo, autor, ano, preco)- Comando INSERT - Linha 15:
VALUES (?, ?, ?, ?)- Placeholders para valores - Linha 16:
''', livro)- Fecha comando e passa dados do livro - Linha 18:
conn.commit()- Confirma inserções no banco - Linha 19:
conn.close()- Fecha conexão - Linha 20:
print("✅ 3 livros inseridos com sucesso!")- Mostra mensagem
3. Listar todos os livros
def listar_livros():
"""Lista todos os livros"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
cursor.execute('SELECT * FROM livros')
livros = cursor.fetchall()
print("📚 Lista de Livros:")
print("-" * 60)
for livro in livros:
print(f"ID: {livro[0]} | Título: {livro[1]} | Autor: {livro[2]} | Ano: {livro[3]} | Preço: R$ {livro[4]}")
conn.close()
return livros
listar_livros()Explicação linha por linha:
- Linha 1:
def listar_livros():- Define função para listar livros - Linha 2:
"""Lista todos os livros"""- Docstring explicando função - Linha 3:
conn = sqlite3.connect('biblioteca.db')- Conecta ao banco - Linha 4:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 6:
cursor.execute('SELECT * FROM livros')- Executa consulta SELECT - Linha 7:
livros = cursor.fetchall()- Recupera todos os resultados - Linha 9:
print("📚 Lista de Livros:")- Imprime cabeçalho - Linha 10:
print("-" * 60)- Imprime linha separadora - Linha 11:
for livro in livros:- Percorre cada livro retornado - Linha 12:
print(f"ID: {livro[0]} | Título: {livro[1]} | Autor: {livro[2]} | Ano: {livro[3]} | Preço: R$ {livro[4]}")- Formata e imprime dados do livro - Linha 14:
conn.close()- Fecha conexão - Linha 15:
return livros- Retorna lista de livros
4. Buscar livros por autor
def buscar_livros_por_autor(autor):
"""Busca livros por autor específico"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
cursor.execute('SELECT * FROM livros WHERE autor = ?', (autor,))
livros = cursor.fetchall()
print(f"🔍 Livros do autor '{autor}':")
for livro in livros:
print(f"- {livro[1]} ({livro[3]}) - R$ {livro[4]}")
conn.close()
return livros
buscar_livros_por_autor('João Silva')Explicação linha por linha:
- Linha 1:
def buscar_livros_por_autor(autor):- Define função com parâmetro autor - Linha 2:
"""Busca livros por autor específico"""- Docstring explicando função - Linha 3:
conn = sqlite3.connect('biblioteca.db')- Conecta ao banco - Linha 4:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 6:
cursor.execute('SELECT * FROM livros WHERE autor = ?', (autor,))- Executa consulta com filtro WHERE - Linha 7:
livros = cursor.fetchall()- Recupera resultados da consulta - Linha 9:
print(f"🔍 Livros do autor '{autor}':")- Imprime cabeçalho com nome do autor - Linha 10:
for livro in livros:- Percorre livros encontrados - Linha 11:
print(f"- {livro[1]} ({livro[3]}) - R$ {livro[4]}")- Imprime título, ano e preço - Linha 13:
conn.close()- Fecha conexão - Linha 14:
return livros- Retorna livros encontrados
5. Contar livros
Explicação linha por linha:
- Linha 1:
def contar_livros():- Define função para contar livros - Linha 2:
"""Conta total de livros na tabela"""- Docstring explicando função - Linha 3:
conn = sqlite3.connect('biblioteca.db')- Conecta ao banco - Linha 4:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 6:
cursor.execute('SELECT COUNT(*) FROM livros')- Executa função de agregação COUNT - Linha 7:
total = cursor.fetchone()[0]- Recupera resultado único - Linha 9:
print(f"📊 Total de livros: {total}")- Imprime total encontrado - Linha 11:
conn.close()- Fecha conexão - Linha 12:
return total- Retorna total de livros
15.6.2 FÁCIL (Nível 2)
6. Sistema de cadastro de alunos
import sqlite3
def criar_sistema_alunos():
"""Cria sistema completo de cadastro de alunos"""
conn = sqlite3.connect('escola.db')
cursor = conn.cursor()
# Criar tabela de alunos
cursor.execute('''
CREATE TABLE IF NOT EXISTS alunos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
matricula TEXT UNIQUE NOT NULL,
curso TEXT NOT NULL,
nota REAL,
data_cadastro TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
print("✅ Sistema de alunos criado!")
def adicionar_aluno(nome, matricula, curso, nota=None):
"""Adiciona novo aluno"""
conn = sqlite3.connect('escola.db')
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO alunos (nome, matricula, curso, nota)
VALUES (?, ?, ?, ?)
''', (nome, matricula, curso, nota))
conn.commit()
print(f"✅ Aluno '{nome}' adicionado!")
return True
except sqlite3.IntegrityError:
print(f"❌ Matrícula '{matricula}' já existe!")
return False
finally:
conn.close()
def listar_alunos():
"""Lista todos os alunos"""
conn = sqlite3.connect('escola.db')
cursor = conn.cursor()
cursor.execute('SELECT * FROM alunos ORDER BY nome')
alunos = cursor.fetchall()
print("📚 Lista de Alunos:")
print("-" * 80)
for aluno in alunos:
nota_texto = f"R$ {aluno[4]:.1f}" if aluno[4] else "Sem nota"
print(f"ID: {aluno[0]:2} | Nome: {aluno[1]:20} | Matrícula: {aluno[2]:10} | Curso: {aluno[3]:15} | Nota: {nota_texto}")
conn.close()
return alunos
def buscar_aluno(termo):
"""Busca aluno por nome ou matrícula"""
conn = sqlite3.connect('escola.db')
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM alunos
WHERE nome LIKE ? OR matricula LIKE ?
''', (f'%{termo}%', f'%{termo}%'))
alunos = cursor.fetchall()
if alunos:
print(f"🔍 Resultados para '{termo}':")
for aluno in alunos:
print(f"- {aluno[1]} (Matrícula: {aluno[2]}) - {aluno[3]}")
else:
print(f"❌ Nenhum aluno encontrado para '{termo}'")
conn.close()
return alunos
# Testando o sistema
criar_sistema_alunos()
adicionar_aluno('Ana Silva', '2024001', 'Ciência da Computação', 8.5)
adicionar_aluno('Carlos Santos', '2024002', 'Engenharia', 7.8)
adicionar_aluno('Maria Costa', '2024003', 'Medicina', 9.2)
listar_alunos()
buscar_aluno('Ana')Explicação linha por linha:
- Linha 1:
import sqlite3- Importa módulo SQLite3 - Linha 3:
def criar_sistema_alunos():- Define função para criar sistema - Linha 4:
"""Cria sistema completo de cadastro de alunos"""- Docstring explicando função - Linha 5:
conn = sqlite3.connect('escola.db')- Conecta ao banco de dados - Linha 6:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 8:
# Criar tabela de alunos- Comentário explicativo - Linha 9:
cursor.execute('''- Inicia comando SQL - Linha 10:
CREATE TABLE IF NOT EXISTS alunos (- Cria tabela se não existir - Linha 11:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 12:
nome TEXT NOT NULL,- Campo nome obrigatório - Linha 13:
matricula TEXT UNIQUE NOT NULL,- Campo matrícula único e obrigatório - Linha 14:
curso TEXT NOT NULL,- Campo curso obrigatório - Linha 15:
nota REAL,- Campo nota como número decimal (opcional) - Linha 16:
data_cadastro TIMESTAMP DEFAULT CURRENT_TIMESTAMP- Campo de data automático - Linha 17:
)- Fecha definição da tabela - Linha 18:
''')- Fecha string SQL - Linha 20:
conn.commit()- Confirma criação da tabela - Linha 21:
conn.close()- Fecha conexão - Linha 22:
print("✅ Sistema de alunos criado!")- Mostra mensagem de sucesso
7. Sistema de produtos com estoque
def criar_sistema_produtos():
"""Cria sistema de produtos com controle de estoque"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
# Criar tabela de produtos
cursor.execute('''
CREATE TABLE IF NOT EXISTS produtos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
categoria TEXT NOT NULL,
preco REAL NOT NULL,
estoque INTEGER DEFAULT 0,
data_cadastro TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Criar tabela de vendas
cursor.execute('''
CREATE TABLE IF NOT EXISTS vendas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
produto_id INTEGER,
quantidade INTEGER NOT NULL,
preco_unitario REAL NOT NULL,
data_venda TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (produto_id) REFERENCES produtos (id)
)
''')
conn.commit()
conn.close()
print("✅ Sistema de produtos criado!")
def adicionar_produto(nome, categoria, preco, estoque=0):
"""Adiciona novo produto"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO produtos (nome, categoria, preco, estoque)
VALUES (?, ?, ?, ?)
''', (nome, categoria, preco, estoque))
conn.commit()
conn.close()
print(f"✅ Produto '{nome}' adicionado!")
def registrar_venda(produto_id, quantidade):
"""Registra uma venda e atualiza estoque"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
try:
# Verificar estoque disponível
cursor.execute('SELECT estoque, preco FROM produtos WHERE id = ?', (produto_id,))
produto = cursor.fetchone()
if not produto:
print("❌ Produto não encontrado!")
return False
if produto[0] < quantidade:
print(f"❌ Estoque insuficiente! Disponível: {produto[0]}")
return False
# Registrar venda
cursor.execute('''
INSERT INTO vendas (produto_id, quantidade, preco_unitario)
VALUES (?, ?, ?)
''', (produto_id, quantidade, produto[1]))
# Atualizar estoque
cursor.execute('''
UPDATE produtos
SET estoque = estoque - ?
WHERE id = ?
''', (quantidade, produto_id))
conn.commit()
print(f"✅ Venda registrada! Estoque atualizado.")
return True
except Exception as e:
print(f"❌ Erro na venda: {e}")
return False
finally:
conn.close()
def produtos_estoque_baixo(limite=10):
"""Encontra produtos com estoque baixo"""
conn = sqlite3.connect('loja.db')
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM produtos
WHERE estoque < ?
ORDER BY estoque ASC
''', (limite,))
produtos = cursor.fetchall()
print(f"⚠️ Produtos com estoque baixo (< {limite}):")
for produto in produtos:
print(f"- {produto[1]} (Estoque: {produto[4]})")
conn.close()
return produtos
# Testando o sistema
criar_sistema_produtos()
adicionar_produto('Notebook', 'Informática', 2500.00, 15)
adicionar_produto('Mouse', 'Informática', 45.90, 5)
adicionar_produto('Teclado', 'Informática', 120.00, 8)
registrar_venda(1, 2) # Vender 2 notebooks
produtos_estoque_baixo()Explicação linha por linha:
- Linha 1:
def criar_sistema_produtos():- Define função para criar sistema de produtos - Linha 2:
"""Cria sistema de produtos com controle de estoque"""- Docstring explicando função - Linha 3:
conn = sqlite3.connect('loja.db')- Conecta ao banco de dados - Linha 4:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 6:
# Criar tabela de produtos- Comentário explicativo - Linha 7:
cursor.execute('''- Inicia comando SQL - Linha 8:
CREATE TABLE IF NOT EXISTS produtos (- Cria tabela de produtos - Linha 9:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 10:
nome TEXT NOT NULL,- Campo nome obrigatório - Linha 11:
categoria TEXT NOT NULL,- Campo categoria obrigatório - Linha 12:
preco REAL NOT NULL,- Campo preço obrigatório - Linha 13:
estoque INTEGER DEFAULT 0,- Campo estoque com valor padrão - Linha 14:
data_cadastro TIMESTAMP DEFAULT CURRENT_TIMESTAMP- Campo de data automático - Linha 15:
)- Fecha definição da tabela - Linha 16:
''')- Fecha string SQL - Linha 18:
# Criar tabela de vendas- Comentário explicativo - Linha 19:
cursor.execute('''- Inicia comando SQL - Linha 20:
CREATE TABLE IF NOT EXISTS vendas (- Cria tabela de vendas - Linha 21:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 22:
produto_id INTEGER,- Campo referenciando produto - Linha 23:
quantidade INTEGER NOT NULL,- Campo quantidade obrigatório - Linha 24:
preco_unitario REAL NOT NULL,- Campo preço unitário obrigatório - Linha 25:
data_venda TIMESTAMP DEFAULT CURRENT_TIMESTAMP,- Campo de data automático - Linha 26:
FOREIGN KEY (produto_id) REFERENCES produtos (id)- Chave estrangeira - Linha 27:
)- Fecha definição da tabela - Linha 28:
''')- Fecha string SQL
8. Sistema de biblioteca
def criar_sistema_biblioteca():
"""Cria sistema completo de biblioteca"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
# Tabela de livros
cursor.execute('''
CREATE TABLE IF NOT EXISTS livros (
id INTEGER PRIMARY KEY AUTOINCREMENT,
titulo TEXT NOT NULL,
autor TEXT NOT NULL,
isbn TEXT UNIQUE,
disponivel BOOLEAN DEFAULT 1
)
''')
# Tabela de usuários
cursor.execute('''
CREATE TABLE IF NOT EXISTS usuarios (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
telefone TEXT
)
''')
# Tabela de empréstimos
cursor.execute('''
CREATE TABLE IF NOT EXISTS emprestimos (
id INTEGER PRIMARY KEY AUTOINCREMENT,
livro_id INTEGER,
usuario_id INTEGER,
data_emprestimo TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
data_devolucao TIMESTAMP,
FOREIGN KEY (livro_id) REFERENCES livros (id),
FOREIGN KEY (usuario_id) REFERENCES usuarios (id)
)
''')
conn.commit()
conn.close()
print("✅ Sistema de biblioteca criado!")
def emprestar_livro(livro_id, usuario_id):
"""Realiza empréstimo de livro"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
try:
# Verificar se livro está disponível
cursor.execute('SELECT disponivel FROM livros WHERE id = ?', (livro_id,))
livro = cursor.fetchone()
if not livro or not livro[0]:
print("❌ Livro não disponível!")
return False
# Realizar empréstimo
cursor.execute('''
INSERT INTO emprestimos (livro_id, usuario_id)
VALUES (?, ?)
''', (livro_id, usuario_id))
# Marcar livro como indisponível
cursor.execute('''
UPDATE livros
SET disponivel = 0
WHERE id = ?
''', (livro_id,))
conn.commit()
print("✅ Empréstimo realizado com sucesso!")
return True
except Exception as e:
print(f"❌ Erro no empréstimo: {e}")
return False
finally:
conn.close()
def devolver_livro(emprestimo_id):
"""Devolve um livro"""
conn = sqlite3.connect('biblioteca.db')
cursor = conn.cursor()
try:
# Buscar empréstimo
cursor.execute('SELECT livro_id FROM emprestimos WHERE id = ? AND data_devolucao IS NULL', (emprestimo_id,))
emprestimo = cursor.fetchone()
if not emprestimo:
print("❌ Empréstimo não encontrado!")
return False
# Registrar devolução
cursor.execute('''
UPDATE emprestimos
SET data_devolucao = CURRENT_TIMESTAMP
WHERE id = ?
''', (emprestimo_id,))
# Marcar livro como disponível
cursor.execute('''
UPDATE livros
SET disponivel = 1
WHERE id = ?
''', (emprestimo[0],))
conn.commit()
print("✅ Livro devolvido com sucesso!")
return True
except Exception as e:
print(f"❌ Erro na devolução: {e}")
return False
finally:
conn.close()
# Testando o sistema
criar_sistema_biblioteca()
print("📚 Sistema de biblioteca pronto para uso!")Explicação linha por linha:
- Linha 1:
def criar_sistema_biblioteca():- Define função para criar sistema de biblioteca - Linha 2:
"""Cria sistema completo de biblioteca"""- Docstring explicando função - Linha 3:
conn = sqlite3.connect('biblioteca.db')- Conecta ao banco de dados - Linha 4:
cursor = conn.cursor()- Cria cursor para comandos SQL - Linha 6:
# Tabela de livros- Comentário explicativo - Linha 7:
cursor.execute('''- Inicia comando SQL - Linha 8:
CREATE TABLE IF NOT EXISTS livros (- Cria tabela de livros - Linha 9:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 10:
titulo TEXT NOT NULL,- Campo título obrigatório - Linha 11:
autor TEXT NOT NULL,- Campo autor obrigatório - Linha 12:
isbn TEXT UNIQUE,- Campo ISBN único - Linha 13:
disponivel BOOLEAN DEFAULT 1- Campo disponibilidade com padrão - Linha 14:
)- Fecha definição da tabela - Linha 15:
''')- Fecha string SQL - Linha 17:
# Tabela de usuários- Comentário explicativo - Linha 18:
cursor.execute('''- Inicia comando SQL - Linha 19:
CREATE TABLE IF NOT EXISTS usuarios (- Cria tabela de usuários - Linha 20:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 21:
nome TEXT NOT NULL,- Campo nome obrigatório - Linha 22:
email TEXT UNIQUE NOT NULL,- Campo email único e obrigatório - Linha 23:
telefone TEXT- Campo telefone opcional - Linha 24:
)- Fecha definição da tabela - Linha 25:
''')- Fecha string SQL - Linha 27:
# Tabela de empréstimos- Comentário explicativo - Linha 28:
cursor.execute('''- Inicia comando SQL - Linha 29:
CREATE TABLE IF NOT EXISTS emprestimos (- Cria tabela de empréstimos - Linha 30:
id INTEGER PRIMARY KEY AUTOINCREMENT,- Campo ID como chave primária - Linha 31:
livro_id INTEGER,- Campo referenciando livro - Linha 32:
usuario_id INTEGER,- Campo referenciando usuário - Linha 33:
data_emprestimo TIMESTAMP DEFAULT CURRENT_TIMESTAMP,- Data de empréstimo automática - Linha 34:
data_devolucao TIMESTAMP,- Data de devolução (opcional) - Linha 35:
FOREIGN KEY (livro_id) REFERENCES livros (id),- Chave estrangeira para livros - Linha 36:
FOREIGN KEY (usuario_id) REFERENCES usuarios (id)- Chave estrangeira para usuários - Linha 37:
)- Fecha definição da tabela - Linha 38:
''')- Fecha string SQL
15.7 Próximos Passos: Continue Aprendendo!
Parabéns! Você agora domina bancos de dados SQL com Python! 🎉
15.7.1 O que você aprendeu:
- ✅ Conceito de Bancos de Dados: Por que usar bancos em vez de arquivos
- ✅ SQL básico: Comandos CREATE, INSERT, SELECT, UPDATE, DELETE
- ✅ SQLite com Python: Como usar a biblioteca
sqlite3integrada - ✅ Operações CRUD: Criar, ler, atualizar e deletar dados
- ✅ Consultas com filtros: WHERE, ORDER BY, GROUP BY
- ✅ Sistema completo: Classe para gerenciar dados de forma organizada
- ✅ Boas práticas: Prevenção de SQL Injection e gerenciamento de conexões
- ✅ Projetos práticos: Sistemas de gerenciamento de dados reais
15.7.2 Desafios para Continuar:
- Explore bancos maiores: Teste PostgreSQL ou MySQL para projetos maiores
- Crie APIs com banco: Integre Flask com bancos de dados
- Automatize tarefas: Use bancos para armazenar dados de scraping
- Contribua com projetos: Encontre projetos que precisam de persistência de dados
15.7.3 Próximo Capítulo:
No Capítulo 16, vamos aprender sobre Expressões Regulares (Regex)! Você vai descobrir como:
- Usar padrões para encontrar texto específico
- Validar emails, CPFs e telefones
- Extrair informações de textos
- Limpar e formatar dados
- Aplicar regex em projetos de scraping e APIs
🎯 batel.tech: Quer praticar mais? Acesse batel.tech e encontre projetos práticos para aplicar seus conhecimentos de bancos de dados! Lá você pode colaborar com outros desenvolvedores e construir sistemas incríveis com persistência de dados!
15.8 Referências Bibliográficas
- SQLite Documentation: SQLite Documentation
- Python sqlite3: Python SQLite3 Documentation
- SQL Tutorial: W3Schools SQL Tutorial
- Database Design: Database Design Best Practices
- SQL Injection Prevention: OWASP SQL Injection Prevention
Capítulo 15 concluído! 🎉 Agora você está pronto para criar sistemas com persistência de dados e bancos de dados profissionais. No próximo capítulo, vamos aprender sobre expressões regulares!