Flask与数据库:SQLAlchemy模型定义

在Web开发中,数据库是存储和管理数据的核心。Flask本身不内置数据库操作功能,但借助扩展库SQLAlchemy可以轻松实现与数据库的交互。SQLAlchemy是一个强大的ORM(对象关系映射)工具,它允许我们通过Python对象直接操作数据库,无需编写复杂的SQL语句。

一、安装必要的库

首先需要安装Flask和Flask-SQLAlchemy(Flask的SQLAlchemy扩展)。如果使用SQLite数据库(适合开发环境),无需额外安装驱动;若使用MySQL或PostgreSQL,需安装对应驱动(如pymysqlpsycopg2)。

pip install flask flask-sqlalchemy

二、初始化Flask应用与SQLAlchemy

在项目中创建app.py,首先导入必要的库并初始化Flask应用和SQLAlchemy:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 初始化Flask应用
app = Flask(__name__)

# 配置数据库连接URI(这里使用SQLite,文件名为mydatabase.db)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
# 关闭SQLAlchemy的修改跟踪(减少性能开销)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化SQLAlchemy实例,绑定到Flask应用
db = SQLAlchemy(app)

三、定义第一个模型

模型本质是Python类,继承自db.Model,类属性对应数据库表的字段。以下是一个简单的User模型示例:

class User(db.Model):
    # 1. 主键字段(自增整数)
    id = db.Column(db.Integer, primary_key=True)

    # 2. 普通字段:字符串类型,长度50,不可为空,唯一
    username = db.Column(db.String(50), nullable=False, unique=True)

    # 3. 字符串类型,长度120,唯一,不可为空
    email = db.Column(db.String(120), unique=True, nullable=False)

    # 4. 整数类型,允许为空
    age = db.Column(db.Integer)

    # 5. 文本类型,存储长文本
    bio = db.Column(db.Text)

    # __repr__方法:对象打印时显示友好信息
    def __repr__(self):
        return f'<User {self.username}>'

模型字段类型与参数说明

字段类型 说明 常用参数
db.Integer 整数类型 primary_key=True(主键)
db.String(n) 字符串类型,n为最大长度 nullable=False(不可为空)
db.Text 长文本类型 default(默认值)
db.Boolean 布尔类型 default=False
db.DateTime 日期时间类型 default=datetime.utcnow

关键参数
- primary_key=True:设为主键,唯一且自增
- unique=True:字段值唯一(如用户名、邮箱)
- nullable=False:字段不可为空(必填)
- default:设置默认值(如default=0表示默认年龄为0)

四、定义带关系的模型

实际开发中,数据往往存在关联。以“用户-文章”为例,一个用户可以发布多篇文章(一对多关系):

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)

    # 外键:关联到User表的id字段(User表名默认小写)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    # 定义关系:User模型通过posts属性反向关联到Post
    author = db.relationship('User', backref=db.backref('posts', lazy=True))

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

关系说明
- db.ForeignKey('user.id'):外键约束,确保user_id必须是User表中已存在的id
- relationship('User', backref=...):定义User和Post的双向关系,backref让User自动拥有posts属性(如user.posts可获取该用户的所有文章)

五、创建数据库表

定义好模型后,需要将模型映射到数据库表。通过db.create_all()方法自动创建表(需在应用上下文中执行):

# 在应用上下文中创建表
with app.app_context():
    db.create_all()  # 生成所有模型对应的表

注意:若模型有修改(如新增字段),需重新执行db.create_all(),但SQLAlchemy会自动处理表结构更新(不会删除已有数据)。

六、使用模型进行数据操作

模型定义完成后,即可通过Python对象操作数据库(CRUD:增删改查)。以下是常见操作示例:

1. 创建记录(新增数据)

# 创建用户
new_user = User(
    username="张三",
    email="zhangsan@example.com",
    age=25,
    bio="热爱编程的初学者"
)

# 添加到数据库会话并提交
db.session.add(new_user)
db.session.commit()

2. 查询记录

# 查询所有用户
all_users = User.query.all()
print(all_users)  # 输出:[<User 张三>, ...]

# 按条件查询(如查用户名是“张三”的用户)
user = User.query.filter_by(username="张三").first()
print(user.age)  # 输出:25

# 关联查询(获取用户的所有文章)
user = User.query.get(1)  # 获取id=1的用户
posts = user.posts  # 通过posts属性获取该用户的文章列表

3. 更新记录

user = User.query.filter_by(username="张三").first()
user.age = 26  # 修改年龄
db.session.commit()  # 提交修改

4. 删除记录

user = User.query.filter_by(username="张三").first()
db.session.delete(user)  # 标记删除
db.session.commit()  # 执行删除

七、总结

SQLAlchemy模型定义是Flask与数据库交互的基础。通过定义继承db.Model的Python类,我们可以:
- 用类属性映射数据库表字段
- 通过db.Column设置字段类型和约束
- 用relationship定义表间关系
- 通过db.create_all()自动创建表结构

掌握模型定义后,即可轻松实现数据的增删改查,无需直接编写SQL语句。后续可进一步学习更复杂的表关系(如多对多)和高级查询技巧。

提示:开发时可使用flask shell快速测试模型操作,执行flask shell后在Python环境中导入模型并操作。

小夜