文章目录
一、为什么你的Flask需要数据库?
各位铁子们(敲黑板),咱们做Web应用要是没有数据库,就像吃火锅没有蘸料——总感觉缺点灵魂啊!Flask自带的开发服务器虽然能用内存临时存点数据,但一重启就全没了(别问我怎么知道的)!
现在主流的方案是用ORM(对象关系映射)工具来操作数据库,简单说就是让咱们用Python代码就能操作数据库,不用手写SQL语句(当然复杂的查询还是需要的)。这里推荐使用Flask-SQLAlchemy
这个扩展包,它简直就是Python和MySQL之间的金牌翻译官!
二、安装必备工具包
先打开你的命令行(Windows用户按Win+R输入cmd,Mac用户直接找终端),输入这两个救命指令:
pip install flask-sqlalchemy
pip install mysqlclient
等等!Windows用户是不是看到安装mysqlclient报错了?(别慌)这是经典坑位!试试这个方法:
- 访问https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
- 下载对应你Python版本的whl文件(比如
MySQLclient‑1.4.6‑cp39‑cp39‑win_amd64.whl
) - 执行
pip install 你下载的文件路径
三、配置数据库连接(超级重要)
在你的Flask应用初始化部分,加入这些配置:
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://用户名:密码@localhost/数据库名'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 这个不关会有警告!
db = SQLAlchemy(app)
注意这三个天坑(血泪教训):
- 确保MySQL服务已经启动(命令行输入
mysql -u root -p
能登录) - 提前用MySQL客户端创建好数据库(
CREATE DATABASE 数据库名;
) - 如果连接远程数据库,要把localhost改成IP地址,还要检查防火墙设置
四、创建数据模型(ORM的核心)
咱们来创建一个用户模型试试:
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)
def __repr__(self):
return '<User %r>' % self.username
这里解释几个关键参数:
String(80)
表示最大长度80字符(MySQL会自动转成varchar)unique=True
是唯一约束(注册时防重复)nullable=False
表示不能为空(必填项)
五、数据库迁移的神操作
在命令行依次执行:
from yourapp import db
db.create_all()
但这样手动迁移太low了!推荐使用Flask-Migrate扩展:
pip install flask-migrate
然后在代码中初始化:
from flask_migrate import Migrate
migrate = Migrate(app, db)
以后修改模型后,只需三步:
flask db init # 第一次初始化
flask db migrate -m "注释说明"
flask db upgrade
六、CRUD操作实战(增删改查)
1. 增加数据
new_user = User(username='老王', email='laowang@example.com')
db.session.add(new_user)
db.session.commit() # 这个不写数据不会入库!
2. 查询数据
# 查全部
users = User.query.all()
# 条件查询
user = User.query.filter_by(username='老王').first()
# 复杂查询
from sqlalchemy import or_
result = User.query.filter(or_(User.email.like('%example%'),
User.username.startswith('王'))).limit(5).all()
3. 更新数据
user = User.query.get(1)
user.email = 'new_email@example.com'
db.session.commit()
4. 删除数据
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
七、性能优化小技巧
- 批量插入用
bulk_save_objects
:
db.session.bulk_save_objects([
User(username='user1'),
User(username='user2'),
User(username='user3')
])
db.session.commit()
- 开启连接池(在配置中添加):
app.config['SQLALCHEMY_POOL_SIZE'] = 20
app.config['SQLALCHEMY_POOL_RECYCLE'] = 300 # 5分钟回收连接
- 生产环境一定要用数据库索引:
class Post(db.Model):
# 在经常查询的字段加索引
title = db.Column(db.String(100), index=True)
八、常见报错解决方案
1. 1045 Access Denied
检查:用户名/密码是否正确,用户是否有远程访问权限(用MySQL命令行验证)
2. 2003 Can’t connect to MySQL server
检查:MySQL服务是否启动,防火墙是否开放3306端口
3. 1366 Incorrect string value
解决方法:在连接URI后添加?charset=utf8mb4
,确保数据库字符集是utf8mb4
4. 1054 Unknown column
说明模型和数据库表结构不一致,执行flask db migrate
和upgrade
九、终极防坑指南
- 永远不要在代码里明文存储密码!应该用环境变量:
import os
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
-
开发环境和生产环境要分开配置(可以用
.env
文件) -
定期备份数据库!可以用这个命令:
mysqldump -u 用户名 -p 数据库名 > backup.sql
- 复杂查询一定要用EXPLAIN分析执行计划
最后说个冷知识:SQLAlchemy的session对象是线程局部的,所以在多线程环境下也不用担心数据混乱的问题。但切记不要在多线程中共享模型实例哦!
(看到这里你已经是Flask+MySQL高手了,赶紧去写个博客系统练手吧!)