当未嵌入`gorm.Model`时,GORM会发生恐慌。

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

GORM panics when `gorm.Model` not embedded

问题

这是我的模型。请注意,我不想将gorm.Model嵌入到我的结构体中。

type Order struct {
    OrderID   uint64     `gorm:"column:order_id" gorm:"primaryKey" gorm:"unique"`
    Cart      Cart       `gorm:"foreignKey:UserID"`
    CreatedBy UserID     `gorm:"index"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time
}

type Category struct {
    ID        uint64     `gorm:"column:category_id" gorm:"primaryKey" gorm:"unique"`
    Name      string     `gorm:"index"`
    Image     string     
    Products  []Product  `gorm:"foreignKey:product_id" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
    CreatedBy UserID     `gorm:"index" gorm:"type:bytea"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

type Cart struct {
    UserID    UserID     `gorm:"column:user_id" gorm:"primaryKey"`
    Products  []Product  `gorm:"foreignKey:ID"`
    Price     float64   
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

type Product struct {
    ID        uint64     `gorm:"column:product_id" gorm:"primaryKey" gorm:"unique"`
    Name      string     `gorm:"index"`
    Price     float64    `gorm:"index"`
    Rating    uint       `gorm:"index"`
    Image     string     
    CreatedBy UserID     `gorm:"index" gorm:"type:bytea"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

当我使用AutoMigrate时,我得到以下错误:

[error] invalid field found for struct moonspace/model.Cart's field Products: define a valid foreign key for relations or implement the Valuer/Scanner interface

我尝试将foreignKey:UserID更改为foreignKey:user_id,但错误仍然存在。

这是我的自动迁移代码:

func createPostgresCLI(cfg types.Config, config ...any) *gorm.DB {
    db, err := gorm.Open(postgres.Open(cfg.Url))
    if err != nil {
        panic(err)
    }

    err = db.AutoMigrate(&model.Order{}, &model.Cart{}, &model.Category{}, &model.Product{})
    if err != nil {
        panic(fmt.Errorf("Error creating database: %w", err))
    }

    return db
}

我做错了什么?
另外,当我使用gorm.Model并尝试将Product插入到Category时,我遇到了外键约束错误。我正在尝试通过关联添加它。

英文:

This is my model. Note that I don't want to embed gorm.Model into my structs.

type Order struct {
    OrderID   uint64     `gorm:"column:order_id" gorm:"primaryKey" gorm:"unique"`
    Cart      Cart       `gorm:"foreignKey:UserID"`
    CreatedBy UserID     `gorm:"index"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time
}

type Category struct {
    ID        uint64     `gorm:"column:category_id" gorm:"primaryKey" gorm:"unique"`
    Name      string     `gorm:"index"`
    Image     string     
    Products  []Product  `gorm:"foreignKey:product_id" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
    CreatedBy UserID     `gorm:"index" gorm:"type:bytea"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

type Cart struct {
	UserID    UserID     `gorm:"column:user_id" gorm:"primaryKey"`
	Products  []Product  `gorm:"foreignKey:ID"`
	Price     float64   
	CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
	UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
	DeletedAt *time.Time 
}

type Product struct {
	ID        uint64     `gorm:"column:product_id" gorm:"primaryKey" gorm:"unique"`
	Name      string     `gorm:"index"`
	Price     float64    `gorm:"index"`
	Rating    uint       `gorm:"index"`
	Image     string     
	CreatedBy UserID     `gorm:"index" gorm:"type:bytea"`
	CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
	UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
	DeletedAt *time.Time 
}

When I use AutoMigrate, I get the following errors:

[error] invalid field found for struct moonspace/model.Cart's field Products: define a valid foreign key for relations or implement the Valuer/Scanner interface

I have tried changing the foreignKey:UserID to foreignKey:user_id but the error remains the same.

Here is my auto-migrate:

func createPostgresCLI(cfg types.Config, config ...any) *gorm.DB {
	db, err := gorm.Open(postgres.Open(cfg.Url))
	if err != nil {
		panic(err)
	}

	err = db.AutoMigrate(&model.Order{}, &model.Cart{}, &model.Category{}, &model.Product{})
	if err != nil {
		panic(fmt.Errorf("Error creating database: %w", err))
	}

	return db
}

What am I doing wrong?
Also, when I use gorm.Model, and when I try to insert a Product into a Category, I'm getting a foreign key constraint error. I'm trying to add it through associations.

答案1

得分: 1

// Category <===> Product: 外键列需要包含在Product中,引用Category ID。当前配置在工作时会使用Category ID更新Product ID,这是错误的。

type Category struct {
	ID       uint64    `gorm:"column:category_id;primaryKey"`
	Products []Product `gorm:"foreignKey:CategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
	// ...
}

type Product struct {
	ID         uint64 `gorm:"column:product_id;primaryKey;unique"`
	CategoryID uint64 // 新字段,用于保存Category ID。
	// ...
}

// Cart <===> Product: 关系可以建模为many2many,使用一个关联表存储产品和购物车的ID,这里可能不需要外键。

type Cart struct {
	CartID   uint64    `gorm:"primaryKey"`
	Products []Product `gorm:"many2many:cart_products"`
	// ...
}

// 另外,你可以将所有的gorm标签合并为一个,不需要重复。
英文:

Category <==> Product: foreign key column needs to be included in Product which will reference Category ID. CUrrent config when working will update product ID with category ID, which will be wrong

type Category struct {
	ID       uint64 `gorm:&quot;column:category_id;primaryKey&quot;`
    Products  []Product  `gorm:&quot;foreignKey:CategoryID&quot; gorm:&quot;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;&quot;`
    ....
}

type Product struct {
    ID        uint64     `gorm:&quot;column:product_id&quot; gorm:&quot;primaryKey&quot; gorm:&quot;unique&quot;`
    CategoryID uint64 // New field to hold category ID.
    ....
}

Cart <===> Product relation can be modelled as many2many with a join table to store products' and carts' IDs, might not need foreign key here.

type Cart struct {
	CartID   uint64 `gorm:&quot;primaryKey&quot;`
	Products []Product `gorm:&quot;many2many:cart_products&quot;`
    ....
}

Also You can use combine all gorm tags into one, no need for repeating.

huangapple
  • 本文由 发表于 2022年10月31日 05:48:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/74257010.html
匿名

发表评论

匿名网友

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

确定