我见过的大多数Go/GORM示例都显示在打开数据库连接后立即调用Automigrate,包括这里的GORM文档。对于API服务,对于每个API请求,这将是一个昂贵的/需要的调用。因此,我认为,对于API服务,应该从常规流中删除自动化并单独处理。我的理解对吗?
选自GORM Documentation
...
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
db.AutoMigrate(&Product{})
...
这不会发生在每个API请求中。差远了。每次应用程序启动时都会发生这种情况,所以基本上:连接到main
中的DB,并在那里运行AutoMigrate
。将连接作为依赖传递给你的处理程序/服务包/任何你需要它们的地方。HTTP处理程序可以直接访问它。
基本上是这样的:
package main
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
fmt.Printf("Failed to connect to DB: %v", err)
os.Exit(1)
}
// see below how this is handled
fRepo := foo.New(db) // all repos here
fRepo.Migrate() // this handles migrations
// create request handlers
fHandler := handlers.NewFoo(fRepo) // migrations have already been handled
mux := http.NewServeMux()
mux.HandleFunc("/foo/list", fHandler.List) // set up handlers
// start server etc...
}
在某些包中与DB交互的代码如下:
package foo
// The DB connection interface as you use it
type Connection interface {
Create()
Find()
AutoMigrate(any)
}
type Foo struct {
db Connection
}
func New(db Connection) *Foo {
return &Foo{
db: db,
}
}
func (f *Foo) Migrate() {
f.db.AutoMigrate(&Stuff{}) // all types this repo deals with go here
}
func (f *Foo) GetAll() ([]Stuff, error) {
ret := []Stuff{}
res := f.db.Find(&ret)
return ret, res.Error
}
然后以一种合理的方式构造你的处理程序,并为它们提供存储库(也就是foo包的东西):
package handlers
type FooRepo interface {
GetAll() ([]Stuff, error)
}
type FooHandler struct {
repo FooRepo
}
func NewFoo(repo FooRepo) *FooHandler {
return &FooHandler{
repo: repo,
}
}
func (f *FooHandler) List(res http.ResponseWriter, req *http.Request) {
all, err := f.repo.GetAll()
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
io.WriteString(w, err.Error())
return
}
// write response as needed
}
每当您部署应用程序的更新版本时,main
函数将调用AutoMigrate
,并且应用程序将处理请求,而无需不断重新连接到DB或尝试一次又一次地处理迁移。
我不知道为什么你会认为你的应用程序将不得不运行通过设置为每个请求,特别是考虑到你的主函数(或一些函数,你从main
调用)显式创建一个HTTP服务器,并监听请求的特定端口。在开始侦听请求之前,应该先处理DB连接和随后的迁移。这不是处理请求的一部分,从来没有…