【问题标题】:GORM One-to One mapping issueGORM 一对一映射问题
【发布时间】:2021-12-26 09:48:16
【问题描述】:

我对 GORM 映射有一个奇怪的问题,我有两个如下所示的结构。

type ParcelOrder struct {
    gorm.Model
    ID                 int                `json:"id"`
    SenderId           uint               `json:"sender_id"`
    OrderID            string             `json:"order_id"`
    PickupAddress      string             `json:"pickup_address"`
    DeliveryAddress    string             `json:"delivery_address"`
    CreatedAt          time.Time          `json:"created_at"`
    UpdatedAt          time.Time          `json:"updated_at"`
    DeletedAt          sql.NullTime       `json:"deleted_at"`
    ParcelOrderDetails ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
}
type ParcelOrderDetails struct {
    gorm.Model
    ID            int           `json:"id"`
    BikerID       sql.NullInt32 `json:"biker_id"`
    ParcelOrderID int           `json:"parcel_order_id"`
    PickupTime    sql.NullTime  `json:"pickup_time"`
    DeliveryTime  sql.NullTime  `json:"delivery_time"`
    Status        int           `json:"status"`
    CreatedAt     time.Time     `json:"created_at"`
    UpdatedAt     time.Time     `json:"updated_at"`
    DeletedAt     sql.NullTime  `json:"deleted_at"`
}

我正在使用 Mysql DB,当我尝试创建订单时,它没有在第二个表上创建条目。 对于创建,我使用以下代码

order := ParcelOrder{
        DeliveryAddress: pickupdata.DeliveryAddress,
        PickupAddress:   pickupdata.PickupAddress,
        OrderID:         GetUniqueID(),
        SenderId:        userId,
        ParcelOrderDetails: ParcelOrderDetails{
            Status: 0,
        },
    }
connection.Create(&order)

另外,当我尝试从表中获取数据时,我收到如下错误

SELECT `parcel_orders`.`id`,`parcel_orders`.`created_at`,`parcel_orders`.`updated_at`,`parcel_orders`.`deleted_at`,`parcel_orders`.`sender_id`,`parcel_orders`.`order_id`,`parcel_orders`.`pickup_address`,`parcel_orders`.`delivery_address`,`ParcelOrderDetails`.`id` AS `ParcelOrderDetails__id`,`ParcelOrderDetails`.`created_at` AS `ParcelOrderDetails__created_at`,`ParcelOrderDetails`.`updated_at` AS `ParcelOrderDetails__updated_at`,`ParcelOrderDetails`.`deleted_at` AS `ParcelOrderDetails__deleted_at`,`ParcelOrderDetails`.`biker_id` AS `ParcelOrderDetails__biker_id`,`ParcelOrderDetails`.`parcel_order_id` AS `ParcelOrderDetails__parcel_order_id`,`ParcelOrderDetails`.`pickup_time` AS `ParcelOrderDetails__pickup_time`,`ParcelOrderDetails`.`delivery_time` AS `ParcelOrderDetails__delivery_time`,`ParcelOrderDetails`.`status` AS `ParcelOrderDetails__status` FROM `parcel_orders` ParcelOrder LEFT JOIN `parcel_order_details` `ParcelOrderDetails` ON `parcel_orders`.`id` = `ParcelOrderDetails`.`parcel_order_id` WHERE ParcelOrder.sender_id = 2

我的获取代码如下所示。提取问题很奇怪,因为别名被分配为ParcelOrder,所以没有用该名称标识的字段,而是仍然使用parcel_orders 实际表名

db.Joins("ParcelOrder").Joins("ParcelOrderDetails").Where("ParcelOrder.sender_id = ?", userId).Find(&order)

数据库不是用 Go 应用程序创建的,而是用 Laravel 应用程序创建的。我正在尝试向该数据库读取/写入数据。

有什么想法吗?

