Home >Backend Development >Golang >When is the best time to run Automigrate with GORM
php Xiaobian Youzi will share with you today the best time to run Automigrate on GORM. GORM is a powerful Go language ORM library that can simplify database operations. Automigrate is an automatic migration tool provided by GORM, which can automatically generate database table structures based on model definitions. So when is the best time to run Automigrate with GORM? Let’s explore it together.
Most go/gorm examples I've seen show calling automigrate immediately after opening a database connection, including the gorm documentation here. For api services, this is an expensive/required call for every api request. So, I think, for api services, automigrate should be removed from the regular process and handled separately. Is my understanding correct?
From 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{}) ...
This does not happen with every api request. Not even close. This happens every time you start the application, so basically: connect to the database in main
and run automigrate
there. Pass the connection as a dependency to your handler/service package/whatever you need. The http handler can access it there.
Basically it’s like this:
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... }
Contain the code for interacting with the database in a package, as shown below:
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 }
Then structure your handlers in a sensible way and provide them with the repository (aka foo package contents):
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 }
Whenever you deploy an updated version of your application, the main
function will call automigrate
and the application will handle the request without having to constantly reconnect to the database or over and over again One attempt is made to process the migration.
I'm not sure why you think your application has to run a per-request setup, especially considering that your main function (or some function called from main
) explicitly creates one http server and listens on a specific port for requests. Before starting to listen for requests, the database connection and subsequent migrations should be handled. It is not part of handling the request, ever...
The above is the detailed content of When is the best time to run Automigrate with GORM. For more information, please follow other related articles on the PHP Chinese website!