前置阅读,关于
Flask-SQLAlchemy
支持哪些数据库及基本配置,链接:Flask-SQLAlchemy_数据库配置
摘要
本文以一段典型的 SQLAlchemy 代码示例为引入,阐述以下核心概念:
- 模型类(Model Class) ↔ 数据库表(Database Table)
- 类属性(db.Column) ↔ 表字段(Table Columns)
- 外键(ForeignKey) ↔ 关系映射(relationship)
通过集中解释属性定义、关系概念与示例,帮助读者快速掌握 SQLAlchemy 在 Flask 应用中的基本用法。
1. 代码示例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
# 初始化 Flask 应用
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db' # 使用 SQLite 数据库
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 初始化 SQLAlchemy
db = SQLAlchemy(app)
# 用户模型(映射 user 表)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
posts = db.relationship('Post', backref='author', lazy='select')
# 内容模型(映射 post 表)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
create_time = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
# 创建所有模型对应的数据库表
with app.app_context():
db.create_all()
2. 核心概念
2.1 模型类(Model Class) ↔ 数据库表(Database Table)
- 每个继承自
db.Model
的类都对应一张数据库表,默认表名为类名小写(如User
类对应user
表)。 - 在执行
db.create_all()
时,SQLAlchemy 会检查数据库中是否存在对应的表:若表不存在则根据模型定义创建新表;若表已存在,则不会对其进行修改或删除,从而保证不会重复创建或覆盖已有数据。
2.2 类属性(db.Column) ↔ 表字段(Table Columns)
在 SQLAlchemy 中,通过 db.Column()
在模型类中定义字段,其调用签名为:
db.Column(type_, *args, **kwargs)
type_
:字段的数据类型,如db.Integer
、db.String(长度)
、db.Text
、db.DateTime
等。*args
:可选位置参数,如db.ForeignKey('表名.字段名')
。**kwargs
:关键字参数控制字段约束与行为,包括:primary_key=True
:主键。unique=True
:唯一约束。nullable=False
:非空约束。default=...
:Python 层面的默认值。server_default=text('...')
:数据库层面的默认值(需导入from sqlalchemy import text
)。index=True
:创建索引。autoincrement=True
:整型主键自动递增。comment='...'
:列注释。doc='...'
:ORM 文档字符串。
2.3 外键(ForeignKey) ↔ 关系映射(relationship)
2.3.1 外键(ForeignKey)
- 外键 是关系型数据库中用于维护表间引用完整性的约束机制,本质是一张表(子表)中的列,其值必须匹配另一张表(父表)中某列(通常是主键)的有效值。
- 需要通过
db.Column
中传入db.ForeignKey('目标表.目标列')
来定义,对应数据库表中的一列。
示例
# Post 模型中的外键字段,定义为类属性,映射到数据库表的 user_id 列
user_id = db.Column(
db.Integer,
db.ForeignKey('user.id'), # 在 Column 中声明外键
nullable=False
)
2.3.2 关系映射(relationship)
- 关系映射 用于在模型之间建立对象关联:它不在数据库中创建新列,而是为模型添加属性,方便在 ORM 中通过属性访问相关对象。
relationship('TargetModel', backref='reverse_attr', lazy=...)
,即可实现双向导航:
- 目标模型名 (
'TargetModel'
):指定关联的模型类名称(字符串形式)。 backref
参数:在目标模型中创建反向属性reverse_attr
,可以自动关联到唯一外键。lazy
参数:控制加载策略,如select
(默认,访问时发起查询)、joined
(关联加载)、subquery
等。
示例:一对多关系
class User(db.Model):
# ... 字段定义 ...
posts = db.relationship(
'Post', # 目标模型类名
backref='author', # 在 Post 中创建 author 属性
lazy='select' # 默认延迟加载
)
class Post(db.Model):
# ... 字段定义 ...
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
posts
属性(“一”方)user.posts
返回一个列表,包含该用户所有的Post
对象。
author
属性(“多”方)post.author
直接返回对应的User
对象。