【问题讨论】:

    标签: mysql go go-gorm


    【解决方案1】:

    答案很简单,但很难理解。

    您只需要添加更改:

    ParcelOrderDetails ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
    

    进入

    ParcelOrderDetails *ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
    

    原因是ParcelOrderDetails 每次初始化ParcelOrder 时都会创建一个空模型(非空),当然在某些情况下我们不打算意外创建ParcelOrderOrderDetails,因为它是一个空模型,我想GORM 处理这种情况。

    所以如果你把它变成*ParcelOrderOrderDetails,默认是nil,这意味着GORM不会创建ParcelOrderOrderDetails,反之亦然。

    这是我的完整代码

    // https://stackoverflow.com/questions/69977516/unsupported-relations-for-schema-with-has-many-relation-in-gorm/70082006#70082006
    package main
    
    import (
        "database/sql"
        "fmt"
        "time"
    
        "gorm.io/driver/mysql"
        "gorm.io/gorm"
        "gorm.io/gorm/logger"
    )
    
    type ParcelOrder struct {
        gorm.Model
        ID                 int                `json:"id"`
        SenderId           uint               `json:"sender_id"`
        OrderID            string             `json:"order_id"`
        PickupAddress      string             `json:"pickup_address"`
        DeliveryAddress    string             `json:"delivery_address"`
        CreatedAt          time.Time          `json:"created_at"`
        UpdatedAt          time.Time          `json:"updated_at"`
        DeletedAt          sql.NullTime       `json:"deleted_at"`
        ParcelOrderDetails *ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
    }
    
    type ParcelOrderDetails struct {
        gorm.Model
        ID            int           `json:"id"`
        BikerID       sql.NullInt32 `json:"biker_id"`
        ParcelOrderID int           `json:"parcel_order_id"`
        PickupTime    sql.NullTime  `json:"pickup_time"`
        DeliveryTime  sql.NullTime  `json:"delivery_time"`
        Status        int           `json:"status"`
        CreatedAt     time.Time     `json:"created_at"`
        UpdatedAt     time.Time     `json:"updated_at"`
        DeletedAt     sql.NullTime  `json:"deleted_at"`
    }
    
    var DB *gorm.DB
    
    func main() {
        databaseConfig := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?multiStatements=true&parseTime=true", "root", "", "127.0.0.1", "3306", "tester")
    
        DB, _ = gorm.Open(mysql.Open(databaseConfig), &gorm.Config{
            Logger: logger.Default.LogMode(logger.Info),
        })
        sqlDB, _ := DB.DB()
        defer sqlDB.Close()
    
        DB.AutoMigrate(&ParcelOrder{}, &ParcelOrderDetails{})
    
        order := ParcelOrder{
            DeliveryAddress: "dummy address",
            PickupAddress:   "dummy pickup address",
            OrderID:         "unique-order-id-1",
            SenderId:        1,
            ParcelOrderDetails: &ParcelOrderDetails{
                Status: 0,
            },
        }
        DB.Create(&order)
    }
    
    

    日志记录:

    2021/11/23 20:57:53 D:/go/src/udemy-solving/00003/main.go:62
    [0.780ms] [rows:1] INSERT INTO `parcel_order_details` (`created_at`,`updated_at`,`deleted_at`,`biker_id`,`parcel_order_id`,`pickup_time`,`delivery_time`,`status`) VALUES ('2021-11-23 20:57:53.393','2021-11-23 20:57:53.393',NULL,NULL,4,NULL,NULL,0) ON DUPLICATE KEY UPDATE `parcel_order_id`=VALUES(`parcel_order_id`)
    
    2021/11/23 20:57:53 D:/go/src/udemy-solving/00003/main.go:62
    [14.900ms] [rows:1] INSERT INTO `parcel_orders` (`created_at`,`updated_at`,`deleted_at`,`sender_id`,`order_id`,`pickup_address`,`delivery_address`) VALUES ('2021-11-23 20:57:53.392','2021-11-23 20:57:53.392',NULL,1,'unique-order-id-1','dummy pickup address','dummy address')
    

    【讨论】:

      猜你喜欢
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 1970-01-01
      • 2018-05-03
      相关资源
      最近更新 更多