2025-07-24
开发
00
请注意,本文编写于 134 天前,最后修改于 134 天前,其中某些信息可能已经过时。

目录

1. 初始化Flask与SQLAlchemy
安装SQLAlchemy
配置Flask应用
2. 创建模型
定义基本模型
创建数据库表
3. 向模型中插入数据
插入数据
4. 查询模型
查询所有数据
查询单个对象
查询条件过滤
查询带条件并排序
5. 更新数据
更新数据
6. 删除数据
删除数据
7. 数据模型的关系
一对多关系(例如,用户和文章)
查询一对多关系
多对多关系(例如,学生和课程)
查询多对多关系
8. 数据库索引
创建索引
联合索引
9. 查询优化
延迟加载

1. 初始化Flask与SQLAlchemy

首先,我们需要为Flask应用配置数据库连接并初始化SQLAlchemy。Flask使用Flask-SQLAlchemy扩展来简化与数据库的交互。

安装SQLAlchemy

bash
pip install Flask-SQLAlchemy

配置Flask应用

python
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 配置数据库URI,Flask-SQLAlchemy支持多种数据库,如SQLite、MySQL、PostgreSQL等 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' # SQLite数据库 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 禁用信号系统,减少不必要的开销 app.secret_key = 'your_secret_key' # 用于会话加密 # 初始化SQLAlchemy db = SQLAlchemy(app)

2. 创建模型

在Flask中,模型通常是与数据库表一一对应的Python类。SQLAlchemy会自动将类的属性映射为数据库表的列。

定义基本模型

python
class User(db.Model): id = db.Column(db.Integer, primary_key=True) # 主键 username = db.Column(db.String(120), unique=True, nullable=False) # 用户名,必须唯一且不能为空 email = db.Column(db.String(120), unique=True, nullable=False) # 邮箱,必须唯一且不能为空 password = db.Column(db.String(60), nullable=False) # 密码 def __repr__(self): return f"User('{self.username}', '{self.email}')"
  • db.Column: 用于定义数据库表的字段。参数包括数据类型(如Integer, String),约束(如primary_key, nullable, unique)。
  • __repr__: 用于定义对象的字符串表示,方便调试时查看对象。

创建数据库表

在定义模型后,需要在数据库中创建对应的表。你可以使用db.create_all()来创建所有定义的表。

python
with app.app_context(): db.create_all() # 创建数据库表

3. 向模型中插入数据

你可以通过创建模型实例并将其添加到数据库会话(session)中来插入数据。

插入数据

python
@app.route('/create_user') def create_user(): user = User(username='johndoe', email='johndoe@example.com', password='password123') db.session.add(user) # 将用户对象添加到会话中 db.session.commit() # 提交事务,将数据保存到数据库 return 'User created!'

4. 查询模型

Flask-SQLAlchemy提供了许多用于查询数据库的方法。你可以使用query对象进行各种查询操作。

查询所有数据

python
@app.route('/all_users') def all_users(): users = User.query.all() # 查询所有用户 return '<br>'.join([user.username for user in users]) # 显示所有用户的用户名

查询单个对象

python
@app.route('/get_user/<int:id>') def get_user(id): user = User.query.get_or_404(id) # 根据ID查询用户,如果没有找到,返回404 return f'Username: {user.username}, Email: {user.email}'

查询条件过滤

python
@app.route('/get_user_by_email/<string:email>') def get_user_by_email(email): user = User.query.filter_by(email=email).first() # 按照邮箱查询第一个匹配的用户 if user: return f'Username: {user.username}, Email: {user.email}' return 'User not found'

查询带条件并排序

python
@app.route('/get_users_sorted') def get_users_sorted(): users = User.query.filter_by(username='johndoe').order_by(User.email.desc()).all() # 按邮箱降序排序 return '<br>'.join([f'{user.username}: {user.email}' for user in users])

5. 更新数据

你可以通过获取模型对象,修改其属性,再提交事务来更新数据。

更新数据

python
@app.route('/update_user/<int:id>') def update_user(id): user = User.query.get_or_404(id) # 获取用户 user.email = 'newemail@example.com' # 更新邮箱 db.session.commit() # 提交更新 return f'Updated user {user.username} with new email: {user.email}'

6. 删除数据

要删除数据,你需要从数据库会话中删除模型对象,然后提交事务。

删除数据

python
@app.route('/delete_user/<int:id>') def delete_user(id): user = User.query.get_or_404(id) # 获取用户 db.session.delete(user) # 删除用户 db.session.commit() # 提交删除 return f'Deleted user {user.username}'

7. 数据模型的关系

在Flask应用中,常常需要处理不同模型之间的关系,例如一对多、多对多等关系。SQLAlchemy通过外键(ForeignKey)来实现模型之间的关联。

一对多关系(例如,用户和文章)

python
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 = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # 外键关联到User模型 user = db.relationship('User', backref=db.backref('posts', lazy=True)) # 定义关系
  • user_id字段是Post表的外键,指向User表的id
  • db.relationship定义了在UserPost之间的一对多关系。backref允许我们通过User对象访问posts

查询一对多关系

python
@app.route('/user_posts/<int:user_id>') def user_posts(user_id): user = User.query.get_or_404(user_id) posts = user.posts # 获取用户的所有文章 return '<br>'.join([post.title for post in posts])

多对多关系(例如,学生和课程)

python
class Course(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) class Student(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) courses = db.relationship('Course', secondary='enrollment', backref=db.backref('students', lazy=True)) class Enrollment(db.Model): id = db.Column(db.Integer, primary_key=True) student_id = db.Column(db.Integer, db.ForeignKey('student.id'), nullable=False) course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
  • Enrollment表充当多对多关系的关联表。

查询多对多关系

python
@app.route('/student_courses/<int:student_id>') def student_courses(student_id): student = Student.query.get_or_404(student_id) courses = student.courses # 获取学生所修的所有课程 return '<br>'.join([course.name for course in courses])

8. 数据库索引

数据库索引对于提高查询效率非常重要,尤其是在大型数据集上。你可以为模型字段创建索引,以提高查询性能。

创建索引

python
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(120), unique=True, nullable=False, index=True) # 在用户名上创建索引 email = db.Column(db.String(120), unique=True, nullable=False, index=True) # 在邮箱上创建索引
  • index=True:创建索引,适用于查询频繁的字段。

联合索引

如果你需要多个字段联合查询时加速查询,可以创建联合索引。

python
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(120), nullable=False) email = db.Column(db.String(120), nullable=False) __table_args__ = ( db.Index('ix_username_email', 'username', 'email'), # 创建联合索引 )

9. 查询优化

当你查询大量数据时,可以通过lazy加载来优化查询,减少不必要的查询。

延迟加载

python
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(120), nullable=False) posts = db.relationship('Post', lazy='dynamic') # 使用动态加载 @app.route('/user_posts/<int:user_id>') def user_posts(user_id): user = User.query.get_or_404(user_id) posts = user.posts.all() # 执行查询 return '<br>'.join([post.title for post in posts])
  • lazy='dynamic':将关系查询延迟到需要访问时再执行,避免一次性加载所有数据。

本文作者:晏秋

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!