Pagination in Python mit Flask und SQLAlchemy

Pagination ist ein häufiges Feature bei der Entwicklung von Web-Anwendungen, die große Datenmengen anzeigen müssen. Es ist besonders nützlich, um die Ladezeit zu reduzieren und die Benutzererfahrung zu verbessern. In diesem Blog-Post werden wir uns ansehen, wie man eine Pagination in Python mit Flask und SQLAlchemy umsetzen kann.

Flask und SQLAlchemy mit pip installieren

Zunächst müssen wir sicherstellen, dass Flask und SQLAlchemy installiert sind. Falls nicht, können Sie sie mit den folgenden Befehlen installieren:

pip install flask
pip install sqlalchemy

Datenbankverbindung in Flask mit SQLAlchemy herstellen

Wir erstellen nun eine Flask-App mit einer SQLAlchemy-Datenbankverbindung. In diesem Beispiel werden wir eine SQLite-Datenbank verwenden. So sieht der erste Teil unserer Flask-App aus:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)

SQLAlchemy Modellklasse erstellen

Als nächstes erstellen wir eine SQLAlchemy-Modellklasse für unsere Daten. In diesem Beispiel werden wir eine einfache „Person“-Tabelle erstellen:

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    age = db.Column(db.Integer)

Testdaten zur Datenbank hinzufügen

Außerdem wollen wir nun noch einige Testdaten zur Datenbank hinzufügen.

def insert_test_data():
    test_names = ["Anna", "Benedikt", "Catharina", "David", "Elena", "Fabian", "Greta", "Hannes", "Isabel", "Jonas", "Katharina", "Lena", "Marcel", "Nina", "Oliver", "Paul", "Quirin", "Raphael", "Sophia", "Theresa", "Ulrich", "Valerie", "Wilhelm", "Xaver", "Yara", "Zacharias", "Emma", "Felix", "Hannah", "Julia"]
    test_ages = [25, 34, 19, 42, 31, 27, 23, 29, 38, 22, 26, 30, 35, 28, 33, 20, 37, 24, 32, 21, 40, 36, 39, 45, 18, 28, 26, 30, 29, 31]
    for i in range(30):
        person = Person(name=test_names[i], age=test_ages[i])
        db.session.add(person)
    db.session.commit()

with app.app_context():
    db.create_all()
    insert_test_data()

Wichtig: Diese Funktionen werden wir nach dem erstmaligen Aufrufen der Flask-App wieder entfernen, da ansonsten bei jedem erneuten Aufruf weitere Daten in unsere Datenbank geschrieben werden.

Flask erstellt automatisch ein instance Verzeichnis und erstellt unsere Datenbank in diesem Verzeichnis. Mehr zum Thema Instance Verzeichnisse kann hier nachgelesen werden.

Tipp am Rande: Ein tolles kleines Tool für das Management von SQLite-Datenbanken ist der DB Browser for SQLite. Mit dem Programm lassen sich sehr einfach neue Datenbanken erstellen oder bereits erstellte Datenbanken öffnen und anpassen.

Pagination-Funktion in Flask erstellen

Jetzt können wir unsere Pagination-Funktion in Flask implementieren. Wir verwenden die paginate()-Methode von SQLAlchemy, um die Daten in Seiten aufzuteilen und sie an die Vorlage weiterzugeben:

@app.route('/')
@app.route('/<int:page>')
def index(page=1):
    per_page = 10
    persons = Person.query.paginate(page=page, per_page=per_page)
    return render_template('index.html', persons=persons)

Hier haben wir eine Funktion namens index() definiert, die den aktuellen Seitenindex page als Parameter annimmt. Wir definieren auch die Anzahl der Datensätze pro Seite per_page.

Innerhalb der Funktion rufen wir Person.query.order_by(Person.id.desc()).paginate() auf, um die Datensätze in der Datenbank abzurufen und sie in Seiten aufzuteilen. Wir sortieren die Datensätze hier nach der ID absteigend.

Schließlich geben wir die persons-Variable an die Vorlage index.html weiter, die wir später erstellen werden.

Template mit Pagination in Flask erstellen

Jetzt müssen wir nur noch unsere Vorlage erstellen, um die Daten auf der Seite anzuzeigen. Hier ist ein Beispiel für eine einfache Vorlage:

{% extends "base.html" %}

{% block content %}
  {% for person in persons.items %}
    <p>{{ person.id }} - {{ person.name }} - {{ person.age }}</p>
  {% endfor %}

  {% if persons.has_prev %}
    <a href="{{ url_for('index', page=persons.prev_num) }}">Previous</a>
  {% endif %}

  {% if persons.has_next %}
    <a href="{{ url_for('index', page=persons.next_num) }}">Next</a>
  {% endif %}
{% endblock %}

In dieser Vorlage verwenden wir die items-Methode, um die Datensätze auf der aktuellen Seite anzuzeigen. Wir überprüfen auch, ob es eine vorherige oder nächste Seite gibt, und erstellen entsprechende Links, um zwischen den Seiten zu navigieren.

Die fertige Flask-App

Und das ist alles! Wir haben erfolgreich eine Pagination in Python mit Flask und SQLAlchemy implementiert. Hier ist der vollständige Code:

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    age = db.Column(db.Integer)

# nach erstmaligem aufruf wieder entfernen
def insert_test_data():
    test_names = ["Anna", "Benedikt", "Catharina", "David", "Elena", "Fabian", "Greta", "Hannes", "Isabel", "Jonas", "Katharina", "Lena", "Marcel", "Nina", "Oliver", "Paul", "Quirin", "Raphael", "Sophia", "Theresa", "Ulrich", "Valerie", "Wilhelm", "Xaver", "Yara", "Zacharias", "Emma", "Felix", "Hannah", "Julia"]
    test_ages = [25, 34, 19, 42, 31, 27, 23, 29, 38, 22, 26, 30, 35, 28, 33, 20, 37, 24, 32, 21, 40, 36, 39, 45, 18, 28, 26, 30, 29, 31]
    for i in range(30):
        person = Person(name=test_names[i], age=test_ages[i])
        db.session.add(person)
    db.session.commit()

# nach erstmaligem aufruf wieder entfernen
with app.app_context():
    db.create_all()
    insert_test_data()

@app.route('/')
@app.route('/<int:page>')
def index(page=1):
    page = page
    per_page = 10
    persons = Person.query.paginate(page=page, per_page=per_page)
    return render_template('index.html', persons=persons)

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

Die __name__ == '__main__'-Bedingung wird verwendet, um sicherzustellen, dass der Server nur gestartet wird, wenn das Skript direkt ausgeführt wird und nicht importiert wird.

Dies ist nur ein einfaches Beispiel dafür, wie man Pagination in Python mit Flask und SQLAlchemy umsetzen kann. Es gibt viele weitere Optionen und Anpassungen, die möglich sind, je nach den spezifischen Anforderungen Ihrer Anwendung.

Das Ganze lässt sich natürlich auch ohne SQLAlchemy umsetzen. In diesem Post erklären wir, wie sich eine Pagination mit Python in Flask und SQLite ohne SQLAlchemy umsetzen lässt.

Ähnliche Beiträge