当前位置:首页 > 云服务器 > 正文

Flask框架如何使用ORM连接数据库,需要注意什么?

Flask 使用 ORM 连接数据库的方法示例

Flask 是一个轻量级 Python Web 框架,本身不包含数据库抽象层,但可以方便地集成 ORM(对象关系映射)工具,如 SQLAlchemyPeewee,其中最常用的是 Flask-SQLAlchemy,它简化了 SQLAlchemy 在 Flask 项目中的配置和使用,以下逐步介绍如何通过 Flask-SQLAlchemy 连接数据库并进行基本操作。

安装依赖

首先安装 Flask 和 Flask-SQLAlchemy,如果使用 MySQL 或 PostgreSQL,还需安装对应的数据库驱动。

Flask框架如何使用ORM连接数据库,需要注意什么? 第1张

配置数据库连接

在 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 并指定类型和约束。

Flask框架如何使用ORM连接数据库,需要注意什么? 第2张

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 操作

以下示例演示如何添加、查询、更新和删除记录。

Flask框架如何使用ORM连接数据库,需要注意什么? 第3张

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 语句。

0