Flask-SQLAlchemy — Datenbankmodelle entwerfen

In diesem Kapitel lernst du, wie du Datenmodelle mit Flask-SQLAlchemy definierst, SQLite-Datenbanktabellen erstellst und Testdaten einfügst.


Warum ein ORM verwenden?

SQL-Anweisungen direkt zu schreiben, um eine Datenbank zu bearbeiten, ist mühsam und fehleranfällig.

ORM (Objektrelationale Abbildung)Damit können Sie Tabellenstrukturen mit Python-Klassen definieren und Daten mit Python-Methoden bearbeiten.

Flask-SQLAlchemy ist die Flask-Integration von SQLAlchemy, die gängige Operationen kapselt und die Konfiguration vereinfacht.


Installation und Konfiguration

(venv) $ pip install flask-sqlalchemy

Beispiel

# Dateipfad: app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# Pfad zur SQLite-Datenbankdatei (im Projektstammverzeichnis)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
# Änderungsverfolgung deaktivieren (spart Speicher, wird in zukünftigen Versionen standardmäßig deaktiviert)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Eine db-Instanz erstellen und an app binden
db = SQLAlchemy(app)

sqlite:///blog.dbDie drei Schrägstriche darin kennzeichnen einen relativen Pfad. Eine SQLite-Datenbank ist nur eine Datei, für die keine Datenbanksoftware installiert werden muss, was sie ideal für Entwicklung und Tests macht.


Modelle definieren: Post und Category

Beispiel

# Dateipfad: models.py
from datetime import datetime
from app import db

class Category(db.Model):
    """Artikelkategorie"""
    __tablename__ = 'categories'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    slug = db.Column(db.String(50), unique=True, nullable=False)
    # backref: Auf dem Category-Objekt können Sie .posts verwenden, um alle seine Artikel in umgekehrter Reihenfolge abzurufen.
    posts = db.relationship('Post', backref='category', lazy='dynamic')

    def __repr__(self):
        return f'<Category {self.name}>'


class Post(db.Model):
    """Blogbeitrag"""
    __tablename__ = 'posts'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False)
    summary = db.Column(db.Text, default='')
    content = db.Column(db.Text, nullable=False)
    # Fremdschlüssel: db.ForeignKey('table_name.field_name')
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def __repr__(self):
        return f'<Post {self.title}>'

Gängige Feldtypen

FeldtypDatenbanktypHäufige Parameter
db.IntegerINTEGERprimary_key, autoincrement
db.String(N)VARCHAR(N)unique, nullable, default
db.TextTEXTdefault
db.DateTimeDATETIMEdefault, onupdate
db.BooleanBOOLEANdefault
db.ForeignKey('table.field')FOREIGN KEY—

Datenbanktabelle erstellen

Im Gegensatz zu Djangos migrate erfordert Flask die manuelle Initialisierung der Datenbanktabellen.

(venv) $ flask shell                        # 进入 Flask 交互式 Shell

Beispiel

# In der flask shell eingeben
from app import db
db.create_all()     # Datenbanktabellen für alle Modelle erstellen
exit()

Nach der Ausführung wird im Projektstammverzeichnis Folgendes erzeugtblog.dbDatei.

db.create_all()Erstellen Sie die Tabelle nur, wenn sie nicht existiert. Wenn Sie die Modellstruktur ändern (z. B. durch Hinzufügen neuer Felder), wird die Tabelle nicht automatisch aktualisiert. In der Produktion sollten Sie Flask-Migrate (Kapitel 5) verwenden, um Strukturänderungen zu verwalten.


Verwenden Sie flask shell, um Testdaten einzufügen.

Beispiel

# In der flask shell eingeben
from app import db
from models import Category, Post

# 1. 创建
py_cat = Category(name='Python', slug='python')
css_cat = Category(name='CSS', slug='css')
flask_cat = Category(name='Flask', slug='flask')
db.session.add_all([py_cat, css_cat, flask_cat])
db.session.commit()

# 2. Artikel erstellen
post1 = Post(
    title='Flask: Vollständiger Leitfaden für Anfänger',
    slug='flask-beginner-guide',
    summary=Lerne Flask von Grund auf und behandle Kernkonzepte wie Routing, Templates, ORM.,
    content=<h2>Warum Flask lernen?</h2><p>Flask ist das flexibelste Web-Mikroframework in Python...</p>,
    category=flask_cat
)
post2 = Post(
    title=Python-Koroutinen erklärt,
    slug='python-coroutine',
    summary=Verstehe asyncio, Koroutinen und Event-Loops in einem Artikel.,
    content=<h2>Was ist eine Koroutine?</h2><p>Eine Koroutine ist eine leichtgewichtigere Nebenläufigkeitslösung als Threads...</p>,
    category=py_cat
)
post3 = Post(
    title=Praktisches CSS Grid Layout,
    slug='css-grid-layout',
    summary=Komplexe responsive Layouts lassen sich mit CSS Grid einfach umsetzen.,
    content=<h2>Erste Schritte mit Grid</h2><p>Grid ist ein zweidimensionales Layout-System...</p>,
    category=css_cat
)
db.session.add_all([post1, post2, post3])
db.session.commit()

# 3. Abfragen überprüfen
print(Post.query.all())
print(Post.query.filter(Post.category_id == 1).all())

Flask-SQLAlchemy Basisabfragen

MethodenÄquivalentes SQLRückgabewert
Post.query.all()SELECT * FROM postsListe
Post.query.get(1)WHERE id = 1Ein einzelnes Objekt oder None
Post.query.get_or_404(1)WHERE id = 1Ein einzelnes Objekt oder gibt automatisch 404 zurück
Post.query.filter_by(category_id=1).all()WHERE category_id=1Liste
Post.query.filter(Post.title.ilike('%flask%')).all()WHERE title LIKE '%flask%'Liste
Post.query.order_by(Post.created_at.desc()).all()ORDER BY created_at DESCListe

Kapitelzusammenfassung

In diesem Kapitel hast du den kompletten Flask-SQLAlchemy-Workflow gemeistert: Installation und Konfiguration von SQLALCHEMY_DATABASE_URI, Definition von Modellen mit db.Model (Feldtypen/Fremdschlüssel/relationship), Initialisierung von Tabellen mit db.create_all() sowie Einfügen und Abfragen von Daten in der flask shell.

Zu diesem Zeitpunkt sind die Datenstrukturen für Beiträge und Kategorien in der SQLite-Datenbank eingerichtet.

Weitere Erweiterungen