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
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
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
| Feldtyp | Datenbanktyp | Häufige Parameter |
|---|---|---|
| db.Integer | INTEGER | primary_key, autoincrement |
| db.String(N) | VARCHAR(N) | unique, nullable, default |
| db.Text | TEXT | default |
| db.DateTime | DATETIME | default, onupdate |
| db.Boolean | BOOLEAN | default |
| 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
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
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 SQL | Rückgabewert |
|---|---|---|
| Post.query.all() | SELECT * FROM posts | Liste |
| Post.query.get(1) | WHERE id = 1 | Ein einzelnes Objekt oder None |
| Post.query.get_or_404(1) | WHERE id = 1 | Ein einzelnes Objekt oder gibt automatisch 404 zurück |
| Post.query.filter_by(category_id=1).all() | WHERE category_id=1 | Liste |
| 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 DESC | Liste |
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