news 2026/7/11 19:23:50

从 PHP 到 AI + Golang,程序员自救转型手记(三十一):增加 config 模型、数据表自动迁移优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从 PHP 到 AI + Golang,程序员自救转型手记(三十一):增加 config 模型、数据表自动迁移优化

这是一个系列 Blog,作者将以一个 PHP 全栈工程师的身份,利用 AI 工具(claude code、codex、deepseek、豆包等):从零开始学习 golang 语言,并最终完成 ai-go-admin(github | gitee)开源项目的制作,全程记录分享。

在上一期,我们进行了 “实现管理员注销接口、API 请求函数命名规范”,本期将完成:增加 config 模型、数据表自动迁移优化

增加 config 模型

得先把config模型加进来,因为站点的名称、备案号这些站点基础配置是存储在里边的,未来后台的【系统配置】功能也主要就是管理这个表中的数据。

作者之前的项目已经设计过完善的config数据表,这里直接将建表 SQL 给它复制过来,让 CC 转换为 GORM 模型:

新建config数据模型,基于以下SQL的表结构:

CREATETABLE`config`(`id`intUNSIGNEDNOTNULLAUTO_INCREMENTCOMMENT'ID',`name`varchar(30)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'变量名',`group`varchar(30)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'分组',`title`varchar(50)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'变量标题',`tip`varchar(100)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'变量描述',`type`varchar(30)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'变量输入组件类型',`value`longtextCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNULLCOMMENT'变量值',`content`longtextCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNULLCOMMENT'字典数据',`rule`varchar(100)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'验证规则',`extend`varchar(255)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'扩展属性',`input_extend`varchar(255)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT''COMMENT'输入框扩展属性',`allow_del`tinyintUNSIGNEDNOTNULLDEFAULT0COMMENT'允许删除:0=否,1=是',`weigh`intNOTNULLDEFAULT0COMMENT'权重',PRIMARYKEY(`id`)USINGBTREE,UNIQUEINDEX`name`(`name`ASC)USINGBTREE)ENGINE=InnoDBAUTO_INCREMENT=1CHARACTERSET=utf8mb4COLLATE=utf8mb4_unicode_ciCOMMENT='系统配置'ROW_FORMAT=DYNAMIC;

AI 生成的模型如下:

funcinit(){Register(&Config{})}// Config 系统配置模型typeConfigstruct{IDuint`gorm:"comment:ID;primarykey;autoIncrement" json:"id"`Namestring`gorm:"comment:变量名;type:varchar(50);uniqueIndex;not null;default:''" json:"name"`Groupstring`gorm:"comment:分组;type:varchar(50);not null;default:''" json:"group"`Titlestring`gorm:"comment:变量标题;type:varchar(50);not null;default:''" json:"title"`Tipstring`gorm:"comment:变量描述;type:varchar(100);not null;default:''" json:"tip"`Typestring`gorm:"comment:变量输入组件类型;type:varchar(50);not null;default:''" json:"type"`Valuestring`gorm:"comment:变量值;type:longtext" json:"value"`Contentstring`gorm:"comment:字典数据;type:longtext" json:"content"`Rulestring`gorm:"comment:验证规则;type:varchar(100);not null;default:''" json:"rule"`Extendstring`gorm:"comment:扩展属性;type:varchar(255);not null;default:''" json:"extend"`InputExtendstring`gorm:"comment:输入框扩展属性;type:varchar(255);not null;default:''" json:"input_extend"`AllowDeluint8`gorm:"comment:允许删除:0=否,1=是;not null;default:0" json:"allow_del"`Weighint`gorm:"comment:权重;not null;default:0" json:"weigh"`}

这时候发现了一个问题,config表内是有初始数据的,而且 GORM 的自动迁移终究不是长久之计,只适用于开发环境(不支持删除字段、不支持字段改名、字段类型变更风险、无版本记录等)。

所以,此时我就得将 GORM 的自动迁移改为更加适合生产环境的,然后再向config表插入数据。

数据表自动迁移优化

我们需要一个更加适合生产环境的数据表迁移工具,最起码得有版本控制,看了很多工具:

