首页/新闻资讯/正文详情

从 PHP 到 AI + Golang,程序员自救转型手记(三十三):admin_rule 数据表迁移与 TaoToken 配置骨架

发布时间:2026/9/27 19:44:33 来源:云帆数科 栏目:资讯中心
从 PHP 到 AI + Golang,程序员自救转型手记(三十三):admin_rule 数据表迁移与 TaoToken 配置骨架
1. 从 PHP 到 Golang 的 admin_rule 迁移为什么值得单独写一篇如果你是从 PHP 转 Golang 的开发者大概率会遇到这样一个场景后台权限系统里有一张admin_rule表存的是菜单、按钮、权限节点这些规则数据。PHP 时代你可能用 ThinkPHP 或者 Laravel 的迁移工具一条命令就搞定了。但换到 Golang 之后迁移这件事突然变得没有标准答案——有人用 GORM AutoMigrate有人手写 SQL 文件有人用 goose、migrate 这类工具。这篇要解决的就是这个具体问题在 Golang 项目里把admin_rule这张表从模型定义到迁移文件完整落地同时把 AI 工具接入需要的配置文件骨架settings.json / config.toml和统一 Key 配置一起整理好。适合正在做 PHP 转 Go 转型、或者正在搭建后台权限系统的读者。核心检索词就是 admin_rule 数据表迁移、Golang 迁移文件、TaoToken 配置骨架。我自己的做法是模型放internal/model/admin.go迁移文件放cmd/migrate/migrations/目录下用编号前缀区分顺序。这样模型和迁移各司其职不会出现改了模型忘了改表的情况。下面把完整流程拆开讲。2. TaoToken 前置准备统一 Key 与配置文件骨架在写迁移之前先把 AI 工具链的配置骨架搭好。因为后面写迁移脚本、排查字段类型的时候我会用 AI 辅助生成和校对统一 Key 能省掉很多重复配置的麻烦。TaoToken 的定位是给开发者提供统一的模型调用入口一个 Key 可以对接多种模型。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 这个不加 UTM。你需要先去控制台创建一个 API Key地址在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建好之后把 Key 存到环境变量里不要硬编码进配置文件。# Linux / macOS export TAOTOKEN_API_KEYsk-你的key # Windows PowerShell $env:TAOTOKEN_API_KEYsk-你的key然后是配置文件骨架。我习惯用两个文件settings.json给编辑器类工具用config.toml给命令行工具用。两个文件都从环境变量读 Key这样切换环境不用改文件。settings.json骨架{ ai: { provider: taotoken, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, default_model: claude-sonnet-4-20250514, timeout_seconds: 60 }, project: { name: ai-go-admin, migration_dir: cmd/migrate/migrations, model_dir: internal/model } }config.toml骨架[ai] provider taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY default_model claude-sonnet-4-20250514 timeout_seconds 60 [project] name ai-go-admin migration_dir cmd/migrate/migrations model_dir internal/model这两个文件的作用是让工具知道去哪里找 Key、用哪个模型、项目结构长什么样。Key 本身不写进文件只写环境变量名这是基本的安全习惯。3. admin_rule 模型定义与迁移文件编写3.1 模型定义internal/model/admin.go先看模型。admin_rule表存的是菜单和权限规则字段比较多但结构清晰。下面是完整的 AdminRule 模型package model import time // AdminRule 菜单和权限规则模型 type AdminRule struct { ID uint gorm:comment:ID;primaryKey;autoIncrement json:id Pid *uint gorm:comment:上级规则;index json:pid Type string gorm:comment:规则类型:dir规则目录,menu菜单项,node权限节点;type:varchar(50);not null;default: json:type Title string gorm:comment:规则标题;type:varchar(50);not null;default: json:title Name string gorm:comment:规则名称;type:varchar(50);not null;default: json:name Path string gorm:comment:菜单路由路径;type:varchar(255);not null;default: json:path Icon string gorm:comment:菜单图标;type:varchar(50);not null;default: json:icon OpenType string gorm:comment:菜单打开方式:tab选项卡,link链接,iframeIframe;type:varchar(50);not null;default: json:open_type URL string gorm:comment:菜单URL;type:varchar(255);not null;default: json:url Component string gorm:comment:菜单组件路径;type:varchar(255);not null;default: json:component Keepalive uint8 gorm:comment:缓存:0关闭,1开启;not null;default:0 json:keepalive Extend string gorm:comment:扩展属性:add_route_only只添加为路由,add_menu_only只添加为菜单;type:varchar(50);not null;default: json:extend Remark string gorm:comment:备注;type:varchar(255);not null;default: json:remark Weigh int gorm:comment:权重;not null;default:0 json:weigh Status uint8 gorm:comment:状态:0禁用,1启用;not null;default:1 json:status UpdateTime time.Time gorm:comment:更新时间 json:update_time CreateTime time.Time gorm:comment:创建时间 json:create_time } func (AdminRule) TableName() string { return admin_rules }几个关键点说明一下。Pid用*uint指针类型因为顶级菜单的 pid 是 0 或者 NULL用指针能区分没设置和设置为 0。Keepalive和Status用uint8而不是bool因为数据库里是 tinyint保持类型一致避免转换麻烦。TableName()方法显式指定表名避免 GORM 复数化规则带来的意外。3.2 迁移文件up 和 down迁移文件放在cmd/migrate/migrations/目录下用编号前缀控制执行顺序。up 文件负责建表down 文件负责回滚。000001_admin_rule.up.sqlCREATE TABLE IF NOT EXISTS __PREFIX__admin_rule ( id int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT ID, pid int UNSIGNED NOT NULL DEFAULT 0 COMMENT 上级规则, type varchar(50) NOT NULL DEFAULT menu COMMENT 规则类型:dir规则目录,menu菜单项,node权限节点, title varchar(50) NOT NULL DEFAULT COMMENT 规则标题, name varchar(50) NOT NULL DEFAULT COMMENT 规则名称, path varchar(255) NOT NULL DEFAULT COMMENT 菜单路由路径, icon varchar(50) NOT NULL DEFAULT COMMENT 菜单图标, open_type varchar(50) NOT NULL DEFAULT COMMENT 菜单打开方式:tab选项卡,link链接,iframeIframe, url varchar(255) NOT NULL DEFAULT COMMENT 菜单URL, component varchar(255) NOT NULL DEFAULT COMMENT 菜单组件路径, keepalive tinyint UNSIGNED NOT NULL DEFAULT 0 COMMENT 缓存:0关闭,1开启, extend varchar(50) NOT NULL DEFAULT COMMENT 扩展属性:add_route_only只添加为路由,add_menu_only只添加为菜单, remark varchar(255) NOT NULL DEFAULT COMMENT 备注, weigh int NOT NULL DEFAULT 0 COMMENT 权重, status tinyint UNSIGNED NOT NULL DEFAULT 1 COMMENT 状态:0禁用,1启用, update_time bigint UNSIGNED NULL DEFAULT NULL COMMENT 更新时间, create_time bigint UNSIGNED NULL DEFAULT NULL COMMENT 创建时间, PRIMARY KEY (id) USING BTREE, INDEX idx_pid (pid ASC) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 菜单和权限规则表 ROW_FORMAT DYNAMIC;000001_admin_rule.down.sqlDROP TABLE IF EXISTS __PREFIX__admin_rule;注意__PREFIX__这个占位符实际执行时会被替换成项目配置的表前缀。这样迁移文件可以复用到不同项目不用改 SQL。3.3 迁移执行器cmd/migrate/main.go光有 SQL 文件还不够需要一个执行器来读取、替换前缀、按顺序执行。下面是一个精简版的迁移执行器package main import ( database/sql fmt log os path/filepath sort strings _ github.com/go-sql-driver/mysql ) func main() { dsn : os.Getenv(DB_DSN) if dsn { log.Fatal(DB_DSN 环境变量未设置) } prefix : os.Getenv(DB_PREFIX) if prefix { prefix ba_ } db, err : sql.Open(mysql, dsn) if err ! nil { log.Fatalf(连接数据库失败: %v, err) } defer db.Close() dir : cmd/migrate/migrations files, err : filepath.Glob(filepath.Join(dir, *.up.sql)) if err ! nil { log.Fatalf(读取迁移目录失败: %v, err) } sort.Strings(files) for _, f : range files { content, err : os.ReadFile(f) if err ! nil { log.Fatalf(读取 %s 失败: %v, f, err) } sqlText : strings.ReplaceAll(string(content), __PREFIX__, prefix) if _, err : db.Exec(sqlText); err ! nil { log.Fatalf(执行 %s 失败: %v, f, err) } fmt.Printf(迁移执行成功: %s\n, filepath.Base(f)) } }这个执行器做了三件事读环境变量拿 DSN 和前缀、按文件名排序保证顺序、替换占位符后执行。回滚的话把*.up.sql换成*.down.sql执行顺序反过来就行。4. 验证请求与成功结果4.1 执行迁移先设置好环境变量然后跑迁移export DB_DSNroot:passwordtcp(127.0.0.1:3306)/ai_go_admin?charsetutf8mb4parseTimetrue export DB_PREFIXba_ go run cmd/migrate/main.go预期输出迁移执行成功: 000001_admin_rule.up.sql4.2 验证表结构连上数据库用SHOW CREATE TABLE确认字段和索引SHOW CREATE TABLE ba_admin_rule;重点检查三处pid字段有没有索引、type和status的默认值对不对、字符集是不是 utf8mb4。如果这三处都对表结构就没问题。4.3 验证 AI 配置骨架配置文件写好后用一次简单的模型对话验证 Key 是否生效。模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 你可以在那里直接测试 Key 能不能正常调用。如果要在命令行验证可以用 curlcurl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [{role: user, content: 回复 OK 两个字母}] }返回里有正常的choices字段说明 Key 和配置骨架都通了。4.4 回滚验证迁移能跑通还不够回滚也要验证。执行 down 文件mysql -u root -p ai_go_admin cmd/migrate/migrations/000001_admin_rule.down.sql然后再跑一次 up确认能重复执行不报错。这一步很多人会跳过但实际项目里回滚能力比迁移能力更重要。5. 本篇常见错排查5.1 字段类型不匹配导致迁移失败最常见的是pid字段。PHP 时代可能用int存 0 表示顶级但 Golang 模型里用了*uint指针。如果迁移 SQL 里pid是NOT NULL DEFAULT 0而模型里是指针插入数据时可能出现 NULL 和 0 混用。建议统一要么都用 0 表示顶级要么都允许 NULL。我选的是NOT NULL DEFAULT 0模型里指针只是为了 JSON 序列化时能区分。5.2 表前缀替换遗漏__PREFIX__占位符如果没替换SQL 会直接报语法错误。检查执行器里strings.ReplaceAll有没有生效以及环境变量DB_PREFIX有没有设置。如果项目里有多处用到前缀建议把替换逻辑抽成一个函数避免漏改。5.3 迁移顺序错乱文件名编号一定要用零填充比如000001、000002不要用1、2。因为sort.Strings是按字符串排序的10会排在2前面。零填充能保证顺序正确。5.4 AI 工具读不到 Key如果配置文件里写的是api_key_env但环境变量没导出工具会报认证失败。检查两点环境变量名和配置文件里写的是否一致、当前 shell 会话有没有export。Windows 下用$env:设置别用set。5.5 迁移执行器权限不足CREATE TABLE需要建表权限DROP TABLE需要删表权限。如果数据库账号只有增删改查权限迁移会失败。开发环境用 root生产环境单独建一个迁移账号只给必要的权限。6. 配置骨架与后续接入迁移跑通之后数据层就稳了。接下来是把 AI 工具链接进来。前面搭好的settings.json和config.toml骨架现在可以填上具体内容。如果你主要是做代码补全和迁移脚本生成建议用 Coding Plan入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。这个方案对长期编码场景更划算不用每次单独配 Key。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各种工具的配置示例。API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 可以创建多个 Key 分别给不同工具用方便排查问题时定位是哪个工具出的错。如果你用的是 Claude Code 这类工具Anthropic 兼容配置的说明在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 照着改 base_url 和 api_key 就行。最后说一个实际踩过的坑迁移文件里的注释别写太长。有些数据库对 COMMENT 长度有限制超过 255 字符会截断或者报错。我一开始把整个字段说明都塞进 COMMENT结果type字段的注释被截了排查了半天才发现是长度问题。现在注释控制在 100 字符以内详细说明放文档里。

