go-gorm-model

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Go GORM Model

Go GORM 模型

Generate GORM persistence models in
internal/modules/<module>/model/
.
internal/modules/<module>/model/
目录下生成GORM持久化模型。

Pattern

命名与路径规则

Model files must follow this location and naming:
  • Path:
    internal/modules/<module>/model/<entity>_model.go
  • Package:
    model
  • Struct name:
    <Entity>Model
  • TableName method:
    • func (*<Entity>Model) TableName() string { return "<table_name>" }
模型文件必须遵循以下路径和命名规则:
  • 路径:
    internal/modules/<module>/model/<entity>_model.go
  • 包名:
    model
  • 结构体名称:
    <Entity>Model
  • TableName方法:
    • func (*<Entity>Model) TableName() string { return "<table_name>" }

File Structure

文件结构

Use this order:
  1. package model
  2. Imports (
    time
    ,
    database/sql
    only when needed)
  3. Struct definition
  4. TableName()
    method
遵循以下顺序:
  1. package model
  2. 导入语句(仅在需要时导入
    time
    database/sql
  3. 结构体定义
  4. TableName()
    方法

Base Template

基础模板

go
package model

import (
	"database/sql"
	"time"
)

type EntityModel struct {
	ID        uint64         `gorm:"primarykey"`
	Name      string         `gorm:"column:name"`
	Meta      sql.NullString `gorm:"column:meta"`
	CreatedAt time.Time      `gorm:"column:created_at"`
	UpdatedAt time.Time      `gorm:"column:updated_at"`
}

func (*EntityModel) TableName() string {
	return "entities"
}
If a field name matches GORM defaults and project style keeps it untagged, omit explicit
gorm:"column:..."
.
go
package model

import (
	"database/sql"
	"time"
)

type EntityModel struct {
	ID        uint64         `gorm:"primarykey"`
	Name      string         `gorm:"column:name"`
	Meta      sql.NullString `gorm:"column:meta"`
	CreatedAt time.Time      `gorm:"column:created_at"`
	UpdatedAt time.Time      `gorm:"column:updated_at"`
}

func (*EntityModel) TableName() string {
	return "entities"
}
如果字段名称符合GORM默认规则且项目风格要求不添加标签,则省略显式的
gorm:"column:..."
标签。

Conventions from Current Codebase

当前代码库的约定

IDs and Primary Keys

ID与主键

  • Use
    uint64
    for numeric IDs.
  • Set primary key as:
    • ID uint64 `gorm:"primarykey"` 
  • 使用
    uint64
    作为数值类型ID。
  • 设置主键为:
    • ID uint64 `gorm:"primarykey"` 

Time fields

时间字段

  • Use
    time.Time
    for required timestamps.
  • Common fields:
    • CreatedAt time.Time
    • UpdatedAt time.Time
  • Use explicit column tags for snake_case DB columns when needed.
  • 使用
    time.Time
    作为必填时间戳类型。
  • 常见字段:
    • CreatedAt time.Time
    • UpdatedAt time.Time
  • 当需要时,为蛇形命名的数据库列添加显式列标签。

Nullable database fields

可空数据库字段

Use
database/sql
nullable types when DB column can be null:
  • sql.NullString
  • sql.NullInt32
  • sql.NullBool
  • sql.NullTime
Examples in this repo:
  • Nonce sql.NullString
  • StatusCode sql.NullInt32
  • ResponseTimeMs sql.NullInt32
当数据库列可为空时,使用
database/sql
包中的可空类型:
  • sql.NullString
  • sql.NullInt32
  • sql.NullBool
  • sql.NullTime
本仓库中的示例:
  • Nonce sql.NullString
  • StatusCode sql.NullInt32
  • ResponseTimeMs sql.NullInt32

Column tags

列标签

Use explicit tags when any of these apply:
  • DB column differs from Go field naming
  • You want consistency with existing model files
  • Composite or relation keys need explicit mapping
Pattern:
  • Field string `gorm:"column:field_name"` 
在以下任一情况下使用显式标签:
  • 数据库列名与Go字段名不同
  • 希望与现有模型文件保持一致性
  • 复合键或关联键需要显式映射
格式:
  • Field string `gorm:"column:field_name"` 

Table name mapping

表名映射

Always implement
TableName()
and return the exact SQL table name.
Examples:
  • authorization_codes
  • external_accounts
  • http_monitor_checks
  • contacts
必须实现
TableName()
方法并返回精确的SQL表名。
示例:
  • authorization_codes
  • external_accounts
  • http_monitor_checks
  • contacts

Generation Steps

生成步骤

  1. Identify module and entity.
  2. Open migration/schema and confirm table + columns.
  3. Create or update
    internal/modules/<module>/model/<entity>_model.go
    .
  4. Define struct fields with correct Go and nullable SQL types.
  5. Add
    gorm
    tags (
    primarykey
    ,
    column:...
    ) where needed.
  6. Add
    TableName()
    with exact table name.
  7. Ensure naming aligns with repository/usecase expectations.
  8. Run
    make test
    and
    make lint
    .
  1. 确定模块和实体。
  2. 打开迁移文件/架构并确认表和列。
  3. 创建或更新
    internal/modules/<module>/model/<entity>_model.go
    文件。
  4. 使用正确的Go类型和可空SQL类型定义结构体字段。
  5. 在需要的地方添加
    gorm
    标签(
    primarykey
    column:...
    )。
  6. 添加返回精确表名的
    TableName()
    方法。
  7. 确保命名与仓库/用例的预期一致。
  8. 运行
    make test
    make lint

Type Mapping Guide

类型映射指南

Use these defaults unless migration requires otherwise:
  • BIGINT/UNSIGNED BIGINT
    ->
    uint64
  • VARCHAR/TEXT
    ->
    string
  • BOOLEAN
    ->
    bool
  • TIMESTAMP/DATETIME
    ->
    time.Time
  • nullable string/int/time ->
    sql.NullString
    /
    sql.NullInt32
    /
    sql.NullTime
  • binary hash columns ->
    []byte
除非迁移文件有特殊要求,否则使用以下默认映射:
  • BIGINT/UNSIGNED BIGINT
    ->
    uint64
  • VARCHAR/TEXT
    ->
    string
  • BOOLEAN
    ->
    bool
  • TIMESTAMP/DATETIME
    ->
    time.Time
  • 可空字符串/整数/时间 ->
    sql.NullString
    /
    sql.NullInt32
    /
    sql.NullTime
  • 二进制哈希列 ->
    []byte

Example: Identity-style Model

示例:Identity风格模型

go
type AuthorizationCodeModel struct {
	ID                  uint64         `gorm:"primarykey"`
	CodeHash            []byte         `gorm:"column:code_hash"`
	UserID              uint64         `gorm:"column:user_id"`
	ClientID            string         `gorm:"column:client_id"`
	RedirectURI         string         `gorm:"column:redirect_uri"`
	Scope               string         `gorm:"column:scope"`
	CodeChallenge       string         `gorm:"column:code_challenge"`
	CodeChallengeMethod string         `gorm:"column:code_challenge_method;default:S256"`
	Nonce               sql.NullString `gorm:"column:nonce"`
	ExpiresAt           time.Time      `gorm:"column:expires_at"`
	CreatedAt           time.Time      `gorm:"column:created_at"`
}
go
type AuthorizationCodeModel struct {
	ID                  uint64         `gorm:"primarykey"`
	CodeHash            []byte         `gorm:"column:code_hash"`
	UserID              uint64         `gorm:"column:user_id"`
	ClientID            string         `gorm:"column:client_id"`
	RedirectURI         string         `gorm:"column:redirect_uri"`
	Scope               string         `gorm:"column:scope"`
	CodeChallenge       string         `gorm:"column:code_challenge"`
	CodeChallengeMethod string         `gorm:"column:code_challenge_method;default:S256"`
	Nonce               sql.NullString `gorm:"column:nonce"`
	ExpiresAt           time.Time      `gorm:"column:expires_at"`
	CreatedAt           time.Time      `gorm:"column:created_at"`
}

Example: Monitor-style Model

示例:Monitor风格模型

go
type HTTPMonitorCheckModel struct {
	ID             uint64         `gorm:"primarykey"`
	HTTPMonitorID  uint64         `gorm:"column:http_monitor_id"`
	CheckedAt      time.Time      `gorm:"column:checked_at"`
	ResponseTimeMs sql.NullInt32  `gorm:"column:response_time_ms"`
	StatusCode     sql.NullInt32  `gorm:"column:status_code"`
	Success        bool           `gorm:"column:success"`
	ErrorMessage   sql.NullString `gorm:"column:error_message"`
}
go
type HTTPMonitorCheckModel struct {
	ID             uint64         `gorm:"primarykey"`
	HTTPMonitorID  uint64         `gorm:"column:http_monitor_id"`
	CheckedAt      time.Time      `gorm:"column:checked_at"`
	ResponseTimeMs sql.NullInt32  `gorm:"column:response_time_ms"`
	StatusCode     sql.NullInt32  `gorm:"column:status_code"`
	Success        bool           `gorm:"column:success"`
	ErrorMessage   sql.NullString `gorm:"column:error_message"`
}

Critical Rules

关键规则

  • Models are persistence only; business logic belongs in usecases.
  • Do not expose GORM models directly in HTTP DTO responses.
  • Keep field names and types aligned with SQL migrations.
  • Do not change existing column/table names without migration updates.
  • Use module-local model package only (
    internal/modules/<module>/model
    ).
  • Never use
    json
    tags on GORM models.
  • 模型仅用于持久化;业务逻辑应放在用例层。
  • 不要在HTTP DTO响应中直接暴露GORM模型。
  • 保持字段名称和类型与SQL迁移文件一致。
  • 不要在未更新迁移文件的情况下修改现有列/表名称。
  • 仅使用模块本地的model包(
    internal/modules/<module>/model
    )。
  • 永远不要在GORM模型上使用
    json
    标签。

Checklist

检查清单

  • File created in
    internal/modules/<module>/model/
  • Struct named
    <Entity>Model
  • ID uint64
    with
    gorm:"primarykey"
  • Nullable columns mapped with
    database/sql
    nullable types
  • Timestamp fields typed correctly
  • TableName()
    added with exact table name
  • Tags and naming consistent with existing module style
  • make test
    and
    make lint
    executed
  • 文件已创建在
    internal/modules/<module>/model/
    目录下
  • 结构体命名为
    <Entity>Model
  • 包含
    ID uint64
    字段并带有
    gorm:"primarykey"
    标签
  • 可空列已映射为
    database/sql
    包中的可空类型
  • 时间戳字段类型正确
  • 已添加返回精确表名的
    TableName()
    方法
  • 标签和命名与现有模块风格一致
  • 已执行
    make test
    make lint