在Web开发中,数据库是存储和管理数据的核心。Flask本身不内置数据库操作功能,但借助扩展库SQLAlchemy可以轻松实现与数据库的交互。SQLAlchemy是一个强大的ORM(对象关系映射)工具,它允许我们通过Python对象直接操作数据库,无需编写复杂的SQL语句。
一、安装必要的库¶
首先需要安装Flask和Flask-SQLAlchemy(Flask的SQLAlchemy扩展)。如果使用SQLite数据库(适合开发环境),无需额外安装驱动;若使用MySQL或PostgreSQL,需安装对应驱动(如pymysql或psycopg2)。
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环境中导入模型并操作。