Flask框架如何使用ORM连接数据库,需要注意什么?
- 云服务器
- 2026-07-24
- 8
Flask 使用 ORM 连接数据库的方法示例
Flask 是一个轻量级 Python Web 框架,本身不包含数据库抽象层,但可以方便地集成 ORM(对象关系映射)工具,如 SQLAlchemy 或 Peewee,其中最常用的是 Flask-SQLAlchemy,它简化了 SQLAlchemy 在 Flask 项目中的配置和使用,以下逐步介绍如何通过 Flask-SQLAlchemy 连接数据库并进行基本操作。
安装依赖
首先安装 Flask 和 Flask-SQLAlchemy,如果使用 MySQL 或 PostgreSQL,还需安装对应的数据库驱动。

配置数据库连接
在 Flask 应用的配置文件中设置数据库 URI,常见的数据库 URI 格式如下:
| 数据库类型 | URI 示例 |
|---|---|
| SQLite | sqlite:///site.db |
| MySQL | mysql+pymysql://username:password@host:port/dbname |
| PostgreSQL | postgresql://username:password@host:port/dbname |
示例代码(app.py):
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 配置数据库 URI,推荐使用环境变量 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 关闭跟踪修改 db = SQLAlchemy(app)
定义模型(ORM 类)
模型对应数据库中的表,通过继承 db.Model 来定义,每个字段使用 db.Column 并指定类型和约束。

class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) age = db.Column(db.Integer, default=18) def __repr__(self): return f'<User {self.username}>'
创建数据库表
在应用上下文内调用 db.create_all() 即可根据模型创建所有表,通常放在 Flask 命令或应用首次启动时执行。
with app.app_context(): db.create_all() # 创建所有未存在的表
基本 CRUD 操作
以下示例演示如何添加、查询、更新和删除记录。

from flask import Flask, request, jsonify @app.route('/add_user', methods=['POST']) def add_user(): data = request.get_json() new_user = User(username=data['username'], email=data['email'], age=data.get('age', 18)) db.session.add(new_user) db.session.commit() return jsonify({'message': 'User created', 'id': new_user.id}), 201 @app.route('/users') def get_users(): users = User.query.all() # 查询所有用户 return jsonify([{'id': u.id, 'username': u.username, 'email': u.email} for u in users]) @app.route('/user/<int:user_id>', methods=['PUT']) def update_user(user_id): user = User.query.get_or_404(user_id) data = request.get_json() user.username = data.get('username', user.username) user.email = data.get('email', user.email) db.session.commit() return jsonify({'message': 'User updated'}) @app.route('/user/<int:user_id>', methods=['DELETE']) def delete_user(user_id): user = User.query.get_or_404(user_id) db.session.delete(user) db.session.commit() return jsonify({'message': 'User deleted'})
使用原生 SQL 与 ORM 共存
某些场景下需要直接执行 SQL 语句,可通过 db.session.execute() 实现。
result = db.session.execute('SELECT FROM user WHERE age > :age', {'age': 20}) rows = result.fetchall()
常见问题与注意事项
- 数据库迁移:生产环境推荐使用 Flask-Migrate(基于 Alembic)管理数据库模式变更。
- 连接池:Flask-SQLAlchemy 默认使用连接池,可通过 SQLALCHEMY_POOL_SIZE 等参数调整。
- 多数据库绑定:支持多个数据库,通过 SQLALCHEMY_BINDS 配置。
相关问题与解答
问题 1:Flask 中如何切换开发环境和生产环境的数据库?
解答:
可以通过环境变量来动态设置数据库 URI,例如在配置文件中读取 os.environ.get('DATABASE_URL'),默认为开发环境数据库,生产环境部署时,在系统环境变量中设置 DATABASE_URL 指向生产数据库,同时建议使用 config.py 分离配置,不同环境加载不同配置类。
import os class Config: SQLALCHEMY_TRACK_MODIFICATIONS = False class DevelopmentConfig(Config): SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db' class ProductionConfig(Config): SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'postgresql://user:pass@localhost/prod_db')
问题 2:使用 ORM 时如何避免 N+1 查询问题?
解答:
N+1 查询常见于关联模型查询时,每次循环都额外执行一次查询,解决方法:
- 使用 joinedload() 或 subqueryload() 提前加载关联数据。
- 例如查询用户及其文章时: from sqlalchemy.orm import joinedload users = User.query.options(joinedload(User.posts)).all()
- 或使用 lazy='joined' 或 lazy='subquery' 在模型关系定义时指定加载策略,但需注意全局默认可能影响性能。
- 对于复杂查询,考虑直接使用 db.session.execute() 编写 JOIN 语句。