【问题标题】:gorm automigrate not creating tablegorm自动迁移不创建表
【发布时间】:2021-10-28 02:30:49
【问题描述】:

在 Golang 中构建 API。 DB 正在连接,但 Postman 请求出现 500 个错误。我认为是因为我试图访问的表没有在迁移中创建。

这是错误跟踪:

Host: localhost:8080 Accept: / Accept-Encoding: gzip, deflate, br 连接:保持活动内容长度:103 内容类型: 应用程序/json 邮递员令牌:175ee0c2-e016-40e9-a599-ce0bce60a650 用户代理:PostmanRuntime/7.28.4

运行时错误:无效的内存地址或 nil 指针取消引用 /usr/local/go/src/runtime/panic.go:221 (0x1049c26) 恐慌:恐慌(内存错误)/usr/local/go/src/runtime/signal_unix.go:735(0x1049bf6) sigpanic:panicmem() /Users/dariusgoore/go/pkg/mod/github.com/jinzhu/gorm@v1.9.16/main.go:853 (0x1309b9d) (*DB).clone: 方言: newDialect(s.dialect.GetName(), s.db), /Users/dariusgoore/go/pkg/mod/github.com/jinzhu/gorm@v1.9.16/main.go:204 (0x13036f0) (*DB).NewScope: dbClone := s.clone() /Users/dariusgoore/go/pkg/mod/github.com/jinzhu/gorm@v1.9.16/main.go:354 (0x1305a4c) (*DB).Find:返回 s.NewScope(out).inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db /Users/dariusgoore/go/src/resource-api/Models/Client.go:11 (0x1504b77) GetAllClients: if err = Config.DB.Find(client).Error;错误!= nil { /Users/dariusgoore/go/src/resource-api/Controllers/Client.go:13 (0x1504b7f) GetClients:错误:= Models.GetAllClients(&client) /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/context.go:165 (0x14fbf01) (*上下文)。下一步:c.handlersc.index /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/recovery.go:99 (0x14fbeec) CustomRecoveryWithWriter.func1: c.Next() /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/context.go:165 (0x14fb166) (*上下文)。下一步:c.handlersc.index /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/logger.go:241 (0x14fb149) LoggerWithConfig.func1: c.Next() /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/context.go:165 (0x14fa69d) (*上下文)。下一步:c.handlersc.index /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/gin.go:489 (0x14fa325) (*Engine).handleHTTPRequest: c.Next() /Users/dariusgoore/go/pkg/mod/github.com/gin-gonic/gin@v1.7.4/gin.go:445 (0x14f9e84) (*Engine).ServeHTTP: engine.handleHTTPRequest(c) /usr/local/go/src/net/http/server.go:2878 (0x1382b3a) serverHandler.ServeHTTP: handler.ServeHTTP(rw, req) /usr/local/go/src/net/http/server.go:1929 (0x137e1e7) (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req) /usr/local/go/src/runtime/asm_amd64.s:1581 (0x10645a0) goexit: BYTE $0x90 // NOP

这里是 Controllers/Client.go:

package Controllers

import (
    "resource-api/Models"
    "fmt"
    "net/http"
    "github.com/gin-gonic/gin"
)

//GetClients ... Get all clients
func GetClients(c *gin.Context) {
    var client []Models.Client
    err := Models.GetAllClients(&client)
    if err != nil {
        c.AbortWithStatus(http.StatusNotFound)
    } else {
        c.JSON(http.StatusOK, client)
    }
} ...

And Models/Client.go

package Models

import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "resource-api/Config"
)

//GetAllClients Fetch all client data
func GetAllClients(client *[]Client) (err error) {
    if err = Config.DB.Find(client).Error; err != nil {
        return err
    }
    return nil
}
...

和模型/ClientModel.go:

package Models

type Client struct {
    Id           uint      `json:"id"`
    Name        string    `json:"name"`
    URL       string    `json:"url"`
    Description  string    `json:"description"`
}
func (c *Client) TableName() string {
    return "client"
}

还有 main.go:

package main

import (
    "fmt"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "resource-api/Config"

    "resource-api/Models"
    "resource-api/Routes"
)

var err error

func main() {

    db, err := gorm.Open(mysql.Open(Config.DbURL(Config.BuildDBConfig())), &gorm.Config{})
    if err != nil {
        fmt.Println("Status:", err)
    }
    defer Config.DB.Close()


    db.Debug().AutoMigrate(&Models.Client{})
    r := Routes.SetupRouter()
    //running
    r.Run()
}

添加 Config/Database.go 以响应 cmets:

package Config

import (
    "fmt"

    "github.com/jinzhu/gorm"
)

var DB *gorm.DB

// DBConfig represents db configuration
type DBConfig struct {
    Host string
    Port int
    User string
    DBName string
    Password string
}

func BuildDBConfig() *DBConfig {
    dbConfig := DBConfig{
        Host: "localhost",
        Port: 3306,
        User: "root",
        Password: "654321cg",
        DBName: "resourcesdb",
    }
    return &dbConfig
}

func DbURL(dbConfig *DBConfig) string {
    return fmt.Sprintf(
        "%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
        dbConfig.User,
        dbConfig.Password,
        dbConfig.Host,
        dbConfig.Port,
        dbConfig.DBName,
        )
}

【问题讨论】:

    标签: mysql go grails-orm


    【解决方案1】:

    我看不到配置文件。调试故障点会容易得多。浏览完您的屏幕截图后,我可以看到您已在 main.go 文件中创建了连接。很好,您还迁移了数据库,但是在您的 Models/Client.go 文件中,您正在访问一个指针变量,该变量应该是您在 main.go 文件中创建的数据库连接对象,我认为您没有使用该数据库连接对象。

    【讨论】:

    • 在问题中添加了配置文件。
    • 好的,因此您正在从 Config 文件访问 DB 对象以查询数据,但您没有将 main.go 文件中的 db 连接对象分配给此配置的 DB 对象。这就是你得到零指针错误的原因。
    • 所以这行不正确?:db, err := gorm.Open(mysql.Open(Config.DbURL(Config.BuildDBConfig())), &gorm.Config{})
    • 不,我没有这么说。我说你需要使用这个 db 对象从你的数据库中查询。但是你正在使用这个来自配置对象的DB,它甚至没有被初始化,默认情况下它在 golang 中是 nil 。现在让你的代码工作在这行Config.DB = db之后添加这行db, err := gorm.Open(mysql.Open(Config.DbURL(Config.BuildDBConfig())), &gorm.Config{})
    • 尝试过并将 Database.go 中的包从“github.com/jinzhu/gorm”更改为“gorm.io/gorm”。出现新错误。邮递员返回 404,但在终端我得到` /...../Models/Client.go:11 dial tcp [::1]:3306: connect: connection denied [0.943ms] [rows:0] SELECT * FROM client [杜松子酒] 2021/08/29 - 07:32:42 | 404 | 1.005165ms | ::1 | GET "/clients/client"`
    猜你喜欢
    • 1970-01-01
    • 2021-05-28
    • 2021-12-27
    • 2020-04-18
    • 2020-07-12
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    相关资源
    最近更新 更多