ID
as Primary Key
GORM uses the field with the name ID
as the table’s primary key by default.
type User struct {
ID string // field named `ID` will be used as a primary field by default
Name string
}
You can set other fields as primary key with tag primaryKey
// Set field `UUID` as primary field
type Animal struct {
ID int64
UUID string `gorm:"primaryKey"`
Name string
Age int64
}
Also check out Composite Primary Key
Pluralized Table Name
GORM pluralizes struct name to snake_cases
as table name, for struct User
, its table name is users
by convention
TableName
You can change the default table name by implementing the Tabler
interface, for example:
type Tabler interface {
TableName() string
}
// TableName overrides the table name used by User to `profiles`
func (User) TableName() string {
return "profiles"
}
NOTE
TableName
doesn’t allow dynamic name, its result will be cached for future, to use dynamic name, you can useScopes
, for example:
func UserTable(user User) func (tx *gorm.DB) *gorm.DB {
return func (tx *gorm.DB) *gorm.DB {
if user.Admin {
return tx.Table("admin_users")
}
return tx.Table("users")
}
}
db.Scopes(UserTable(user)).Create(&user)
Temporarily specify a name
Temporarily specify table name with Table
method, for example:
// Create table `deleted_users` with struct User's fields
db.Table("deleted_users").AutoMigrate(&User{})
// Query data from another table
var deletedUsers []User
db.Table("deleted_users").Find(&deletedUsers)
// SELECT * FROM deleted_users;
db.Table("deleted_users").Where("name = ?", "jinzhu").Delete(&User{})
// DELETE FROM deleted_users WHERE name = 'jinzhu';
Check out From SubQuery for how to use SubQuery in FROM clause
NamingStrategy
GORM allows users change the default naming conventions by overriding the default NamingStrategy
, which is used to build TableName
, ColumnName
, JoinTableName
, RelationshipFKName
, CheckerName
, IndexName
, Check out GORM Config for details
Column Name
Column db name uses the field’s name’s snake_case
by convention.
type User struct {
ID uint // column name is `id`
Name string // column name is `name`
Birthday time.Time // column name is `birthday`
CreatedAt time.Time // column name is `created_at`
}
You can override the column name with tag column
or use NamingStrategy
type Animal struct {
AnimalID int64 `gorm:"column:beast_id"` // set name to `beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"` // set name to `day_of_the_beast`
Age int64 `gorm:"column:age_of_the_beast"` // set name to `age_of_the_beast`
}
Timestamp Tracking
CreatedAt
For models having CreatedAt
field, the field will be set to the current time when the record is first created if its value is zero
db.Create(&user) // set `CreatedAt` to current time
user2 := User{Name: "jinzhu", CreatedAt: time.Now()}
db.Create(&user2) // user2's `CreatedAt` won't be changed
// To change its value, you could use `Update`
db.Model(&user).Update("CreatedAt", time.Now())
You can disable the timestamp tracking by setting autoCreateTime
tag to false
, for example:
type User struct {
CreatedAt time.Time `gorm:"autoCreateTime:false"`
}
UpdatedAt
For models having UpdatedAt
field, the field will be set to the current time when the record is updated or created if its value is zero
db.Save(&user) // set `UpdatedAt` to current time
db.Model(&user).Update("name", "jinzhu") // will set `UpdatedAt` to current time
db.Model(&user).UpdateColumn("name", "jinzhu") // `UpdatedAt` won't be changed
user2 := User{Name: "jinzhu", UpdatedAt: time.Now()}
db.Create(&user2) // user2's `UpdatedAt` won't be changed when creating
user3 := User{Name: "jinzhu", UpdatedAt: time.Now()}
db.Save(&user3) // user3's `UpdatedAt` will change to current time when updating
You can disable the timestamp tracking by setting autoUpdateTime
tag to false
, for example:
type User struct {
UpdatedAt time.Time `gorm:"autoUpdateTime:false"`
}
NOTE GORM supports having multiple time tracking fields and track with UNIX (nano/milli) seconds, checkout Models for more details