Published on

Guía de conexión a base de datos con FastAPI y SQLAlchemy

Authors

¡Hola!

Hoy vamos a ver cómo combinar FastAPI y SQLAlchemy para conectar tu aplicación a una base de datos SQLite de forma sencilla, y cómo aprovechar esta configuración para migrar más adelante a PostgreSQL u otras bases de datos relacionales.

1. Requisitos previos

  • Python 3.8 o superior
  • Gestión de dependencias con Poetry
  • Estructura básica de un proyecto FastAPI lista

2. Instalación de paquetes

# Como dependencias de producción
poetry add sqlalchemy aiosqlite
  • SQLAlchemy: biblioteca ORM (Object-Relational Mapping)
  • aiosqlite: driver asíncrono para SQLite

Nota: si planeas gestionar migraciones con Alembic, añade también:

poetry add --dev alembic

3. Configuración de la base de datos (app/db/config.py)

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# Ruta al archivo SQLite
SQLALCHEMY_DATABASE_URL = 'sqlite:///./test.db'

# Opciones específicas de SQLite
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={'check_same_thread': False},
)

# Generador de sesiones por petición
SessionLocal = sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=engine,
)

# Clase base para modelos
Base = declarative_base()
  • connect_args={'check_same_thread': False} elimina la restricción de hilos de SQLite.
  • Llamar a SessionLocal() devuelve una sesión de DB exclusiva para cada petición.

4. Definición del modelo (app/db/models.py)

from sqlalchemy import Column, Integer, String
from app.db.config import Base

class KanaLink(Base):
    __tablename__ = 'kana_links'

    id = Column(Integer, primary_key=True, index=True)
    url = Column(String, unique=True, index=True)
  • Extiende Base para mapear la tabla.
  • unique=True evita URLs duplicadas, e index=True acelera las búsquedas.

5. Convertir la sesión en dependencia (app/db/session.py)

from app.db.config import SessionLocal

 def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()
  • Función generadora que FastAPI gestiona completamente, cerrando la sesión al terminar.

6. Creación de tablas y arranque de la aplicación (main.py)

from fastapi import FastAPI
from app.db.config import engine, Base
from app.db.models import KanaLink
from app.api.sakuhindb import router as sakuhin_router
from app.logging_config import setup_logging

# Configuración de logging
setup_logging()

# Crea las tablas según los modelos si no existen
Base.metadata.create_all(bind=engine)

app = FastAPI()
app.include_router(sakuhin_router, prefix='/api')
  • Al llamar create_all al iniciar, se generan automáticamente las tablas basadas en tus modelos.

7. Ejemplo de uso en un endpoint (app/api/sakuhindb.py)

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.db.session import get_db
from app.services.scraping.sakuhindb.list import SakuhinListScraper
from app.services.scraping.client import ScrapingClient

router = APIRouter()

@router.post('/scraping')
 def scraping(db: Session = Depends(get_db)):
    client = ScrapingClient()
    scraper = SakuhinListScraper(client)
    inserted = scraper.save_links(db)
    return {'inserted_count': inserted}
  • Usa Depends(get_db) para inyectar la sesión de DB en el endpoint.
  • El método save_links guarda los resultados del scraper y devuelve el número de registros insertados.

Resumen

  • SQLAlchemy + SQLite es perfecto para prototipos rápidos.
  • Combina FastAPI Depends para automatizar la gestión de sesiones.
  • Migrar a PostgreSQL o integrar Alembic más adelante es muy sencillo.

¡Prueba esta configuración y, si todo funciona, anímate a implementar migraciones y bases de datos relacionales más avanzadas!