将 gorm.DB 分配给模型变量时出错。

huangapple go评论80阅读模式
英文:

Error assigning gorm.DB to a model variable

问题

我需要帮助解决Golang中指针的问题panic: runtime error: invalid memory address or nil pointer dereference,我试图将gorm的*gorm.DB实例返回给另一个文件夹中的模型。

我的想法是在我的模型中实例化一个具有连接的变量,但是当我在func Init()中实例化时,出现了错误。

main.go

package main

import (
	"log"
	"github.com/joho/godotenv"
	"gitlab.com/project/database"
	"gitlab.com/project/models"
)

func main() {
	
	err := godotenv.Load()
	if err != nil {
		panic("Error loading .env file")
	}

	database.InitDatabase()

	memes, err := models.GetAll();

	if err != nil {
		log.Fatal("err database get memes")
	}

	for _, meme := range memes {
		log.Printf(meme.Url)
	}
}

database/database.go

package database

import (
	"gorm.io/gorm"
	"gorm.io/driver/postgres"
)

var (
	DB *gorm.DB
) 

func InitDatabase(){
	d, err := gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{})
	
	if err != nil {
		panic("failed to connect database")
	}

	DB = d
}

func GetDB() (*gorm.DB) {
	return DB
}


models/meme.go

package models

import (
	"gorm.io/gorm"
	"gitlab.com/webeoparty/api/database"
)

type Meme struct {
	gorm.Model
	Id  uint32
	Source string
	Filename_local string
	Original_filename string
	Public_id string
	Url string
	Secure_url string
	Resource_type string
	Width uint32
	Height uint32
}

var Conn *gorm.DB

func init() {
	Conn = database.GetDB()
}

func GetAll() ([]Meme, error) {
	var memes []Meme

	tx := Conn.Find(&memes)

	if tx.Error != nil {
		return []Meme{}, tx.Error
	}

	return memes, nil
}

当我尝试获取*gorm.DB实例时,出现错误panic: runtime error: invalid memory address or nil pointer dereference

但是,当我将方法database.GetDB()写在GetAll()函数内部时,项目可以正常运行。

package models

...

var Conn *gorm.DB

func GetAll() ([]Meme, error) {
	var memes []Meme

    Conn = database.GetDB()
	tx := Conn.Find(&memes)
    
	
    if tx.Error != nil {
		return []Meme{}, tx.Error
	}

	return memes, nil
}

英文:

I Need help with pointers in Golang panic: runtime error: invalid memory address or nil pointer dereference, I'm trying to return an instance of gorm *gorm.DB to my model in another folder

My idea is to have one variable with the connection in my model instantiated once but when I instanced in func Init() I have an error

main.go

package main

import (
	"log"
	"github.com/joho/godotenv"
	"gitlab.com/project/database"
	"gitlab.com/project/models"
)

func main() {
	
	err := godotenv.Load()
	if err != nil {
		panic("Error loading .env file")
	}

	database.InitDatabase()

	memes, err := models.GetAll();

	if err != nil {
		log.Fatal("err database get memes")
	}

	for _, meme := range memes {
		log.Printf(meme.Url)
	}
}

database / database.go

package database

import (
	"gorm.io/gorm"
	"gorm.io/driver/postgres"
)

var (
	DB * gorm.DB
) 

func InitDatabase(){
	d, err := gorm.Open(postgres.Open(os.Getenv("DATABASE_URL")), &gorm.Config{})
	
	if err != nil {
		panic("failed to connect database")
	}

	DB = d
}

func GetDB() (*gorm.DB) {
	return DB
}


models / meme.go

package models

import (
	"gorm.io/gorm"
	"gitlab.com/webeoparty/api/database"
)

type Meme struct {
	gorm.Model
	Id  uint32
	Source string
	Filename_local string
	Original_filename string
	Public_id string
	Url string
	Secure_url string
	Resource_type string
	Width uint32
	Height uint32
}

var Conn *gorm.DB

func init() {
	Conn = database.GetDB()
}

func GetAll() ([]Meme, error) {
	var memes []Meme

	tx := Conn.Find(&memes)

	if tx.Error != nil {
		return []Meme{}, tx.Error
	}

	return memes, nil
}

the error is panic: runtime error: invalid memory address or nil pointer dereference when i try to get the instance of *gorm.DB is

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x28 pc=0xf02a78]

goroutine 1 [running]:
gorm.io/gorm.(*DB).getInstance(0x280bb540108?)
        C:/Users/edoco/Documents/go-workspace/pkg/mod/gorm.io/gorm@v1.23.5/gorm.go:363 +0x18
gorm.io/gorm.(*DB).Find(0x12d96c8?, {0x1194c40?, 0xc000005998}, {0x0, 0x0, 0x0})
        C:/Users/edoco/Documents/go-workspace/pkg/mod/gorm.io/gorm@v1.23.5/finisher_api.go:163 +0x45
gitlab.com/webeoparty/api/models.GetAll()
        C:/Users/edoco/Documents/go-workspace/src/webeoparty-api/models/meme.go:34 +0x54
main.main()
        C:/Users/edoco/Documents/go-workspace/src/webeoparty-api/main.go:22 +0x4a
exit status 2

but When I write the method database.GetDB() inside of the func GetAll() the project run perfectly

package models

...

var Conn *gorm.DB

func GetAll() ([]Meme, error) {
	var memes []Meme

    Conn = database.GetDB()
	tx := Conn.Find(&memes)
    
	
    if tx.Error != nil {
		return []Meme{}, tx.Error
	}

	return memes, nil
}

答案1

得分: 1

models/meme.go中的init()函数在database/database.go中的DB被赋值之前被调用(InitDatabase()尚未被调用)。

这是因为init()是一个特殊的函数,在导入包时被调用,在变量初始化之后;请参阅Effective Go - The Init Function以获取解释。

您可以通过完全删除全局变量Connmodels/meme.go中的init()函数,并在每个模型函数中调用GetDB()来解决此问题。

英文:

init() in models/meme.go gets called before DB is assigned in database/database.go (InitDatabase() was not called yet).

This is because init() is special function and gets called when package is imported, after variable initializers; see Effective Go - The Init Function for explanation.

You can solve this problem by completely removing global variable Conn and init() function from models/meme.go and call GetDB() in each model function to obtain connection.

huangapple
  • 本文由 发表于 2022年6月6日 08:49:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/72512057.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定