go - 如何从 GORM 结构模型生成 SQL 代码?
问题描述
我正在使用 goose 来管理我的数据库迁移,但我需要直接在迁移文件中编写 SQL 语句。有没有办法直接从 GORM 模型生成 SQL?
解决方案
不幸的是,使用该gorm.Session{DryRun: true}
选项不会像使用普通查询那样使调用者可以使用迁移 SQL 语句。
我现在能看到的唯一方法是通过重新实现gorm.io/gorm/logger.Interface
接口来捕获迁移运行的 SQL。具体来说,Trace
方法。
type Interface interface {
LogMode(LogLevel) Interface
Info(context.Context, string, ...interface{})
Warn(context.Context, string, ...interface{})
Error(context.Context, string, ...interface{})
Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error)
}
在内部Trace
,您可以调用该fc
函数参数来获取 SQL 和RowsAffected
,您可以随心所欲地使用它。
例如:
import (
"time"
"context"
"gorm.io/gorm/logger"
)
type RecorderLogger struct {
logger.Interface
Statements []string
}
func (r *RecorderLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
sql, _ := fc()
r.Statements = append(r.Statements, sql)
}
现在将其用作:
recorder := RecorderLogger{logger.Default.LogMode(logger.Info)}
session := db.Session(&gorm.Session{
Logger: &recorder
})
session.AutoMigrate(&Model{}, ...)
// or
session.Migrator().CreateTable(&Model{}, ...) // or any method therein
// now recorder.Statements contains the statements run during migration
这非常 hacky,您可能会遇到问题,因为AutoMigrate
修改了数据库的当前状态并将其迁移到您的模型所需的(直到某一点),并且要使其正常工作,您当前的数据库必须反映您的生产的当前状态数据库(或您希望迁移的任何数据库)。因此,如果您小心的话,您可以构建该工具来帮助您启动迁移脚本,但要正确获得迁移系统的优势,就像goose
您需要使用 SQL 一样:)
推荐阅读
- docker - pm2 和 pm2-runtime 有什么区别?
- php - PHP - Google Analytics - 仅访问用户统计信息的最低要求
- javascript - 断页时页脚重叠内容。如何解决?
- typescript - 使用 tsc 运行类型检查某些文件时如何忽略某些文件
- codeigniter - 如何修复“遇到未捕获的异常”类型:ArgumentCountError
- html - 如何将图像添加到 jinja html 页面
- android - 当应用程序在 Oreo 及更高版本中关闭时,AlarmManager 会触发
- javascript - Element.style.left 属性拒绝取值?
- c# - ASP.NET中如何使用输出参数插入存储过程
- typescript - 在 TypeScript 中通过对象名称设置对象的属性而不会丢失静态类型