生产脚本不像门童,见人就点头;它更像地铁闸机,票错一毫米,也该当场夹住你。我把话说死:到了 sqlite-utils 4.0rc3,我觉得,只有会当场报错的 sqlite-utils,才配写生产脚本。

很多人把“好工具”理解反了,以为它该圆滑、体贴、会猜、会兜底,最好脚本一路绿灯,控制台安静得像深夜图书馆。那是给演示台挑玩具,不是给生产环境挑器械。生产脚本碰的不是自尊心,是订单、账目、外键、迁移。这里最可怕的,从来不是一声报错,而是它没报错,甚至还摆出一副“已经办妥”的笑脸。

工具一旦学会替人圆场,人就得替工具背锅。

翻一眼 sqlite-utils 的更新记录 就知道,4.0rc2 和 4.0rc3 这两个候选版最可贵的地方,不是会更多,而是装得更少。该立刻执行的,立刻执行;该立刻提交的,立刻提交;该拦住的,直接拦住;该保住的约束,一条都别偷走。它开始像闸机,不再像门童。

周一早上 8 点 43 分,运营把一份 CSV(逗号分隔表格文件)修单表丢进脚本,二千行里混了一行没有订单主键。以前那种“体贴”的做法,是把这行当成新单悄悄塞进去。下午财务对账,营业额凭空长出一截,所有人都以为是业务爆了,最后发现只是工具太会做人。4.0rc2 把这种假好心收了回去:主键缺了,当场报错。脚本没给你面子,数据才保住了脸。

生产环境最阴险的不是异常,是异常被伪装成成功。

凌晨 1 点 17 分,值班工程师跑一段修复 SQL(数据库语句)。db.execute()(直接执行 SQL 的接口)做完以后,他顺手又查了同一个连接,数据看起来已经改了,于是回了句“已处理”,合上电脑睡觉。第二天早上,连接一关,昨夜那点“成功”像雾一样散掉,原来写入根本没真正落地,只是在本地照了照镜子。4.0rc2 这回说得很直白:写就是写,默认就提交;你要回滚,就明确开事务。生产脚本最烦的不是严格,是暧昧。

脚本里的客气,往往是事故里的粗暴。

周五傍晚 6 点 58 分,小郑改表结构,要把 Name 改成 title。SQLite 自己对列名大小写并不刻薄,可工具如果在自己那层悄悄装聋,日志就会是绿的,库却还是旧的,夜里跑批才替你发现 title 根本没生效。4.0rc3 把这一类含糊账清了:列名按实际表结构做不区分大小写的匹配,不再让“你以为改了”和“库里其实没改”同时成立。会报错的工具,不一定温柔;不会装懂的工具,才算诚实。

还有一种沉默更毒。内容库本来写着 ON DELETE CASCADE(删主记录时连带删掉子记录),你做一次 table.transform()(重建表的变更操作),旧行为却可能把这条约束悄悄磨没。眼前一切正常,两周后删掉一个作者,文章却没跟着走,搜索索引、推荐缓存、统计报表里到处都是孤儿记录。4.0rc3 把这类外键动作老老实实保了下来。真正的稳定,不是表面没声音,是规则没失忆。

真正折磨人的,从来不是报错;是公司把机器该承担的确定性,偷偷外包给人去猜。白天叫“协作”,夜里叫“值班”。工具少发一条错误,群里就多十条消息;控制台省下一次翻脸,会议室里就多一轮追责。现代办公室最擅长的一种魔术,就是把系统的含糊包装成组织的成熟,把机器的不负责,改名叫人的经验。

所以我喜欢 sqlite-utils 4.0rc3,不是因为它更聪明,而是因为它没那么会装聪明。它开始承认一件朴素得近乎粗鲁的事实:生产环境不是社交场,不奖励圆滑,奖励可证实;不奖励“差不多”,奖励“你现在就给我停下”。

会尖叫的工具,救的是数据;只会陪笑的工具,害的是人。

我宁可让脚本在终端里当场翻脸,也不愿它在数据库里事后留尸体。


别人聊 AI,我们测 AI——每个结论都能下载原始数据自己复算。 🔗 官网 👉 https://crawdpad.com