【AI总结】在 Peewee 中基于 MySQL 实现“动态表名”——从连接到查询的完整实战
文章目录
- 在 Peewee 中基于 MySQL 实现“动态表名”——从连接到查询的完整实战
- 一、前言
- 二、环境准备
- 1. 安装依赖
- 2. 创建数据库(以 MySQL 为例)
- 三、连接 MySQL 并封装基础模型
- 四、核心:动态模型工厂函数
- 五、使用示例:动态建表 + 增删查改
- 六、优化建议:缓存模型类避免重复创建
- 七、总结
在 Peewee 中基于 MySQL 实现“动态表名”——从连接到查询的完整实战
标签:Python、ORM、Peewee、MySQL、动态表名、分表、实战
一、前言
在使用 Peewee 操作 MySQL 时,有时我们会遇到这样的需求:
- 数据量太大,需要按年份、月份、用户 ID 等进行分表;
- 表名在运行时才确定,无法提前写死在模型类中;
- 但又想继续使用 Peewee 的 ORM 接口进行增删查改。
问题来了:Peewee 的 Meta.table_name
是类级属性,运行时无法修改。
解决方案:动态创建模型类,每个表名对应一个新类,完全复用 Peewee 的 ORM 能力。
二、环境准备
1. 安装依赖
pip install peewee pymysql
2. 创建数据库(以 MySQL 为例)
CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARSET utf8mb4;
三、连接 MySQL 并封装基础模型
import pymysql
from peewee import *# 让 pymysql 兼容 MySQLdb
pymysql.install_as_MSQLdb()# 创建数据库连接
db = MySQLDatabase('demo',user='root',password='123456',host='127.0.0.1',port=3306,charset='utf8mb4'
)# 公共基类,统一绑定数据库
class BaseModel(Model):class Meta:database = db
四、核心:动态模型工厂函数
def create_dynamic_model(table_name: str) -> type:"""根据表名动态创建 Peewee 模型类"""# 动态创建 Meta 类Meta = type('Meta', (), {'table_name': table_name})# 模型字段定义attrs = {'id': AutoField(primary_key=True),'source_id': IntegerField(null=True),'index_name_one': CharField(max_length=255, null=True),'index_name_two': CharField(max_length=255, null=True),'Meta': Meta,'__module__': __name__,}# 动态类名,方便调试class_name = f'IndexRecordPairs_{table_name}'return type(class_name, (BaseModel,), attrs)
五、使用示例:动态建表 + 增删查改
# 假设我们按年份分表
table_2023 = create_dynamic_model('index_record_pairs_2023')
table_2024 = create_dynamic_model('index_record_pairs_2024')# 自动建表(仅不存在时创建)
db.create_tables([table_2023, table_2024])# 插入数据
table_2023.create(source_id=1001,index_name_one='GDP',index_name_two='地区生产总值'
)# 查询数据
for row in table_2023.select():print(row.id, row.index_name_one, row.index_name_two)# 更新数据
table_2023.update(index_name_two='全省GDP').where(table_2023.source_id == 1001).execute()# 删除数据
table_2023.delete().where(table_2023.source_id == 1001).execute()
六、优化建议:缓存模型类避免重复创建
_MODEL_CACHE = {}def get_dynamic_model(table_name: str) -> type:if table_name not in _MODEL_CACHE:_MODEL_CACHE[table_name] = create_dynamic_model(table_name)return _MODEL_CACHE[table_name]
七、总结
功能 | 是否支持 |
---|---|
动态表名 | ✅ 通过动态创建模型类 |
ORM 接口 | ✅ 完全保留 |
自动建表 | ✅ db.create_tables() |
事务支持 | ✅ 复用 Peewee 事务 |
性能影响 | ✅ 极小,模型类可缓存 |
结论:
Peewee 虽然不支持“运行时改表名”,但借助 Python 的 type()
动态创建类,我们可以轻松实现 MySQL 动态表名 的需求,且代码简洁、可维护性强,非常适合分表、日志、审计等场景。
如需进一步扩展,可以结合:
- 分表策略(按年月、哈希、用户 ID);
- 自动迁移工具(如
pt-online-schema-change
); - 连接池(
playhouse.pool
)提升并发性能。
希望这篇博客能帮你在实际项目中灵活运用 Peewee!