工具star数备注
https://github.com/golang-migrate/migrate18.7k纯 SQL 驱动的迁移工具,不支持通过模型生成 SQL,生态第一
https://github.com/ariga/atlas8.5k新兴的迁移工具,支持通过模型生成 SQL,支持的语言和框架很多,感觉杂而不精
https://github.com/go-gormigrate/gormigrate1.2kstar 太少了

其他看过的就不一一列出了,感觉golang-migrate/migrate挺好的,一个是官方背书,二是用户多,原生 SQL 驱动也方便 DBA 审核 SQL,至于不支持通过模型生成 SQL,AI 时代不是问题。接下来做规划如下:

  1. 使用https://github.com/golang-migrate/migrate实现生产级数据库迁移功能
  2. 项目需要同时支持golang-migrate/migrateCLI模式和模式,库模式于cmd/migrate/main.go建立自定义命令来执行:迁移、回滚、查看状态、创建新的迁移文件
  3. cmd/migrate/migrations建立迁移文件,请参考现有模型写好SQL

同时支持 CLI 模式和库模式的意思是:

# 即可以这样执行迁移migrate-database"postgres://user:pass@host:port/dbname?sslmode=disable"-pathcmd/migrate/migrations up# 也可以执行项目自定义命令执行迁移tmp/aigo.exe migrate up

自定义命令也就是库模式下,不需要填写-database-path参数,也不需要单独安装migrate CLI,是我最喜欢的模式。

CLI 模式其实是天然支持的,只要你安装了migrate CLI即可使用,安装后能额外执行:forcedrop等命令。

将以上内容发给 CC:

后续 CC 询问以何种方式实现自定义命令,这里选择了spf13/cobra,然后:

库模式下迁移文件以何种方式加载? ❯1. go:embed 内嵌(推荐) up/down/status 用 go:embed 内嵌的迁移文件(编译后二进制自包含,便于部署);create 命令按--dir写入磁盘目录。开发时创建后需重新编译才能 up。2. 文件系统路径 所有操作直接读写 cmd/migrate/migrations 目录,与 golang-migrate CLI 模式完全一致,创建后立即可用。但运行二进制时需能访问到该目录。

意思也很简单,第一个是内嵌到编译产物内,生产直接就能用,第二个是文件系统内存储,生产要用迁移,得先上传文件,所以这里当然是选择内嵌。

第一轮完成后,再将原有项目 config 数据表的数据导出来,整理了一下可能会用得上的配置项,让 CC 基于该 SQL 生成一个 seed 迁移,主要包含站点名称、自定义后台入口、备案号、邮件发送等系统基础配置:

INSERTINTO`config`VALUES(1,'config_group','basic','配置分组','','array','[{\"key\":\"basic\",\"value\":\"基础配置\"},{\"key\":\"mail\",\"value\":\"邮件配置\"},{\"key\":\"config_quick_entrance\",\"value\":\"快捷配置入口\"}]',NULL,'required','','',0,-1);INSERTINTO`config`VALUES(2,'name','basic','站点名称','','string','AI GO ADMIN',NULL,'required','','',0,99);INSERTINTO`config`VALUES(3,'entrance','basic','自定义后台入口','','string','/admin',NULL,'required','','',0,1);INSERTINTO`config`VALUES(4,'record_number','basic','域名备案号','','string','渝ICP备8888888号-1',NULL,'','','',0,0);INSERTINTO`config`VALUES(5,'version','basic','系统版本号','','string','v1.0.0',NULL,'required','','',0,0);INSERTINTO`config`VALUES(6,'timezone','basic','时区','','string','Asia/Shanghai',NULL,'required','','',0,0);INSERTINTO`config`VALUES(7,'no_access_ip','basic','禁止访问 IP','禁止访问站点的ip列表,一行一个','textarea',NULL,NULL,'','','',0,0);INSERTINTO`config`VALUES(8,'smtp_server','mail','SMTP 服务器','','string','smtp.com',NULL,'','','',0,9);INSERTINTO`config`VALUES(9,'smtp_port','mail','SMTP 端口','','string','465',NULL,'','','',0,8);INSERTINTO`config`VALUES(10,'smtp_user','mail','SMTP 用户','','string',NULL,NULL,'','','',0,7);INSERTINTO`config`VALUES(11,'smtp_pass','mail','SMTP 密码','','string',NULL,NULL,'','','',0,6);INSERTINTO`config`VALUES(12,'smtp_verification','mail','SMTP 验证方式','','select','SSL','{\"SSL\":\"SSL\",\"TLS\":\"TLS\"}','','','',0,5);INSERTINTO`config`VALUES(13,'smtp_sender_mail','mail','SMTP 发件人邮箱','','string',NULL,NULL,'email','','',0,4);INSERTINTO`config`VALUES(14,'config_quick_entrance','quick_entrance','快捷配置入口','','array','[]',NULL,'','','',0,0);

