The open blogging platform. Say no to algorithms and paywalls.

Creating a Simple Task CRUD App with Flask, PostgreSQL, SQLAlchemy, and Docker

A step-by-step guide on how to create a simple task CRUD app with Flask, PostgreSQL, SQLAlchemy, and Docker.

In the world of web development, one common task is to build CRUD (Create, Read, Update, Delete) applications. Let’s walk through the process of creating a simple Task CRUD app using Flask, PostgreSQL, SQLAlchemy, and Docker. This tutorial assumes you have a basic understanding of Docker and Python.

Step 1: Set Up Your Development Environment

Before diving in, make sure you have Docker and Docker Compose installed on your system. Create a new directory for your project:

mkdir flask-task-app  
cd flask-task-app

Set up a virtual environment:

python -m venv venv  
source venv/bin/activate

Install the required Python packages:

pip install Flask Flask-SQLAlchemy Flask-Migrate

Step 2: Initialize a Git Repository

Initialize a Git repository in your project directory:

git init

Step 3: Set Up Flask App and Database

Create the following directory structure for your project:

flask-task-app/  
    app/  
        __init__.py  
        models.py  
        views.py  
    migrations/  
    config.py  
    run.py

Inside config.py, configure your Flask application and database:

# config.py  
  
import os  
  
class Config:  
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'your_secret_key'  
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'postgresql://postgres:password@db:5432/tasks'  
    SQLALCHEMY_TRACK_MODIFICATIONS = False

Step 4: Create Database Models

Define your database models inside models.py. For this example, let's create a Task model:

# app/models.py  
  
from app import db  
  
class Task(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    title = db.Column(db.String(100), nullable=False)  
    description = db.Column(db.String(255))

Step 5: Create Flask Views

Create views for your Flask application inside views.py. Implement CRUD operations for tasks:

# app/views.py  
  
from flask import Blueprint, jsonify, request  
from app import db  
from app.models import Task  
  
tasks_bp = Blueprint('tasks', __name__)  
  
@tasks_bp.route('/tasks', methods=['GET'])  
def get_tasks():  
    tasks = Task.query.all()  
    task_list = [{'id': task.id, 'title': task.title, 'description': task.description} for task in tasks]  
    return jsonify(task_list)  
  
@tasks_bp.route('/tasks/<int:id>', methods=['GET'])  
def get_task(id):  
    task = Task.query.get(id)  
    if not task:  
        return jsonify({'message': 'Task not found'}), 404  
    return jsonify({'id': task.id, 'title': task.title, 'description': task.description})  
  
@tasks_bp.route('/tasks', methods=['POST'])  
def create_task():  
    data = request.json  
    task = Task(title=data['title'], description=data['description'])  
    db.session.add(task)  
    db.session.commit()  
    return jsonify({'message': 'Task created successfully'}), 201  
  
@tasks_bp.route('/tasks/<int:id>', methods=['PUT'])  
def update_task(id):  
    task = Task.query.get(id)  
    if not task:  
        return jsonify({'message': 'Task not found'}), 404  
    data = request.json  
    task.title = data['title']  
    task.description = data['description']  
    db.session.commit()  
    return jsonify({'message': 'Task updated successfully'})  
  
@tasks_bp.route('/tasks/<int:id>', methods=['DELETE'])  
def delete_task(id):  
    task = Task.query.get(id)  
    if not task:  
        return jsonify({'message': 'Task not found'}), 404  
    db.session.delete(task)  
    db.session.commit()  
    return jsonify({'message': 'Task deleted successfully'})

Step 6: Initialize Database Migrations

Initialize Alembic for database migrations:

flask db init

Edit the generated migrations/env.py file to load your Flask application and database configuration:

from your_app import create_app, db  
  
app = create_app()  
app.app_context().push()

Step 7: Create Database Migrations

Generate an initial migration:

flask db migrate -m "Initial migration"

Apply the migration to create the database tables:

flask db upgrade

Step 8: Create a Docker Compose File

Create a docker-compose.yml file to define your application and database services:

# docker-compose.yml  
  
version: '3'  
  
services:  
  web:  
    build: .  
    command: python run.py  
    volumes:  
      - ./app:/app  
    ports:  
      - "5000:5000"  
    depends_on:  
      - db  
    environment:  
      FLASK_APP: run.py  
      FLASK_ENV: development  
      SECRET_KEY: your_secret_key  
      SQLALCHEMY_DATABASE_URI: postgresql://postgres:password@db:5432/tasks  
  
  db:  
    image: postgres:latest  
    environment:  
      POSTGRES_USER: postgres  
      POSTGRES_PASSWORD: password  
      POSTGRES_DB: tasks  
    volumes:  
      - postgres_data:/var/lib/postgresql/data  
  
volumes:  
  postgres_data:

Step 9: Create a Dockerfile

Create a Dockerfile to build your Flask application container:

# Dockerfile  
  
FROM python:3.8-slim  
  
WORKDIR /app  
  
COPY requirements.txt requirements.txt  
RUN pip install -r requirements.txt  
  
COPY . .  
  
CMD ["python", "run.py"]

Step 10: Create a Requirements File

Create a requirements.txt file to list your project's dependencies:

Flask==2.0.1  
Flask-SQLAlchemy==2.5.1  
Flask-Migrate==3.1.1

Step 11: Build and Run the Docker Containers

Build and run the Docker containers for your application:

docker-compose up --build

Your Flask Task CRUD app is now running in a Docker container, and you can access it at http://localhost:5000. Use tools like Postman or cURL to interact with the CRUD API.

This is a basic setup, and you can extend it further by adding authentication, more features, and error handling based on your project requirements.




Continue Learning