You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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等字段和自定义字段重名,且没有正确映射到数据库的下划线列,因此出现冗余空字段。

正确配置方案

  1. 调整结构体字段类型和标签,不要嵌入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"`
}
  1. 调整创建逻辑,去掉不必要的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:18:09