相关推荐

GitHub 2026年AI项目热度分析报告:用TaoToken统一Key跑通数据采集与AI分析全流程
GitHub 2026年AI项目热度分析报告:用TaoToken统一Key跑通数据采集与AI分析全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 19:44:33

GitHub 热榜项目 · 日榜精选(2026-01-09):chrome-devtools-mcp、claude-code 与 stb 的配置骨架拆解
GitHub 热榜项目 · 日榜精选(2026-01-09):chrome-devtools-mcp、claude-code 与 stb 的配置骨架拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 19:44:33

控诊协同论文分享:故障诊断也需要考虑控制信号
控诊协同论文分享:故障诊断也需要考虑控制信号

在船舶与重型动力装备的智能运维研究中,状态监测与故障诊断大多依赖于振动、温度、压力和流量等状态响应信号。然而,动力系统并非孤立运行的被动对象,其内部状态时刻受到控制指令的调节。近期发表在《Transactions of the Institute of Measu… · 2026/9/27 19:44:27

四川网站推广优化速查手册:被黑挂马后这样修才不白做
四川网站推广优化速查手册:被黑挂马后这样修才不白做

四川网站推广优化速查手册:被黑挂马后这样修才不白做 网站被黑挂马,首页突然变成博彩页面,后台密码改了也进不去?别慌,这种时候最忌讳盲目重装系统。我见过太多四川本地的企业站,因为不懂底层逻辑,花了大价钱找“黑客”删链,结果没三天又复发。今天这… · 2026/9/27 20:13:44

