现在位置: 首页 > Flask 教程 > 正文

Flask-SQLAlchemy — 设计数据库模型

本章你将学会用 Flask-SQLAlchemy 定义数据模型,创建 SQLite 数据库表,并插入测试数据。


为什么要用 ORM?

直接写 SQL 语句操作数据库繁琐且容易出错。

ORM(对象关系映射) 让你用 Python 类来定义表结构,用 Python 方法操作数据。

Flask-SQLAlchemy 是 SQLAlchemy 的 Flask 集成版,封装了常见操作,配置更简单。


安装与配置

(venv) $ pip install flask-sqlalchemy

实例

# 文件路径:app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# SQLite 数据库文件路径(位于项目根目录)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
# 关闭修改追踪(节省内存,将来版本默认关闭)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 创建 db 实例,绑定到 app
db = SQLAlchemy(app)

sqlite:///blog.db 中的三个斜杠表示相对路径。SQLite 数据库就是一个文件,无需安装任何数据库软件,非常适合开发和测试。


定义模型:Post 和 Category

实例

# 文件路径:models.py
from datetime import datetime
from app import db

class Category(db.Model):
    """文章分类"""
    __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:在 Category 对象上可通过 .posts 反向获取其下所有文章
    posts = db.relationship('Post', backref='category', lazy='dynamic')

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


class Post(db.Model):
    """博客文章"""
    __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)
    # 外键:db.ForeignKey('表名.字段名')
    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}>'

常用字段类型

字段类型数据库类型常用参数
db.IntegerINTEGERprimary_key, autoincrement
db.String(N)VARCHAR(N)unique, nullable, default
db.TextTEXTdefault
db.DateTimeDATETIMEdefault, onupdate
db.BooleanBOOLEANdefault
db.ForeignKey('表.字段')FOREIGN KEY

创建数据库表

与 Django 的 migrate 不同,Flask 需要手动初始化数据库表。

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

实例

# 在 flask shell 中输入
from app import db
db.create_all()     # 创建所有模型对应的数据库表
exit()

执行后,项目根目录下会生成 blog.db 文件。

db.create_all() 只在表不存在时才创建。如果修改了模型结构(如新增字段),它不会自动更新表。生产环境中应该用 Flask-Migrate(第五章)管理结构变更。


用 flask shell 插入测试数据

实例

# 在 flask shell 中输入
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. 创建文章
post1 = Post(
    title='Flask 入门完全指南',
    slug='flask-beginner-guide',
    summary='从零开始学习 Flask,涵盖路由、模板、ORM 等核心概念。',
    content='<h2>为什么学 Flask?</h2><p>Flask 是 Python 最灵活的 Web 微框架...</p>',
    category=flask_cat
)
post2 = Post(
    title='Python 协程详解',
    slug='python-coroutine',
    summary='一文搞懂 asyncio、协程、事件循环。',
    content='<h2>什么是协程?</h2><p>协程是一种比线程更轻量的并发方案...</p>',
    category=py_cat
)
post3 = Post(
    title='CSS Grid 布局实战',
    slug='css-grid-layout',
    summary='用 CSS Grid 轻松实现复杂的响应式布局。',
    content='<h2>Grid 入门</h2><p>Grid 是二维布局系统...</p>',
    category=css_cat
)
db.session.add_all([post1, post2, post3])
db.session.commit()

# 3. 验证查询
print(Post.query.all())
print(Post.query.filter(Post.category_id == 1).all())

Flask-SQLAlchemy 基础查询

方法等价 SQL返回值
Post.query.all()SELECT * FROM posts列表
Post.query.get(1)WHERE id = 1单个对象或 None
Post.query.get_or_404(1)WHERE id = 1单个对象或自动返回 404
Post.query.filter_by(category_id=1).all()WHERE category_id=1列表
Post.query.filter(Post.title.ilike('%flask%')).all()WHERE title LIKE '%flask%'列表
Post.query.order_by(Post.created_at.desc()).all()ORDER BY created_at DESC列表

本章小结

本章你掌握了 Flask-SQLAlchemy 的完整流程:安装并配置 SQLALCHEMY_DATABASE_URI、db.Model 定义模型(字段类型/外键/relationship)、db.create_all() 初始化建表、flask shell 中插入与查询数据。

至此,文章和分类的数据结构已在 SQLite 数据库中建立。