如何用GORM+Postgres存储值数组?迁移多对多模型遇错求助
GORM多对多关系迁移PostgreSQL时的唯一约束错误解决
问题重现
参考GORM多对多相关文档编写代码后,运行迁移触发如下错误:
go/src/testpostgres/main.go:25 ERROR: there is no unique constraint matching given keys for referenced table "users" (SQLSTATE 42830) [4.951ms] [rows:0] CREATE TABLE "user_languages" ("user_id" bigint,"language_id" bigint,PRIMARY KEY ("user_id","language_id"),CONSTRAINT "fk_user_languages_user" FOREIGN KEY ("user_id") REFERENCES "users"("id"),CONSTRAINT "fk_user_languages_language" FOREIGN KEY ("language_id") REFERENCES "languages"("id")) panic: error while trying to migrate models: ERROR: there is no unique constraint matching given keys for referenced table "users" (SQLSTATE 42830)
用到的代码如下:
main.go
package main import ( "fmt" "gorm.io/driver/postgres" "gorm.io/gorm" ) type User struct { gorm.Model Languages []Language `gorm:"many2many:user_languages;"` } type Language struct { gorm.Model Name string } func main() { dsn := "host=localhost user=postgres password=asdf dbname=postgres port=5432" db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) check("connect to db", err) err = db.AutoMigrate(&User{}, &Language{}) check("migrate models", err) } func check(task string, err error) { if err != nil { panic(fmt.Sprintf("error during %v: %v", task, err.Error())) } }
go.mod
module testpostgres go 1.21.1 require ( gorm.io/driver/postgres v1.5.2 gorm.io/gorm v1.25.4 ) // ** + indirect requirements ** //
解决方案
错误核心是PostgreSQL无法找到users表中id字段的唯一约束(主键约束属于唯一约束的一种),可通过以下方式解决:
重置测试数据库表
若为测试环境,直接删除已存在的关联表,让GORM重新生成带正确约束的表:DROP TABLE IF EXISTS user_languages; DROP TABLE IF EXISTS users; DROP TABLE IF EXISTS languages;执行完后重新运行
go run main.go即可。手动添加主键约束
若无法删除表,直接通过SQL为users表的id字段补全主键约束:ALTER TABLE users ADD PRIMARY KEY (id);完成后再次运行迁移代码即可。
显式声明主键字段
若AutoMigrate自动生成的约束存在异常,可在结构体中显式声明主键,避免逻辑歧义:type User struct { ID uint `gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` Languages []Language `gorm:"many2many:user_languages;"` }
内容的提问来源于stack exchange,提问作者frizzkitten
相关产品推荐
相关产品推荐

