Flask-SQLAlchemy全面指南从模型定义到高级查询

106 阅读2分钟

Flask-SQLAlchemy全面指南从模型定义到高级查询

Flask-SQLAlchemy全面指南从模型定义到高级查询

1.1 为什么选择ORM?

传统SQL操作存在以下痛点: • SQL注入风险 • 不同数据库语法差异 • 重复编写CRUD代码 • 对象与关系数据转换繁琐 Flask-SQLAlchemy优势: ```

Flask-SQLAlchemy全面指南从模型定义到高级查询

cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

Flask-SQLAlchemy全面指南从模型定义到高级查询

user = User.query.get(user_id)

 ### 1.2 安装与配置
 安装命令: ```
pip install flask-sqlalchemy pymysql

基础配置示例: ``` from flask import Flask from flask_sqlalchemy import SQLAlchemy

app = Flask(name) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://user:password@localhost/dbname' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app)

 配置参数说明: • `SQLALCHEMY_POOL_SIZE` : 连接池默认大小(推荐5-10) • `SQLALCHEMY_ECHO` : 开启SQL日志(调试模式) • `SQLALCHEMY_ENGINE_OPTIONS` : 高级引擎配置 ## 二、数据模型定义
 ### 2.1 学生模型示例

class Student(db.Model): """学生信息表""" tablename = 'tb_student'

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), nullable=False)
sex = db.Column(db.Boolean, default=True, comment='性别')
age = db.Column(db.SmallInteger, index=True)
class_name = db.Column('class', db.String(10))
description = db.Column(db.Text)
status = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.now)

def __repr__(self):
    return f'<Student {self.name}>'
 字段类型对照表: ORM类型 MySQL类型 说明 Integer INT 32位整数 String(20) VARCHAR(20) 可变长度字符串 Text TEXT 长文本数据 Boolean TINYINT(1) 布尔值存储 DateTime DATETIME 日期时间类型 ## 三、CRUD操作详解
 ### 3.1 创建数据

Flask-SQLAlchemy全面指南从模型定义到高级查询

new_student = Student(name='王小明', class_name='301', age=16) db.session.add(new_student) db.session.commit()

Flask-SQLAlchemy全面指南从模型定义到高级查询

students = [ Student(name='张小红', class_name='302', age=17), Student(name='李小白', class_name='303', age=16) ] db.session.bulk_save_objects(students) db.session.commit()

 ### 3.2 查询操作
 基础查询方法: ```
# Flask-SQLAlchemy全面指南从模型定义到高级查询
all_students = Student.query.all()

# Flask-SQLAlchemy全面指南从模型定义到高级查询
first_student = Student.query.first()

# Flask-SQLAlchemy全面指南从模型定义到高级查询
student = Student.query.get(1)

复杂条件查询: ``` from sqlalchemy import and_, or_

Flask-SQLAlchemy全面指南从模型定义到高级查询

result = Student.query.filter( or_( and_(Student.class_name == '301', Student.age >= 15), and_(Student.class_name == '302', Student.age < 18) ) ).order_by(Student.created_at.desc()).limit(10).all()

 ### 3.3 更新数据

student = Student.query.get(1) student.age = 17 db.session.commit()

Flask-SQLAlchemy全面指南从模型定义到高级查询

Student.query.filter_by(class_name='301').update({'age': Student.age + 1}) db.session.commit()

 ### 3.4 删除数据

student = Student.query.get(1) db.session.delete(student) db.session.commit()

 ## 四、高级查询技巧
 ### 4.1 分页查询

def paginate(page=1, per_page=20): return Student.query.order_by(Student.id).paginate( page=page, per_page=per_page, error_out=False )

 ### 4.2 聚合查询

from sqlalchemy import func

Flask-SQLAlchemy全面指南从模型定义到高级查询

class_stats = db.session.query( Student.class_name, func.count(Student.id).label('total') ).group_by(Student.class_name).all()

 ### 4.3 关联查询

class Score(db.Model): student_id = db.Column(db.Integer, db.ForeignKey('tb_student.id')) # 定义关系 student = db.relationship('Student', backref='scores')

Flask-SQLAlchemy全面指南从模型定义到高级查询

student_with_scores = db.session.query(Student, Score).join( Score, Student.id == Score.student_id ).filter(Student.class_name == '301').all()

 ## 五、原生SQL操作
 ### 5.1 执行原生查询

Flask-SQLAlchemy全面指南从模型定义到高级查询

sql = "SELECT * FROM tb_student WHERE class = :class_name" result = db.session.execute(sql, {'class_name': '301'}) students = [dict(row) for row in result]

 ### 5.2 执行数据修改

update_sql = """ UPDATE tb_student SET age = age + 1 WHERE created_at < :threshold """ db.session.execute(update_sql, {'threshold': datetime(2023, 1, 1)}) db.session.commit()

 ## 六、最佳实践
 ### 6.1 性能优化
 • 使用 `yield_per` 处理大数据集: ```
for student in Student.query.yield_per(100):
    process(student)

• 避免N+1查询问题: ```

Flask-SQLAlchemy全面指南从模型定义到高级查询

from sqlalchemy.orm import joinedload students = Student.query.options(joinedload(Student.scores)).all()

 ### 6.2 安全建议
 1. 始终使用参数化查询
2. 敏感字段加密存储
3. 定期备份数据库
4. 使用只读账号进行查询操作
 ### 6.3 错误处理

try: db.session.begin() # 数据库操作... db.session.commit() except Exception as e: db.session.rollback() current_app.logger.error(f"Database error: {str(e)}") raise

 ## 七、扩展学习
 1. 数据库迁移工具 : ```
pip install flask-migrate

初始化: ``` from flask_migrate import Migrate migrate = Migrate(app, db)


2. 查询性能分析 : ```
from sqlalchemy import event
from sqlalchemy.engine import Engine

@event.listens_for(Engine, "before_cursor_execute")
def before_cursor_execute(conn, cursor, stmt, params, context, executemany):
    context._query_start_time = time.time()

@event.listens_for(Engine, "after_cursor_execute")
def after_cursor_execute(conn, cursor, stmt, params, context, executemany):
    duration = time.time() - context._query_start_time
    if duration > 0.5:  # 记录慢查询
        app.logger.warning(f"Slow query ({duration:.2f}s): {stmt}")
  1. 异步支持 (SQLAlchemy 2.0+): ``` from sqlalchemy.ext.asyncio import create_async_engine async_engine = create_async_engine("mysql+asyncmy://user:pass@host/db")

 通过本文的学习,您将掌握: • Flask-SQLAlchemy的核心使用方法 • 复杂业务场景下的查询构建技巧 • 数据库操作的最佳实践 • 性能优化与安全防护策略 建议在实际项目中结合具体需求,灵活运用这些技术,并持续关注SQLAlchemy的版本更新和新特性。

> 原文链接: https://www.cnblogs.com/qm666/articles/18793879