Tu primera app Flask con SQLite, de verdad completa
No un hola mundo: una app Flask con base de datos SQLite, rutas, plantillas y un formulario que guarda datos. La base sobre la que se construye todo lo demás.
La mayoría de tutoriales de Flask terminan justo donde empieza lo interesante: cuando necesitas guardar datos. Aquí vamos a construir una app pequeña pero completa —una lista de notas— con base de datos real, para tener la estructura sobre la que luego crece cualquier proyecto.
Lo que vamos a construir
Una app con tres piezas: una ruta que muestra las notas guardadas, un formulario para crear una nota nueva, y una base de datos SQLite que las persiste. Nada de librerías pesadas: Flask y la librería sqlite3 que ya viene con Python.
Estructura del proyecto
notas/
├── app.py
├── schema.sql
└── templates/
└── index.html
La base de datos
Primero el esquema. Un solo campo de texto y una fecha:
CREATE TABLE IF NOT EXISTS notas (
id INTEGER PRIMARY KEY AUTOINCREMENT,
contenido TEXT NOT NULL,
creada TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
La aplicación
import sqlite3
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
DB = "notas.db"
def get_db():
conn = sqlite3.connect(DB)
conn.row_factory = sqlite3.Row
return conn
@app.route("/")
def index():
db = get_db()
notas = db.execute("SELECT * FROM notas ORDER BY creada DESC").fetchall()
db.close()
return render_template("index.html", notas=notas)
@app.route("/crear", methods=["POST"])
def crear():
contenido = request.form["contenido"].strip()
if contenido:
db = get_db()
db.execute("INSERT INTO notas (contenido) VALUES (?)", (contenido,))
db.commit()
db.close()
return redirect(url_for("index"))
if __name__ == "__main__":
app.run(debug=True)
Fíjate en el detalle que evita el error más común: usamos parámetros (?) en el INSERT en vez de meter el texto directo en la consulta. Eso previene inyección SQL, y es un hábito que conviene tener desde la primera app.
La plantilla
<form action="/crear" method="post">
<input name="contenido" placeholder="Nueva nota" required>
<button>Guardar</button>
</form>
<ul>
{% for nota in notas %}
<li>{{ nota.contenido }}</li>
{% endfor %}
</ul>
Antes de ejecutar
Inicializa la base una vez con el esquema:
sqlite3 notas.db < schema.sql
python app.py
Y ya tienes una app que guarda datos de verdad. A partir de aquí, todo lo demás —editar, borrar, usuarios, API— son variaciones sobre esta misma estructura. En próximos artículos la vamos ampliando.