beego orm 必须注册名为 default 的数据库别名,否则首次调用 orm.neworm() 会 panic 报“must have one register database alias named default”;该别名必须在 init() 中、orm 操作前完成注册,且驱动注册须先于数据源注册。

Beego ORM 必须注册名为 default 的数据库别名
不注册 default,应用启动后第一次调用 orm.NewOrm() 就会 panic,报错信息是 must have one register DataBase alias named `default`。这不是连接失败,而是 ORM 内部初始化时查不到这个固定别名,直接退出进程。
注册必须在 init() 函数里完成,且早于任何 ORM 操作(比如 RunSyncdb 或控制器中首次 NewOrm)。驱动注册和数据源注册顺序不能颠倒:
- 先调用
orm.RegisterDriver("postgres", orm.DR_Postgres)或orm.RegisterDriver("mysql", orm.DR_MySQL) - 再调用
orm.RegisterDataBase("default", "mysql", dsn1)—— 别名必须叫default,哪怕你实际主库是 PostgreSQL - 其他库(如报表库)可额外注册,例如
orm.RegisterDataBase("report", "postgres", dsn2),但default不可省略
o.Using("alias") 是切换数据源的唯一运行时方式
Beego ORM 不支持“自动路由”或“注解切换”,所有非 default 库的查询都必须显式调用 .Using("alias")。漏写就会走默认库,查错表、写错库,且无任何警告。
常见错误场景:
- 在 controller 里写了
o := orm.NewOrm(),但没接.Using("report"),结果本该查报表库的 SQL 去了主库 - 事务中混用多个
.Using:Beego 不支持跨 alias 事务,o.Using("mysql").Begin()和o.Using("pg").Insert()会各自开独立事务,无法原子提交 - 模型定义未适配多库:同一个
type User struct在 MySQL 和 PostgreSQL 中字段类型可能不兼容(如jsonbvsjson),AutoMigrate 需分别对每个 alias 执行
多数据源 ≠ 多连接池共享配置
每个 RegisterDataBase 调用都会创建独立的 *sql.DB 实例,底层连接池参数互不影响。不能只配一次 SetMaxOpenConns 就认为全库生效。
必须为每个 alias 单独设置连接池行为(尤其在高并发或长连接场景下):
- 调用
orm.GetDB("default")和orm.GetDB("report")分别获取原生*sql.DB - 对每个实例单独调用
SetMaxOpenConns(50)、SetMaxIdleConns(10)、SetConnMaxLifetime(1h) - 若某库是只读报表库,可调低
MaxOpenConns;主库写压力大,则需更高值并监控sql.DB.Stats().OpenConnections
业务层避免硬编码 if db == "pg" 分支
把数据库类型判断散落在 service 层,会导致测试难覆盖、上线易漏改、模型变更时同步成本高。
推荐用接口 + 工厂模式隔离切换点:
- 定义统一仓储接口:
type UserRepository interface { GetByID(id int) (*User, error) } - 为每个库实现具体版本:
mysqlUserRepo和pgUserRepo,各自内部用o.Using("mysql")或o.Using("report") - 启动时根据配置选择注入:
repo := newUserRepository(config.DBType),后续业务代码只依赖接口
真正容易被忽略的是:Beego 的 RegisterDataBase 是全局静态注册,一旦完成就不可增删。这意味着运行时动态加载新库(比如按租户切库)必须绕过 ORM,直接操作 database/sql,再自行管理 *sql.DB 生命周期。











