Search code examples
mysqlgo-gorm

How to use the type "time" from the database in GORM?


In my structure I have a field like this:

type model struct {
    gorm.Model
    Time *time.Time `gorm:"type:time"`
}

It turns out that from what I could see, GORM uses the time type of Go itself and not the time type of the database, which was my intention.

This generates the following sql using the Debug() function:

CREATE TABLE `models` (`time` datetime(3) NULL)

And not:

CREATE TABLE `models` (`time` time NULL)

Want was what I expected.

How to make it work?

Even reading the documentation and other forums, everything I've tried has been useless.


Solution

  • This is the default behaviour of GORM database type mapping.

    In GORM, the time in type:"time" is treating as a keyword to set the default database column type as datetime for mysql or timestamptz for postgresql.

    the schema

    // GORM fields types
    const (
        ....
        Time   DataType = "time"
        Bytes  DataType = "bytes"
    )
    

    for MYSQL

    case schema.Time: 
            return dialector.getSchemaTimeType(field)
    
    func (dialector Dialector) getSchemaTimeType(field *schema.Field) string {
        .... 
    
        if field.NotNull || field.PrimaryKey {
            return "datetime" + precision
        }
        return "datetime" + precision + " NULL"
    }
    

    for POSTGRES

    ....
    
    case schema.Time:
            if field.Precision > 0 {
                return fmt.Sprintf("timestamptz(%d)", field.Precision)
            }
    

    Solution to set it as time

    You can use the customisation approach provided by GORM.

    GORM will read column’s database type from tag type, if not found, will check if the struct implemented interface GormDBDataTypeInterface or GormDataTypeInterface and will use its result as data type

    here is the snippet

    type model struct {
        gorm.Model
        Time CustomTime
    }
    
    type CustomTime struct {
        time.Time
    }
    
    func (CustomTime) GormDataType() string {
        return "time"
    }
    
    func (CustomTime) GormDBDataType(db *gorm.DB, field *schema.Field) string {
        return "time"
    }
    

    References :