news 2026/7/3 5:20:37

Flask与MySQL数据库连接实战:从配置到CRUD操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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'] = 'mysql+pymysql://root:123456@localhost:3306/flask_demo?charset=utf8mb4' 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 f'Connection failed: {str(e)}', 500

启动应用后访问/health端点,看到"Database connection OK"即表示配置正确。

4. 模型定义与表操作

4.1 创建用户模型

class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password = db.Column(db.String(120), nullable=False) created_at = db.Column(db.DateTime, server_default=db.func.now()) def __repr__(self): return f'<User {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( username='john_doe', password='secure_password', # 实际项目应该存储hash值 created_at=datetime.utcnow() ) db.session.add(new_user) db.session.commit()

安全提醒:实际项目中密码必须使用bcrypt等库进行哈希处理,绝对不要明文存储!

5.2 查询操作

基本查询:

# 获取所有用户 users = User.query.all() # 按条件查询 user = User.query.filter_by(username='john_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(username='user1') db.session.add(user1) # 操作2 user2 = User(username='user2') db.session.add(user2) db.session.commit() except Exception as e: db.session.rollback() print(f"Transaction 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(f'SLOW QUERY: {query.statement} {query.parameters} {query.duration}') return response

7. 常见问题排查

7.1 连接超时问题

症状:间歇性出现"MySQL server has gone away"错误。

解决方案:

  1. 检查MySQL的wait_timeout设置(默认8小时)
  2. 配置pool_recycle小于wait_timeout
  3. 实现连接健康检查

7.2 编码问题

确保所有环节统一使用utf8mb4:

  1. 数据库创建时指定
  2. 连接字符串添加charset参数
  3. Python文件头部添加编码声明

7.3 会话管理

常见错误:在请求结束后尝试使用数据库会话。

正确做法:

@app.teardown_appcontext def shutdown_session(exception=None): db.session.remove()

8. 安全最佳实践

  1. 使用参数化查询防止SQL注入(ORM已自动处理)
  2. 密码必须加盐哈希存储(推荐使用Flask-Bcrypt)
  3. 生产环境禁用DEBUG模式
  4. 定期备份数据库
  5. 为数据库用户分配最小必要权限

我在实际项目中总结出一个有用的技巧:为每个模型添加通用的审计字段:

class BaseModel(db.Model): __abstract__ = True created_at = db.Column(db.DateTime, server_default=db.func.now()) updated_at = db.Column(db.DateTime, onupdate=db.func.now()) is_deleted = db.Column(db.Boolean, default=False) class User(BaseModel): # 其他字段...

这种设计便于实现软删除和操作追踪。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/3 5:20:04

处理医疗废水要安装在线监测设备吗?

我国一些场所早已要求一些排放重点水污染物处理区安装水质在线监测设备&#xff0c;其中处于环境敏感的地区以及是市或地级以上环境保护行政部门列为重点污染源的排放单位&#xff0c;这些都是必须要安装水质监测设备的。那么处理医疗废水要安装在线监测设备吗&#xff1f;答案…

作者头像 李华
网站建设 2026/7/3 5:18:42

Triton Puzzles(Demo1-4)

Triton Puzzles 之前做tilelang puzzles的时候&#xff0c;发现readme里提到是仿照triton puzzles的&#xff0c;但当时感觉triton没有学的必要&#xff0c;就没做 最近发现triton的设计思想和tilelang差异很大&#xff0c;感觉可以开拓一下视野&#xff0c;就找到这个https://…

作者头像 李华
网站建设 2026/7/3 5:18:04

OpenAI Residency:顶尖AI工程师的实战破壁实验室

1. 项目概述&#xff1a;这不是“AI夏令营”&#xff0c;而是一场高强度、高门槛的实战淬炼“Top AI Adventure: OpenAI Residency”——光看标题&#xff0c;很多人第一反应是“哦&#xff0c;OpenAI办的AI训练营”或者“类似谷歌AI residency那种实习项目”。但实话讲&#x…

作者头像 李华
网站建设 2026/7/3 5:15:07

软件审计风暴下,企业如何用自动化工具守住合规底线?

近年来&#xff0c;软件供应商的审计力度正在以前所未有的速度收紧。数据显示&#xff0c;过去三年中多达73%的企业遭遇过Oracle发起的Java合规性审计。而审计一旦启动&#xff0c;代价往往超出预期——超过四分之一的受访企业每年在解决非合规许可问题上的花费超过50万美元&am…

作者头像 李华
网站建设 2026/7/3 5:11:51

ArgoCD从内网的GitLab Repo部署应用

K8s Cluster 我有一个3节点的k8s集群&#xff1a; 一个maste&#xff0c;2个node ❯ kubectl cluster-info Kubernetes control plane is running at https://192.168.1.101:6443 CoreDNS is running at https://192.168.1.101:6443/api/v1/namespaces/kube-system/services/…

作者头像 李华
网站建设 2026/7/3 5:11:12

信创深水区,企业即时通讯如何走出替代陷阱

信创深水区&#xff0c;企业即时通讯如何走出“替代陷阱” 当信创从党政机关向金融、能源、电信等八大行业全面铺开&#xff0c;企业即时通讯&#xff08;IM&#xff09;的选型逻辑正在被彻底改写。过去&#xff0c;许多组织将“替换微信/钉钉”等同于完成国产化任务&#xff0…

作者头像 李华