Terceira Fase - adicionando funcionalidade editar
Para integrar a funcionalidade de Edição/Atualização (UPDATE) no navegador com Bottle e SQLite, implementa-se o padrão web tradicional composto por duas etapas:
- Rota
GET /editar/<id:int>: Busca os dados atuais do cliente no SQLite pelo seu ID e renderiza um formulário preenchido com as informações existentes. - Rota
POST /editar/<id:int>: Recebe os novos dados enviados pelo formulário e executa o comando SQLUPDATEde forma segura com marcadores de posição?.
Como Funciona a Lógica de Edição
- Captura do ID na URL: Utiliza-se o filtro dinâmico de rota
<id:int>do Bottle para capturar o ID do cliente que será alterado - Busca do Registro: Executa-se
SELECT id, nome, email FROM clientes WHERE id = ?e recupera-se o registro individual usandocursor.fetchone() - Atualização no Banco: No envio do formulário, os dados capturados com
request.forms.get()são passados para a instruçãoUPDATE clientes SET nome = ?, email = ? WHERE id = ?. A transação é gravada comconn.commit()e o usuário é redirecionado de volta à página principal comredirect('/').
Código Completo Atualizado (app.py)
Abaixo está a versão completa do script, com a listagem, cadastro, exclusão e a nova rota de edição completa:
import sqlite3
from bottle import route, get, post, request, redirect, template, run
DB_NAME = 'meu_banco_de_dados.db'
def inicializar_banco():
"""Garante a existência da tabela 'clientes' no banco SQLite."""
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS clientes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nome TEXT NOT NULL,
email TEXT NOT NULL
);
''')
conn.commit()
conn.close()
# 1. ROTA PRINCIPAL: Listagem de Clientes e Formulário de Cadastro
@get('/')
def index():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT id, nome, email FROM clientes;")
clientes = cursor.fetchall()
conn.close()
html_template = '''
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Gestão de Clientes - Bottle + SQLite</title>
<style>
body { font-family: Arial, sans-serif; margin: 30px; }
h1, h2 { color: #333; }
form { margin-bottom: 20px; background: #f4f4f4; padding: 15px; border-radius: 5px; }
input { margin-bottom: 10px; padding: 8px; width: 250px; display: block; }
input[type="submit"] { background: #28a745; color: white; border: none; cursor: pointer; width: 120px; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #007bff; color: white; }
.btn-edit { color: #007bff; text-decoration: none; font-weight: bold; margin-right: 10px; }
.btn-del { color: red; text-decoration: none; font-weight: bold; }
</style>
</head>
<body>
<h1>Cadastro de Clientes</h1>
<form action="/cadastrar" method="post">
<label>Nome:</label>
<input type="text" name="nome" required placeholder="Digite o nome completo">
<label>E-mail:</label>
<input type="email" name="email" required placeholder="exemplo@email.com">
<input type="submit" value="Cadastrar">
</form>
<h2>Clientes Cadastrados</h2>
<table>
<tr>
<th>ID</th>
<th>Nome</th>
<th>E-mail</th>
<th>Ações</th>
</tr>
% for id_, nome, email in lista_clientes:
<tr>
<td>{{id_}}</td>
<td>{{nome}}</td>
<td>{{email}}</td>
<td>
<a class="btn-edit" href="/editar/{{id_}}">Editar</a>
<a class="btn-del" href="/deletar/{{id_}}">Excluir</a>
</td>
</tr>
% end
</table>
</body>
</html>
'''
return template(html_template, lista_clientes=clientes)
# 2. ROTA DE CADASTRO (Novo Cliente)
@post('/cadastrar')
def cadastrar():
nome = request.forms.get('nome')
email = request.forms.get('email')
if nome and email:
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("INSERT INTO clientes (nome, email) VALUES (?, ?);", (nome, email))
conn.commit()
conn.close()
redirect('/')
# 3. ROTA DE EDIÇÃO - EXIBIR FORMULÁRIO (GET)
@get('/editar/<id:int>')
def exibir_formulario_edicao(id):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT id, nome, email FROM clientes WHERE id = ?;", (id,))
cliente = cursor.fetchone()
conn.close()
if not cliente:
redirect('/')
html_editar = '''
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Editar Cliente</title>
<style>
body { font-family: Arial, sans-serif; margin: 30px; }
h1 { color: #333; }
form { background: #f4f4f4; padding: 15px; border-radius: 5px; width: 300px; }
input { margin-bottom: 10px; padding: 8px; width: 90%; display: block; }
input[type="submit"] { background: #007bff; color: white; border: none; cursor: pointer; width: 100px; }
a { color: #6c757d; text-decoration: none; display: inline-block; margin-top: 10px; }
</style>
</head>
<body>
<h1>Editar Cliente #{{cliente}}</h1>
<form action="/editar/{{cliente}}" method="post">
<label>Nome:</label>
<input type="text" name="nome" value="{{cliente}}" required>
<label>E-mail:</label>
<input type="email" name="email" value="{{cliente}}" required>
<input type="submit" value="Salvar">
</form>
<a href="/">← Cancelar e Voltar</a>
</body>
</html>
'''
return template(html_editar, cliente=cliente)
# 4. ROTA DE EDIÇÃO - SALVAR ALTERAÇÕES (POST)
@post('/editar/<id:int>')
def salvar_edicao(id):
nome = request.forms.get('nome')
email = request.forms.get('email')
if nome and email:
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
# Atualiza os dados com a instrução SQL UPDATE usando parâmetros seguros
cursor.execute(
"UPDATE clientes SET nome = ?, email = ? WHERE id = ?;",
(nome, email, id)
)
conn.commit()
conn.close()
redirect('/')
# 5. ROTA DE EXCLUSÃO
@get('/deletar/<id:int>')
def deletar(id):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("DELETE FROM clientes WHERE id = ?;", (id,))
conn.commit()
conn.close()
redirect('/')
if __name__ == '__main__':
inicializar_banco()
print("Servidor rodando em http://localhost:8080 ...")
run(host='localhost', port=8080, debug=True, reloader=True)Testando no Navegador
- Salve o código e inicie o aplicativo no terminal:
python app.py - Acesse
http://localhost:8080. - Na tabela de clientes cadastrados, clique no link Editar.
- O navegador abrirá a tela com os campos preenchidos com o nome e e-mail atuais.
- Modifique os valores e clique em Salvar. Os dados atualizados serão salvos no SQLite com
UPDATEe exibidos na tabela principal.
💡 Próximos passos: como tratar erros de banco de dados (usando try/except com rollback()) para evitar que a aplicação caia em caso de falha de conexão.
Pratica CRUD Python Sqlite Quarta fase - tratamento de erros