Pular para o conteúdo principal

Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker

Criando uma Aplicação CRUD com Flask, PostgreSQL e Docker

Neste guia, vamos criar uma aplicação básica que acessa um banco de dados PostgreSQL e realiza operações CRUD (Create, Read, Update, Delete). Vamos usar Flask e executar tudo com Docker. Sem estilos ou extras, apenas o essencial.

Estrutura do Projeto

crud-app/
|-- app/
|   |-- app.py
|   |-- templates/
|   |   |-- index.html
|   |   |-- edit.html
|-- Dockerfile
|-- requirements.txt
|-- docker-compose.yml

Passo 1: Dependências

Crie um arquivo requirements.txt com as seguintes linhas:

Flask==2.2.2
Flask-SQLAlchemy==3.0.2
psycopg2-binary==2.9.3
Werkzeug==2.2.2

Passo 2: Aplicação Flask

Arquivo app/app.py:

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# Configuração do banco de dados
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@db:5432/crud_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Modelo
class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)

# Criação automática das tabelas
@app.before_first_request
def create_tables():
    db.create_all()

@app.route('/')
def index():
    items = Item.query.all()
    return render_template('index.html', items=items)

@app.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit(id):
    item = Item.query.get(id)
    if request.method == 'POST':
        item.name = request.form['name']
        db.session.commit()
        return redirect(url_for('index'))
    return render_template('edit.html', item=item)

@app.route('/add', methods=['POST'])
def add():
    new_item = Item(name=request.form['name'])
    db.session.add(new_item)
    db.session.commit()
    return redirect(url_for('index'))

@app.route('/delete/<int:id>')
def delete(id):
    item = Item.query.get(id)
    db.session.delete(item)
    db.session.commit()
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

Passo 3: Templates HTML

Arquivo app/templates/index.html:

<!DOCTYPE html>
<html>
<head>
    <title>CRUD App</title>
</head>
<body>
    <h1>Lista de Itens</h1>
    <form action="/add" method="post">
        <input type="text" name="name" placeholder="Novo Item" required>
        <button type="submit">Adicionar</button>
    </form>
    <ul>
        {% for item in items %}
        <li>
            {{ item.name }} - <a href="/edit/{{ item.id }}">Editar</a> | <a href="/delete/{{ item.id }}">Excluir</a>
        </li>
        {% endfor %}
    </ul>
</body>
</html>

Arquivo app/templates/edit.html:

<!DOCTYPE html>
<html>
<head>
    <title>Editar Item</title>
</head>
<body>
    <h1>Editar Item</h1>
    <form action="/edit/{{ item.id }}" method="post">
        <input type="text" name="name" value="{{ item.name }}" required>
        <button type="submit">Salvar</button>
    </form>
    <a href="/">Voltar</a>
</body>
</html>

Passo 4: Configurando o Docker

Arquivo Dockerfile:

FROM python:3.9

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000
CMD ["python", "app/app.py"]

Arquivo docker-compose.yml:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/app
    depends_on:
      - db
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: crud_db
    ports:
      - "5432:5432"

Passo 5: Executando o Projeto

  1. Suba os contêineres:

    docker-compose up --build
    
  2. Acesse a aplicação em http://localhost:5000.


E pronto! Sua aplicação CRUD com Flask, PostgreSQL e Docker está funcionando. 

Esse projeto pode ser encontrado aqui.

Comentários

Mais visitadas

Listar arquivos existentes em diretório (Delphi)

Mostraremos uma maneira simples e prática para listar o conteúdo de um diretório com a opção de incluir nessa listagem os arquivos de seus subdiretórios. No exemplo abaixo temos um Edit para receber o diretório a ser pesquisado um CheckBox para indicar se os subdiretórios entrarão na pesquisa um botão para efetuar a pesquisa e um Memo para listar os arquivos encontrados, no final um Edit que receberá o cálculo final (em bytes) da soma do tamanho dos arquivos. procedure TForm1.Button1Click(Sender: TObject); begin   tamanhoTotal := 0;   memLista.Lines.Clear;   ListarArquivos(edtDiretorio.Text, chkSub.Checked);   Edit1.Text := IntToStr( tamanhoTotal ); end; procedure TForm1.ListarArquivos(Diretorio: string; Sub:Boolean); var   F: TSearchRec;   Ret: Integer;   TempNome: string; begin   Ret := FindFirst(Diretorio+'\*.*', faAnyFile, F);   try     while Ret = 0 do ...

Funções de data Oracle

  Com o Oracle é possível obter uma série de resultados a partir de uma ou mais datas, como por exemplo verificar o último dia do mês ou verificar a quantidade de meses entre duas datas, então vamos a alguns exemplos:   Data atual do sistema: SYSDATE Remover meses de uma data: ADD_MONTHS(SYSDATE, -1) Adicionar meses de uma data: ADD_MONTHS(SYSDATE, +1) Buscar o último dia do mês: LAST_DAY(SYSDATE) Primeiro dia do mês: TRUNC(SYSDATE, ‘MONTH’) Quantidade de meses entre duas datas: MONTHS_BETWEEN(SYSDATE, ‘27/07/1982’) Primeiro dia do ano: TRUNC(SYSDATE, ‘YEAR’) Dias da semana: DECODE( TO_NUMBER( TO_CHAR          (SYSDATE, ‘D’) ) ,1, ‘domingo’ ,2, ‘segunda-feira’ ,3, ‘terça-feira’ ,4, ‘quarta-feira’ ,5, ‘quinta-feira’ ,6, ‘sexta-feira’ ,7,’sábado’ )

Lista de políticos com ficha suja

ATUALIZAÇÃO (08/03/2012 ano de eleição) Representantes de duas pessoas da lista (Eliseu Padilha e Alex Canziani) entraram em contato e pediram que esses fossem removidos, alegando que não houve condenação. É justo essa requisição, porém vale lembrar que escândalos nacionalmente reconhecidos de corrupção não deram em nada, por isso o que realmente conta nesse ano de eleição é uma pesquisa minuciosa sobre os candidatos escolhidos, eu particularmente, por não estar nem um pouco satisfeito, não irei votar em ninguém que já tenha sido eleito. Estou voltando a postar por um motivo nobre, meu tempo continua apertado mas esse post é rápido, na verdade nem meu ele é (visitem o espaço de nosso amigo Lord ), estou apenas repassando essa valiosa informação. Teremos eleição esse ano, e é importante não repetirmos erros passados, vamos ficar atentos em relação a esses nomes e exclui-los de vez do cenário politico nacional. Façamos nossa parte, publicando em nossos blog...