EP08 · 讲义

Genesis2000 Python 脚本实战 · 第8集 数据库——业务库与配置库

本集学什么

这集讲数据。学完你能独立写数据库操作:查料号参数、写配置、留日志。 两套体系各讲透:远程业务库怎么封装,本地配置库怎么设计,最后看几个工程细节。

回顾:数据从哪来、到哪去

第 6 集的 ERP 查询,底层走的就是这集要讲的 SqlClasses;第 7 集的界面配置,就存在这集的 db_manager 里。 数据层是前面所有故事的幕后支撑。这集把它请到台前。

两套体系的定位

# 远程业务库 SQL Server / MySQL —— 料号·快板·计划
# 本地配置库 SQLite —— 菜单·主题·设置
第一套是 SqlClasses:连接远程的 SQL Server 和 MySQL,读写业务数据——料号库、快板库、计划库。 第二套是 db_manager:本地的 SQLite 文件,保存界面程序的配置——菜单、主题、用户设置。数据性质不同,技术选型不同,封装也分开。

通用封装:两个核心方法(完整源码)

def exec_query(self, sql):       # 查询 → list[dict] / list[tuple]
  ...执行...
  fetchall()
  close()                     # 用完即关
def exec_non_query(self, sql): # 写入 → "ok" / "no"
  ...执行...
SqlClasses 的核心就两个方法:exec_query 查,exec_non_query 写。查询结果可以选字典列表或元组列表两种模式,构造子类时指定。 写入失败会弹错误框提示,返回 no。业务脚本里百分之九十九的数据库操作,这两个方法就够。

字典生成 SQL

_make_sql(表名, {字段: 值, ...})
  → INSERT INTO 表 (字段...) VALUES (...)
  → None 自动转成 NULL
还有个贴心的功能:传一个字典,自动生成插入语句——键是字段名,值是数据,None 自动转成数据库的 NULL。 手工拼 SQL 是出错重灾区:引号、逗号、空值。这个生成器把这类低级错误消灭在源头。

预置连接子类

每个业务库对应一个子类,连接参数在类里预置好。要用快板库,实例化对应子类就行,不用记服务器地址、账号、库名。 设计取向很明确:通用能力在父类,连接细节在子类。新增一个库,只需加一个几行的子类——典型的模板方法思想。

用完即关的取舍

一个值得讲的取舍:每次数据库操作都新建连接、用完即关,没有连接池。代码里还有注释专门提醒必须关闭。 代价是每次连接的握手开销,好处是简单可靠——脚本场景的数据库操作频率不高,换来不用管理连接生命周期。工程上,够用就好。

MySQL 版本兼容

MySQL 的兼容处理值得一看:不同版本返回游标的行为有差异,代码里先按一种方式取,失败再换另一种。 兼容逻辑藏在封装内部,调用方完全无感。对接外部系统时,这类「先试再换」的写法很实用。

Python2 残留的识别

raise (NameError, "message")   # Python2 元组式异常
老代码里还能看到 Python2 时代的写法:元组形式的异常抛出。这种写法在 Python3 里已经不生效。 认得出这些残留很重要——它们不会报错,只是静默失效。读老代码时看到陌生语法,先怀疑是不是历史包袱。

db_manager:SQLite 配置库

再看本地配置库 db_manager。模块开头就写着设计理由:替代 JSON 文件,提供事务保护、并发安全、内置版本。 过去界面配置散落在多个 JSON 文件里,读写出错难查;换成 SQLite,一个文件、事务保证、结构清晰。

表结构与变更留痕

表结构七张:界面设置、菜单配置、流程列表、管理员、主题模板、系统信息,外加一张变更日志。 变更日志是亮点——每次配置改动自动记一笔。配置被谁改过、改成什么,出了问题可以回溯。

WAL 与事务(完整代码)

PRAGMA journal_mode=WAL     # 读写并发安全
with conn:                    # 事务块:要么全成,要么全不
  ...写入 + 记日志
两个可靠性细节。第一,启用 WAL 模式:SQLite 的预写日志,让读写可以并发,多进程访问不冲突。 第二,写入包在事务块里:一条配置的写入和它的日志记录要么一起成功,要么一起回滚——不会出现「改了配置但没记录」的中间状态。

一次性迁移

从 JSON 换到 SQLite,老数据怎么办?代码里写了迁移函数:启动时把旧的 JSON 文件批量导入新库,主题、菜单、系统配置都覆盖。 迁移函数带防重复标记,只执行一次。老版本升级到新版本,数据平滑过渡——这种「一次性迁移」模式很值得学。

使用案例巡览

sql.exec_query("SELECT ... FROM 料号表")   # 查业务库
sql.exec_non_query("UPDATE ...")         # 写业务库
dbm.set_ui_settings(key, value)             # 写本地配置
最后看真实用法。查业务库、写业务库,各一行;写本地配置,也是一行——前面六集见过的所有数据操作,都汇聚在这几行里。 下一集看外围模块:自动化任务的触角——企微推送、涨缩系数接口、文件传输、邮件通知。

小结与预告

这一集我们看到:数据层分了两套——业务数据走远程库,配置数据走本地库,各自有各自的封装与取舍。 下一集看外围部队:企业微信推送、涨缩系数接口、文件传输、邮件通知——自动化任务的触角是怎么伸出去的。
零壹AI工作室出品 · 《用 Python 驱动 Genesis2000》免费公开课 · www.binwindai.com