Guia técnico: Construindo uma aplicação CRUD com Flask, SQLAlchemy e templates
Abordagem prática para desenvolver, testar e implantar uma aplicação web com foco em clareza, desempenho e manutenibilidade.
Resumo do conteúdo
Este artigo apresenta, de forma prática e detalhada, a construção de uma aplicação CRUD (Create, Read, Update, Delete) utilizando o microframework Flask, o ORM SQLAlchemy e templates Jinja2. Do setup inicial ao deploy em Heroku, cobrimos cada bloco de construção essencial: organização do projeto, roteamento, renderização de templates, gestão de estado com o banco de dados, operações do CRUD e considerações de deploy. Ao final, você terá uma aplicação funcional de “tarefas” que pode ser expandida conforme as suas necessidades.
O objetivo é oferecer conteúdo técnico com explicações claras, exemplos de código legíveis e uma estrutura que facilite a reutilização em projetos reais. A narrativa segue o fluxo de desenvolvimento, com trechos de código destacados para facilitar a leitura e o aprendizado.
Pré-requisitos e ambiente de desenvolvimento
Antes de iniciar, assegure-se de possuir um ambiente de desenvolvimento com Python 3.6+ e o gerenciador de pacotes (pip). A seguir, descrevemos uma forma comum de configuração, alinhada ao fluxo utilizado neste guia:
- Python 3.x instalado (recomendado 3.7+).
- Git disponível para versionamento e eventual deploy com Heroku.
- Virtualização de ambiente de desenvolvimento com virtualenv (convenção: criar uma pasta chamada env ou similar).
Comandos típicos (baseados no fluxo descrito no material de referência):
# Instalar o utilitário de ambientes virtuais (se ainda não estiver instalado)
pip3 install virtualenv
# Criar o ambiente virtual
virtualenv env
# Ativar o ambiente virtual
# Em Linux/macOS
source env/bin/activate
# Em Windows (cmd)
env\Scripts\activate
# Instalar dependências básicas
pip3 install flask
pip3 install flask_sqlalchemy
Observação: este fluxo utiliza Flask juntamente com SQLAlchemy para gerenciar o banco de dados de forma simples e eficiente, mantendo o ambiente isolado para o projeto.
Estrutura básica do projeto
Para suportar uma aplicação Flask organizada, adotamos uma estrutura simples, com as pastas e arquivos a seguir:
- app.py – ponto de entrada da aplicação e definição de rotas.
- templates/ – templates HTML usando Jinja2.
- static/ – conteúdo estático (CSS, JavaScript, imagens).
- templates/base.html – template base com a estrutura comum das páginas.
- templates/index.html – página principal com o CRUD da tarefa.
- templates/update.html – página de edição de uma tarefa.
- models.py (opcional) – modelo de dados com SQLAlchemy (em app.py neste guia para simplicidade).
Exemplo conceitual de arquivos-chave (trechos resumidos):
# app.py (trecho)
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return f'Todo {self.id} - {self.content}'
Com o layout descrito, a interface fica simples porém funcional, com clara separação entre lógica de aplicação, templates e estilos.
Templates e conteúdo estático
O Flask utiliza o mecanismo de templates Jinja2 para gerar HTML dinâmico. A ideia central é criar um template base que define a cabeça, o rodapé e a estrutura comum, permitindo que as páginas herdem dessa base e apenas especifiquem o conteúdo relevante.
Exemplo de base.html (template base):
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Taskmaster – Gerenciador de Tarefas</title>
<style>
/* estilo inline global (evitar exageros) */
</style>
</head>
<body>
<header>
<h1>Taskmaster</h1>
</header>
<main>
<block content></block>
</main>
</body>
</html>
Exemplo de index.html (herda base.html e exibe a lista de tarefas):
<!-- templates/index.html -->
<extends 'base.html'>
<block name="content">
<h2>Tarefas</h2>
<table>
<tr><th>Tarefa</th><th>Criada</th><th>Ações</th></tr>
{% for task in tasks %}
<tr>
<td>{{ task.content }}</td>
<td>{{ task.date_created.date() }}</td>
<td>
<a href="{{ url_for('delete', id=task.id) }}">Excluir</a>
<a href="{{ url_for('update', id=task.id) }}">Atualizar</a>
</td>
</tr>
{% endfor %}
</table>
<form method="post" action="{{ url_for('index') }} ">
<input type="text" name="content" placeholder="Nova tarefa" />
<input type="submit" value="Adicionar">
</form>
</block>
Arquivo update.html segue o mesmo estilo, com um formulário para editar o conteúdo da tarefa selecionada.
Banco de dados com SQLAlchemy
Para gerenciar o estado da aplicação, utilizamos o SQLAlchemy como ORM. A configuração básica envolve a inicialização do objeto SQLAlchemy com o aplicativo Flask e a definição de modelos de dados simples, como o modello Todo representando uma tarefa.
Modelo de dados simples (exemplo ampliado):
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return f''
Criação do banco (em tempo de desenvolvimento):
# Em um shell Python rodando no ambiente virtual
from app import db
db.create_all()
Operações básicas de CRUD com SQLAlchemy aparecem naturalmente no fluxo de rotas da aplicação Flask (criar, ler, atualizar e excluir registros).
Operações CRUD com Flask: fluxo de criação, leitura, atualização e exclusão
A implementação prática de um CRUD com Flask envolve rotas específicas para cada operação, bem como a integração com templates para a apresentação dos dados.
Criação (Create)
Recebemos dados de um formulário via método POST, criamos uma nova instância do modelo Todo e persistimos no banco.
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
task_content = request.form['content']
new_task = Todo(content=task_content)
try:
db.session.add(new_task)
db.session.commit()
return redirect('/')
except:
return 'Erro ao adicionar tarefa'
else:
tasks = Todo.query.order_by(Todo.date_created).all()
return render_template('index.html', tasks=tasks)
Leitura (Read)
A lista de tarefas é obtida a partir de uma consulta ao ORM, ordenada por data de criação.
tasks = Todo.query.order_by(Todo.date_created).all()
Atualização (Update)
A atualização de uma tarefa é realizada através de uma rota que recebe o identificador único (id) da tarefa, exibe o formulário com o conteúdo atual e, em POST, persiste as alterações.
@app.route('/update/', methods=['GET', 'POST'])
def update(id):
task = Todo.query.get_or_404(id)
if request.method == 'POST':
task.content = request.form['content']
try:
db.session.commit()
return redirect('/')
except:
return 'Erro ao atualizar tarefa'
else:
return render_template('update.html', task=task)
Exclusão (Delete)
A exclusão é realizada com base no id da tarefa, removendo o registro correspondente do banco.
@app.route('/delete/')
def delete(id):
task_to_delete = Todo.query.get_or_404(id)
try:
db.session.delete(task_to_delete)
db.session.commit()
return redirect('/')
except:
return 'Erro ao deletar tarefa'
Estilização e experiência de usuário
Para manter a aparência profissional de um blog tech, adotamos um design limpo, com alinhamento, espaçamento consistente e blocos de código destacados de maneira clara. O CSS é incorporado no próprio HTML (tag style) para evitar dependências externas, seguindo a restrição de não usar frameworks de terceiros.
Exemplo de estilos CSS aplicados (extrato):
:root { --bg: #0f1115; --fg: #e9eef8; --accent: #2b9bdc; }
body { background: var(--bg); color: var(--fg); font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
pre { background: #0e111a; border: 1px solid #1e2a38; border-radius: 8px; padding: 1rem; }
Deploy com Heroku (visão geral)
A publicação da aplicação Flask em Heroku envolve alguns passos simples, mantendo a etapa mínima necessária de configuração para que a aplicação rode em seus servidores.
- Instalar a CLI do Heroku e fazer login com sua conta.
- Adicionar Gunicorn como servidor de aplicação (requisito para Heroku com Python).
- Criar um Procfile com a configuração: web: gunicorn app:app.
- Gerar o arquivo requirements.txt com as dependências do ambiente (pip freeze).
- Realizar commit no repositório Git e criar um app no Heroku com git push heroku master.
Observação: o fluxo descreve passo a passo como preparar o projeto para o deploy, incluindo a criação do Procfile e a listagem de dependências através de requirements.txt.
# Exemplo de conteúdo do Procfile
web: gunicorn app:app
# Geração de requirements
pip3 freeze > requirements.txt
Considerações finais e próximos passos
Este guia oferece uma base sólida para entender o ciclo completa do desenvolvimento de uma aplicação Flask com persistência de dados, template rendering e operações CRUD. A partir daqui, é possível evoluir para recursos mais avançados, como autenticação de usuários, validação de formulários com Flask-WTF, migrações de banco de dados com Flask-Migrate, e a integração de estilos mais refinados com CSS moderno.
Boas práticas recomendadas incluem:
- Separar responsabilidades: manter o código de modelo, rotas e templates organizados em módulos.
- Garantir tratamento de erros com mensagens úteis para o usuário e logs para diagnóstico.
- Utilizar migrations para evoluir o schema do banco, mantendo dados consistentes.
- Testes automatizados para validação das rotas, modelos e integrações.
- Preparar a aplicação para produção, com configuração de secret keys, debug desligado e ajustes de performance.
Está desenvolvendo um projeto digital e precisa de um site moderno, performático e bem estruturado?
Eu posso te ajudar a transformar essa ideia em uma solução completa — com foco em performance, design e funcionalidade.
Acesse yurideveloper.com.br ou chame no WhatsApp: (37) 99670-7290. Vamos criar algo incrível juntos!
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!