Flask与MySQL数据库连接实战:从配置到CRUD操作
1. Flask与MySQL数据库连接实战指南作为Python轻量级Web框架的佼佼者Flask在数据库操作方面提供了极大的灵活性。不同于直接使用pymysql等驱动编写原生SQL采用ORM对象关系映射技术能让我们的代码更加Pythonic也更容易维护。本文将手把手带你实现Flask与MySQL的完整对接流程从环境配置到CRUD操作全覆盖。我最近在开发一个用户管理系统时就采用了Flask-SQLAlchemy这套方案。实际体验下来ORM不仅减少了约60%的数据库相关代码量还完美解决了SQL注入风险。特别是在团队协作时统一的ORM接口让代码可读性大幅提升。2. 环境准备与数据库配置2.1 安装必要依赖在开始前确保已安装Python 3.6和MySQL 5.7。然后通过pip安装核心包pip install flask flask-sqlalchemy pymysql这里有个容易踩的坑如果只安装flask-sqlalchemy而不显式安装pymysql在某些环境下会出现驱动找不到的错误。我建议总是明确指定这两个依赖。2.2 创建MySQL数据库登录MySQL控制台执行CREATE DATABASE flask_demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;选择utf8mb4字符集非常重要它能完整支持emoji和所有Unicode字符。曾经有个项目就因为用了utf8导致用户昵称中的特殊符号变成问号不得不做数据迁移。3. Flask应用配置3.1 基础连接配置新建app.py文件配置数据库连接from flask import Flask from flask_sqlalchemy import SQLAlchemy app Flask(__name__) # 配置数据库URI app.config[SQLALCHEMY_DATABASE_URI] mysqlpymysql://root:123456localhost:3306/flask_demo?charsetutf8mb4 app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False # 关闭警告信息 db SQLAlchemy(app)重要提示生产环境务必不要将密码硬编码在代码中应该使用环境变量或配置中心管理敏感信息。3.2 连接测试添加以下代码验证连接是否成功app.route(/health) def health_check(): try: db.session.execute(SELECT 1) return Database connection OK except Exception as e: return fConnection failed: {str(e)}, 500启动应用后访问/health端点看到Database connection OK即表示配置正确。4. 模型定义与表操作4.1 创建用户模型class User(db.Model): __tablename__ users id db.Column(db.Integer, primary_keyTrue) username db.Column(db.String(80), uniqueTrue, nullableFalse) password db.Column(db.String(120), nullableFalse) created_at db.Column(db.DateTime, server_defaultdb.func.now()) def __repr__(self): return fUser {self.username}模型设计要点显式指定__tablename__避免表名猜测添加created_at字段记录创建时间为username添加unique约束防止重复实现__repr__方便调试4.2 初始化数据库表在Flask shell中执行from app import db db.create_all()或者添加CLI命令app.cli.command() def initdb(): Initialize the database. db.create_all() print(Initialized the database.)之后通过flask initdb命令即可初始化表结构。5. CRUD操作实战5.1 创建用户from datetime import datetime new_user User( usernamejohn_doe, passwordsecure_password, # 实际项目应该存储hash值 created_atdatetime.utcnow() ) db.session.add(new_user) db.session.commit()安全提醒实际项目中密码必须使用bcrypt等库进行哈希处理绝对不要明文存储5.2 查询操作基本查询# 获取所有用户 users User.query.all() # 按条件查询 user User.query.filter_by(usernamejohn_doe).first() # 复杂查询 from sqlalchemy import or_ admins User.query.filter( or_( User.username.like(%admin%), User.id.in_([1, 2, 3]) ) ).order_by(User.created_at.desc()).limit(10).all()5.3 更新操作user User.query.get(1) # 获取ID为1的用户 if user: user.password new_hashed_password db.session.commit()批量更新User.query.filter(User.id 10).update({password: updated}) db.session.commit()5.4 删除操作user User.query.get(1) if user: db.session.delete(user) db.session.commit()6. 高级技巧与性能优化6.1 连接池配置app.config[SQLALCHEMY_ENGINE_OPTIONS] { pool_size: 10, max_overflow: 20, pool_timeout: 30, pool_recycle: 3600 }合理配置连接池可以显著提升高并发下的性能。根据我的经验pool_size设为CPU核心数的2-3倍是个不错的起点。6.2 事务管理try: # 操作1 user1 User(usernameuser1) db.session.add(user1) # 操作2 user2 User(usernameuser2) db.session.add(user2) db.session.commit() except Exception as e: db.session.rollback() print(fTransaction failed: {e})6.3 性能监控添加以下配置记录慢查询app.config[SQLALCHEMY_RECORD_QUERIES] True from flask_sqlalchemy import get_debug_queries app.after_request def after_request(response): for query in get_debug_queries(): if query.duration 0.5: # 超过500ms的查询 print(fSLOW QUERY: {query.statement} {query.parameters} {query.duration}) return response7. 常见问题排查7.1 连接超时问题症状间歇性出现MySQL server has gone away错误。解决方案检查MySQL的wait_timeout设置默认8小时配置pool_recycle小于wait_timeout实现连接健康检查7.2 编码问题确保所有环节统一使用utf8mb4数据库创建时指定连接字符串添加charset参数Python文件头部添加编码声明7.3 会话管理常见错误在请求结束后尝试使用数据库会话。正确做法app.teardown_appcontext def shutdown_session(exceptionNone): db.session.remove()8. 安全最佳实践使用参数化查询防止SQL注入ORM已自动处理密码必须加盐哈希存储推荐使用Flask-Bcrypt生产环境禁用DEBUG模式定期备份数据库为数据库用户分配最小必要权限我在实际项目中总结出一个有用的技巧为每个模型添加通用的审计字段class BaseModel(db.Model): __abstract__ True created_at db.Column(db.DateTime, server_defaultdb.func.now()) updated_at db.Column(db.DateTime, onupdatedb.func.now()) is_deleted db.Column(db.Boolean, defaultFalse) class User(BaseModel): # 其他字段...这种设计便于实现软删除和操作追踪。