GORM 一对一映射问题
GORM One-to One mapping issue
我对 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 数据库,当我尝试创建订单时它没有在第二个 table 上创建条目。
为了创建,我使用以下代码
order := ParcelOrder{
DeliveryAddress: pickupdata.DeliveryAddress,
PickupAddress: pickupdata.PickupAddress,
OrderID: GetUniqueID(),
SenderId: userId,
ParcelOrderDetails: ParcelOrderDetails{
Status: 0,
},
}
connection.Create(&order)
此外,当我尝试从 table 中获取数据时,我收到如下错误
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
实际 table 名称
db.Joins("ParcelOrder").Joins("ParcelOrderDetails").Where("ParcelOrder.sender_id = ?", userId).Find(&order)
数据库不是使用 Go 应用程序创建的,而是使用 Laravel 应用程序创建的。我正在尝试 read/write 数据到该数据库。
有什么想法吗?
答案简单但难以理解。
您只需添加零钱:
ParcelOrderDetails ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
进入
ParcelOrderDetails *ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
原因是 ParcelOrderDetails
会在每次初始化 ParcelOrder
时创建一个空模型(非空),当然在某些情况下我们不打算意外创建 ParcelOrderOrderDetails
因为这是一个空模型,我认为 GORM 可以处理这种情况。
所以如果你把它变成*ParcelOrderOrderDetails
,默认情况下它将是nil
,这意味着GORM不会创建ParcelOrderOrderDetails
,反之亦然。
这是我的完整代码
//
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')
我对 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 数据库,当我尝试创建订单时它没有在第二个 table 上创建条目。 为了创建,我使用以下代码
order := ParcelOrder{
DeliveryAddress: pickupdata.DeliveryAddress,
PickupAddress: pickupdata.PickupAddress,
OrderID: GetUniqueID(),
SenderId: userId,
ParcelOrderDetails: ParcelOrderDetails{
Status: 0,
},
}
connection.Create(&order)
此外,当我尝试从 table 中获取数据时,我收到如下错误
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
实际 table 名称
db.Joins("ParcelOrder").Joins("ParcelOrderDetails").Where("ParcelOrder.sender_id = ?", userId).Find(&order)
数据库不是使用 Go 应用程序创建的,而是使用 Laravel 应用程序创建的。我正在尝试 read/write 数据到该数据库。
有什么想法吗?
答案简单但难以理解。
您只需添加零钱:
ParcelOrderDetails ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
进入
ParcelOrderDetails *ParcelOrderDetails `gorm:"foreignKey:ParcelOrderID"`
原因是 ParcelOrderDetails
会在每次初始化 ParcelOrder
时创建一个空模型(非空),当然在某些情况下我们不打算意外创建 ParcelOrderOrderDetails
因为这是一个空模型,我认为 GORM 可以处理这种情况。
所以如果你把它变成*ParcelOrderOrderDetails
,默认情况下它将是nil
,这意味着GORM不会创建ParcelOrderOrderDetails
,反之亦然。
这是我的完整代码
//
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')