Flask的ORM工具SQLAlchemy
Flask的ORM工具SQLAlchemy
一、ORM 是什么?
ORM(Object-Relational Mapping,对象关系映射)是一种编程技术,用于在面向对象的编程语言与关系型数据库之间建立映射关系。它允许开发者使用面向对象的语法(如类、对象、方法)操作数据库,而无需直接编写 SQL 语句。
ORM 的核心作用:
- 抽象数据库操作:将数据库表映射为编程语言中的“类”,表中的行映射为“对象”,表的字段映射为“对象属性”。
- 屏蔽数据库差异:同一套 ORM 代码可适配多种数据库(如 MySQL、PostgreSQL、SQLite 等),无需修改核心逻辑。
- 简化开发流程:避免手动编写复杂 SQL,减少出错概率,同时让代码更易读、易维护。
二、Flask 的 ORM 工具:SQLAlchemy 详解
SQLAlchemy 是 Python 生态中最流行的 ORM 框架之一,并非专为 Flask 设计,但通过 Flask-SQLAlchemy扩展可与 Flask 无缝集成,成为 Flask 项目中操作数据库的首选工具。
1、SQLAlchemy 的定位
SQLAlchemy 不仅是 ORM,更是一个“SQL 工具包”,它包含两部分核心功能:
- Core(核心):提供 SQL 表达式语言,可直接通过 Python 代码生成 SQL 语句(类似“高级 SQL 生成器”)。
- ORM:在 Core 基础上封装的对象关系映射层,支持通过类和对象操作数据库。
2、Flask-SQLAlchemy 扩展
Flask-SQLAlchemy 是 Flask 官方推荐的扩展,它简化了 SQLAlchemy 与 Flask 的集成,自动处理配置、会话管理等细节。
(1)安装
pip install flask-sqlalchemy
(2)基本配置与初始化
在 Flask 项目中,需先配置数据库连接信息并初始化 SQLAlchemy:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 配置数据库 URI(以 SQLite 为例,文件型数据库,无需额外服务)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
# 关闭 SQLAlchemy 的修改跟踪功能(优化性能)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 初始化 SQLAlchemy 实例,关联 Flask 应用
db = SQLAlchemy(app)
数据库 URI 格式(不同数据库):
- SQLite:sqlite:///数据库文件名.db(相对路径,文件存于项目根目录)
- MySQL:mysql+pymysql://用户名:密码@主机:端口/数据库名
- PostgreSQL:postgresql://用户名:密码@主机:端口/数据库名
3、核心概念与使用
(1)模型(Model):映射数据库表
模型是 ORM 的核心,对应数据库中的一张表。通过继承 db.Model 定义模型类,类的属性对应表的字段。
示例:定义一个 User 模型(对应 user 表):
class User(db.Model):
#表名(不指定则默认用类名小写,如 User → user)
__tablename__ = 'users'
#字段定义:id(主键,自增整数)
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)
#定义对象的字符串表示(便于调试)
def __repr__(self):
return f'<User {self.username}>'
- db.Column:定义表的字段,第一个参数为数据类型(如 db.Integer、db.String)。
- 常用参数:
- primary_key=True:设为主键。
- unique=True:字段值唯一(如用户名不可重复)。
- nullable=False:字段不可为空(必填)。
- default:设置默认值(如 default=datetime.utcnow)。
(2)创建数据库和表
定义模型后,需通过代码创建实际的数据库文件和表:
#在 Flask 应用上下文内执行(如在视图函数中,或通过 shell)
with app.app_context():
#创建所有模型对应的表(若表已存在则不重复创建)
db.create_all()
执行后,项目根目录会生成 mydatabase.db(SQLite),包含 users 表。
(3)会话(Session):操作数据库的“接口”
SQLAlchemy 通过“会话(Session)”执行数据库操作(增删改查),Flask-SQLAlchemy 中通过 db.session 调用。
会话的作用:暂存所有操作,最终通过 commit() 提交到数据库,类似“事务”。
(4)基本操作示例
① 新增数据(插入)
with app.app_context():
#创建用户对象(对应表中的一行)
user1 = User(username='alice', email='alice@example.com')
user2 = User(username='bob', email='bob@example.com')
#将对象添加到会话
db.session.add(user1)
db.session.add(user2) #可批量添加:db.session.add_all([user1, user2])
#提交会话(实际写入数据库)
db.session.commit()
② 查询数据
Flask-SQLAlchemy 提供了丰富的查询方法,通过 模型类.query 调用:
with app.app_context():
#1. 查询所有用户(返回列表)
all_users = User.query.all()
print(all_users) # [<User alice>, <User bob>]
#2. 查询第一个用户
first_user = User.query.first()
print(first_user.username) #'alice'
#3. 通过主键查询(高效)
user_by_id = User.query.get(1) #查询 id=1 的用户
print(user_by_id.email) # 'alice@example.com'
#4. 条件查询(filter_by,简化版,只支持关键字参数)
user_bob = User.query.filter_by(username='bob').first()
#5. 复杂条件查询(filter,支持表达式)
#例如:查询邮箱包含 'example' 的用户
users_with_example = User.query.filter(User.email.like('%example%')).all()
#6. 排序(按 username 升序)
sorted_users = User.query.order_by(User.username).all()
#7. 限制查询数量(前 10 条)
limited_users = User.query.limit(10).all()
③ 更新数据
with app.app_context():
#1. 先查询到要更新的对象
user = User.query.filter_by(username='alice').first()
#2. 修改属性
user.email = 'new_alice@example.com'
#3. 提交会话(保存修改)
db.session.commit()
④ 删除数据
with app.app_context():
#1. 先查询到要删除的对象
user = User.query.filter_by(username='bob').first()
#2. 从会话中删除
db.session.delete(user)
#3. 提交会话(执行删除)
db.session.commit()
(5)关系(Relationship):处理表之间的关联
实际数据库中表常有关联(如“用户-文章”一对多),SQLAlchemy 通过 db.relationship 定义模型间的关系。
示例:用户(User)和文章(Post)的一对多关系:
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
#外键:关联 users 表的 id 字段
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
#定义与 User 的反向关系(一个用户对应多篇文章)
#backref:在 User 中自动添加 posts 属性,可通过 user.posts 获取该用户的所有文章
author = db.relationship('User', backref=db.backref('posts', lazy=True))
使用示例:
with app.app_context():
#查询用户的所有文章
user = User.query.get(1)
user_posts = user.posts #所有该用户的文章列表
#查询文章的作者
post = Post.query.get(1)
post_author = post.author #文章对应的用户对象
4、数据库迁移:Flask-Migrate
当模型结构变更(如新增字段、修改类型)时,直接删除表重建会丢失数据。Flask-Migrate 扩展基于 Alembic(SQLAlchemy 作者开发的迁移工具),可安全地同步模型变更到数据库。
(1)安装
pip install flask-migrate
(2)初始化
from flask_migrate import Migrate
#关联 app 和 db
migrate = Migrate(app, db)
(3)常用迁移命令
# 初始化迁移环境(仅首次执行)
flask db init
#生成迁移脚本(检测模型与数据库的差异)
flask db migrate -m "描述迁移内容,如:新增用户年龄字段"
#执行迁移(将脚本应用到数据库)
flask db upgrade
三、SQLAlchemy 的优势
- 灵活性:支持 ORM 模式(面向对象)和 Core 模式(直接生成 SQL),可根据需求选择。
- 跨数据库兼容:一套代码适配多种数据库,切换数据库只需修改 URI。
- 强大的查询能力:提供丰富的查询 API,支持复杂条件、联表查询、聚合函数等。
- 事务支持:通过会话的 commit() 和 rollback()(回滚)保证数据一致性。
- 与 Flask 无缝集成:Flask-SQLAlchemy 简化了配置和会话管理,开箱即用。
四、总结
ORM 是连接面向对象编程与关系型数据库的桥梁,而 SQLAlchemy 是 Python 中功能最完善的 ORM 工具之一。通过 Flask-SQLAlchemy 扩展,开发者可以在 Flask 项目中用简洁的面向对象语法操作数据库,大幅提升开发效率,同时保证代码的可维护性和扩展性。
浙公网安备 33010602011771号