目前广泛应用的AI编程工具配 TaoToken:统一 Key 接入与 settings.json 配置骨架
目前广泛应用的AI编程工具配 TaoToken:统一 Key 接入与 settings.json 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:13:44

零代码穿透:微信一键接入 OpenClaw 教程(TaoToken 统一 Key 配置版)
零代码穿透:微信一键接入 OpenClaw 教程(TaoToken 统一 Key 配置版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:13:37

DeepSeek + AnythingLLM 搭建个人知识库:TaoToken 统一 API 配置与 RAG 验证
DeepSeek + AnythingLLM 搭建个人知识库:TaoToken 统一 API 配置与 RAG 验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:13:37

enable_all_triggers 配置避坑:TaoToken 统一 Key 接入 SQL 触发器调试链路
enable_all_triggers 配置避坑:TaoToken 统一 Key 接入 SQL 触发器调试链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 20:13:31

微信引流神器手机电影网站怎么做新手最佳实践避坑指南
微信引流神器手机电影网站怎么做新手最佳实践避坑指南

微信引流神器手机电影网站怎么做新手最佳实践避坑指南 网站被黑挂马不知道怎么办?别慌,先查服务器日志,再看是否开启了自动更新,最后确认SSL证书状态。很多新手做 微信引流神器手机电影网站怎么做… · 2026/9/27 20:13:19

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码