完工后,人工review发现了以下问题:

缺少表前缀配置应用

cmd\migrate\migrations中的 SQL,表名全是adminstokens这种不带表前缀的,但是我们的系统支持表前缀,只是默认为空。

这里让 AI 在 SQL 中以固定字符串__PREFIX__表示表前缀,执行迁移前将该字符串替换为项目数据库配置中的实际表前缀。

项目命令规划

现在多了一个迁移命令,将原来的cmd/api/main.go改名为cmd/serve/serve.go(作为单独的服务启动命令),然后新增cmd/main.go文件作为统一命令入口,从现在起:

# 启动 API 服务go run cmd/main.go serve# 应用数据库迁移go run cmd/main.go migrate up# 或编译后再运行go build-o./tmp/aigo.exe ./cmd/main.go tmp/aigo.exe serve tmp/aigo.exe migrate up

同时serve作为默认命令,是可以省略的。

同步修改 AGENTS.md / README.md / .air.toml

这次对数据迁移做了改动,项目启动流程和迁移功能介绍都需要重新写,直接让 CC 帮忙完成,再人工整理一下。

放弃原生的 Migrate CLI 工具

https://github.com/golang-migrate/migrate是支持CLI双模式的,正常情况下我整合了库模式,CLI天然就能用,此时突然发现原生的Migrate CLI不支持传递表前缀啊,这里只能再看看CLI还有那些命令是我们当前不支持的,让 CC 全部实现一遍(version 和 drop 子命令),然后直接放弃CLI模式。

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

图神经网络过平滑问题:从谱域分析到4层GCN的收敛证明

图神经网络过平滑问题的谱域分析与四层GCN收敛性证明在社交网络分析、分子结构预测和推荐系统等实际应用中,图神经网络(GNN)展现出了强大的建模能力。然而,随着网络层数的增加,节点特征会逐渐失去区分度,这种现象被称为"过平…

作者头像 李华
网站建设 2026/7/11 19:22:42

TradingAgents-CN:基于多智能体LLM的智能投资分析平台终极指南

TradingAgents-CN:基于多智能体LLM的智能投资分析平台终极指南 【免费下载链接】TradingAgents-CN 基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版 项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN TradingAgents-CN是一…

作者头像 李华
网站建设 2026/7/11 19:22:39

2026最新8款企业级AI编程工具实测深度对比

我去年作为信创项目的国产化改造负责人,牵头做代号为「青驹」的省级物流追踪系统迭代项目的时候,12人的后端团队要在3个月内完成原有老系统的Python Flask微服务改造,还要适配国产鲲鹏服务器、满足等保2.0的所有合规要求,一开始团…

作者头像 李华
网站建设 2026/7/11 19:22:18

线结构光标定精度对比:灰度重心法 vs Steger算法 vs 互相关法,3种中心线提取方案实测

线结构光标定精度对比:灰度重心法 vs Steger算法 vs 互相关法 在工业视觉测量领域,线结构光系统的标定精度直接影响三维重建的准确性。激光条纹中心线提取作为标定流程的核心环节,其算法选择直接决定了亚像素级边缘定位的可靠性。本文将深入解…

作者头像 李华
网站建设 2026/7/11 19:21:02

不用多设备模拟器跑通 ShareKit 碰一碰分享

很多开发者想上手鸿蒙特色的碰一碰分享,但手头没有两台支持NFC的鸿蒙实体设备,甚至只有模拟器环境。先明确一个客观前提: 碰一碰的硬件触发环节(NFC近场检测、设备自动发现)依赖实体NFC与蓝牙硬件,纯模拟器…

作者头像 李华