GORM创建PostgreSQL记录后如何返回数据库自动生成字段
GORM创建记录后无法获取数据库自动生成字段问题解决
问题复现
编写用户创建函数时,创建成功后无法获取数据库自动生成的id、created_at字段值,初始代码如下:
type User struct { Id string `json:"id" gorm:"primaryKey"` Email string `json:"email"` Password string `json:"password"` Created_At string `json:"created_at"` Updated_At string `json:"updated_at"` Deleted_At string `json:"deleted_at"` } type UserRequest struct { Email string `json:"email"` Password string `json:"password"` } func CreateUserRepo(newUser UserRequest) (*User, error) { user := User{Email: newUser.Email, Password: newUser.Password} fmt.Println(user) result := services.PostgresSQLDB.Select("Email", "Password").Create(&user) fmt.Println(result.RowsAffected) if result.Error != nil { modules.Logger.Error(result.Error) return nil, result.Error } return &user, nil }
接口返回的结构体中自动生成字段均为空字符串:
{ "id": "", "email": "test@test.com", "password": "password", "created_at": "", "updated_at": "", "deleted_at": "" }
测试嵌入gorm.Model后,可以拿到数据库生成的UUID,但会出现大量重复冗余字段(大写开头的ID、CreatedAt、UpdatedAt、DeletedAt和自定义的小写下划线字段同时存在),对应代码和返回如下:
type User struct { gorm.Model Id uuid.UUID `json:"id"` Email string `json:"email"` Password string `json:"password"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt gorm.DeletedAt `json:"deleted_at"` }
{ "ID": 0, "CreatedAt": "0001-01-01T00:00:00Z", "UpdatedAt": "0001-01-01T00:00:00Z", "DeletedAt": null, "id": "b4dea226-3be2-4ee7-8548-67ccbbbcbcca", "email": "test@test.com", "password": "password", "created_at": "2022-06-25T20:59:27.872198797+01:00", "updated_at": "2022-06-25T20:59:27.872198797+01:00", "deleted_at": null }
使用的PostgreSQL表结构如下:
-- CreateTable CREATE TABLE "users" ( "id" UUID NOT NULL DEFAULT gen_random_uuid(), "email" TEXT NOT NULL, "password" TEXT, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, "deleted_at" TIMESTAMP(3), CONSTRAINT "users_pkey" PRIMARY KEY ("id") );
问题原因
问题由三个配置错误导致:
- 字段类型与GORM映射规则不匹配:id是UUID类型、时间字段是timestamp类型,用string类型无法接收数据库返回的值;自定义字段用
Created_At这类下划线命名不符合GORM默认的大驼峰转下划线映射规则,导致字段无法正确关联。 - Create时使用
Select("Email", "Password")限制了操作字段,GORM只会插入和回填指定的两个字段,不会主动读取其他数据库自动生成的字段值。 - 嵌入
gorm.Model时,其内置的ID、CreatedAt等字段和自定义字段重名,且没有正确映射到数据库的下划线列,因此出现冗余空字段。
正确配置方案
- 调整结构体字段类型和标签,不要嵌入
gorm.Model,按照数据库字段类型匹配对应Go类型,遵循GORM大驼峰字段命名规则:
import ( "time" "github.com/google/uuid" "gorm.io/gorm" ) type User struct { Id uuid.UUID `json:"id" gorm:"type:uuid;primaryKey;default:gen_random_uuid()"` Email string `json:"email" gorm:"type:text;not null"` Password string `json:"password" gorm:"type:text"` CreatedAt time.Time `json:"created_at" gorm:"type:timestamp(3);not null;default:CURRENT_TIMESTAMP"` UpdatedAt time.Time `json:"updated_at" gorm:"type:timestamp(3);not null"` DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"type:timestamp(3);index"` }
- 调整创建逻辑,去掉不必要的Select字段限制,GORM创建成功后会自动回填所有数据库生成的字段值:
func CreateUserRepo(newUser UserRequest) (*User, error) { user := User{Email: newUser.Email, Password: newUser.Password} result := services.PostgresSQLDB.Create(&user) if result.Error != nil { modules.Logger.Error(result.Error) return nil, result.Error } return &user, nil }
调整后接口返回无冗余字段,所有自动生成的值均可正常获取:
{ "id": "b4dea226-3be2-4ee7-8548-67ccbbbcbcca", "email": "test@test.com", "password": "password", "created_at": "2022-06-25T20:59:27.872+08:00", "updated_at": "2022-06-25T20:59:27.872+08:00", "deleted_at": null }
内容的提问来源于stack exchange,提问作者Kay
相关产品推荐
相关产品推荐

