Flask-SQLAlchemy核心概念:模型类与数据库表、类属性与表字段、外键与关系映射

发布于:2025-05-22 ⋅ 阅读:(17) ⋅ 点赞:(0)

前置阅读,关于Flask-SQLAlchemy支持哪些数据库及基本配置,链接:Flask-SQLAlchemy_数据库配置

摘要

本文以一段典型的 SQLAlchemy 代码示例为引入,阐述以下核心概念:

  1. 模型类(Model Class) ↔ 数据库表(Database Table)
  2. 类属性(db.Column) ↔ 表字段(Table Columns)
  3. 外键(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.Integerdb.String(长度)db.Textdb.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 对象。

网站公告

今日签到

点亮在社区的每一天
去签到