数据库连接配置写在外部源(如config.yaml、环境变量等),优先级从低到高为:config.yaml→config-dev.yaml→环境变量→命令行参数→etcd;后加载的同名key覆盖前者。

数据库连接配置写在哪?优先级怎么定
Kratos 的数据库配置不写死在代码里,而是通过 config.Config 加载外部源(如 YAML 文件、环境变量、etcd),最终注入到业务组件中。关键点是:**配置项的 key 名称必须与结构体字段名匹配,且加载顺序决定覆盖关系**。
默认推荐顺序(从低到高):configs/config.yaml(默认)→ configs/config-dev.yaml(环境)→ 环境变量 → 命令行参数 → etcd。后加载的同名 key 会覆盖前面的值。
- YAML 中数据库段建议用
data.database作为顶层 key,和 Kratos 官方示例保持一致 - 环境变量名需大写加下划线,比如
DATA_DATABASE_SOURCE对应source字段 - 如果同时用了 YAML 和环境变量,且都设置了
source,环境变量生效
config.yaml 里 database 部分怎么写才不报错
常见错误是格式缩进错、字段缺失或类型不匹配。Kratos 本身不校验数据库连接串语法,但 sql.Open 在首次调用时会 panic,所以配置必须能被 Go 标准库解析。
正确示例(MySQL):
data:
database:
driver: mysql
source: root:123456@tcp(127.0.0.1:3306)/kratos-demo?charset=utf8mb4&parseTime=True&loc=Local
-
driver必须是database/sql支持的驱动名,如mysql、postgres、sqlite3 -
source是完整 DSN,注意 URL 中的&要写成&(YAML 转义)或改用单引号包裹整个字符串 - 别漏掉
parseTime=True,否则time.Time字段扫描失败;loc=Local避免时区错乱 - SQLite 示例:
source: file:app.db?_fk=1,注意路径权限和_fk=1开启外键
如何把 config.yaml 里的 database 配置传给 GORM 或 Ent
Kratos 不绑定 ORM,所以你要手动把 config.Value("data.database") 解析成对应 ORM 所需的结构。GORM 和 Ent 的初始化入口通常在 internal/data/ 下的 newData() 或 newDB() 函数中。
以 GORM 为例:
type DatabaseConfig struct {
Driver string `json:"driver"`
Source string `json:"source"`
}
// 在 data.go 中
func newDB(c *conf.Data) (*gorm.DB, error) {
var cfg DatabaseConfig
if err := c.Database.Unmarshal(&cfg); err != nil {
return nil, err
}
db, err := gorm.Open(mysql.Open(cfg.Source), &gorm.Config{})
// ...
}
- 别直接用
c.Database.String()拼接,要Unmarshal到结构体再取字段,否则无法兼容嵌套字段(如max_open_conns) - Ent 初始化更简单,
ent.Open(cfg.Driver, cfg.Source)即可,但注意 SQLite 需要额外导入驱动(_ "github.com/mattn/go-sqlite3") - 如果用了连接池配置(如
max_idle_conns),得在 YAML 里显式定义,并在 Unmarshal 后手动设置db.SetMaxIdleConns()
为什么数据库连上了却查不到数据?检查这三点
配置加载成功 ≠ 查询可用。很多问题出在连接池、事务上下文或驱动兼容性上。
- 检查日志是否输出
failed to ping database:说明db.PingContext()失败,可能是网络、账号密码或 MySQL 8+ 默认认证插件不兼容(需加&allowNativePasswords=true) - GORM 默认开启事务,
First()查不到记录时返回gorm.ErrRecordNotFound,不是nil错误,别用if err != nil直接 panic - Ent 的
Create()方法返回的是*ent.User,不是error;错误只在Save(ctx)时返回,漏掉这个调用会导致静默失败
最易忽略的是:Kratos 的 Bootstrap 初始化顺序。数据库 client 必须在 HTTP/gRPC server 启动前完成构建,否则服务起来就 panic —— 这个依赖关系要在 cmd/server/main.go 的 app.New 调用链里理清楚。











