временной столбец в sqlite с помощью gorm - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь запросить объекты из sqlite, но получаю эту ошибку из-за типа time:

(sql: Scan error on column index 1: unsupported Scan, storing driver.Value type []uint8 into type *time.Time)

Моя структура:

type Timeline struct {
ID        string     `json:"id"`
Timestamp *time.Time `json:"timestamp"`

и моя база данных выглядит так:

CREATE TABLE timelines (id text, timestamp text, ...

и одна из строк образца:

('Locked in VR', '2018-03-17 10:50:59.548+01:00',...

есть идеи? я должен иметь что-то в структуре, как?

Timestamp *time.Time `json:"timestamp" gorm:"time"`

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Использование этого позаботится об этом:

type Timeline struct {
    ID        string     `json:"id"`
    Timestamp *time.Time `json:"timestamp" gorm:"type:datetime"`
}

Вы могли бы даже изменить объявленный тип поля Timestamp на что-то другое, скажем, int64 для представления времени Unix. Затем вы можете написать сканер для чтения поля даты и времени в поле int64.

type TimeStampUnix int64
type Timeline struct {
    ID        string        `json:"id"`
    TimeStamp TimeStampUnix `json:"timestamp" gorm:"type:datetime"`
}

func (t *TimeStampUnix) Scan(src interface{}) error {
    switch src.(type) {
    case time.Time:
        *t = TimeStampUnix(src.(time.Time).Unix())
        return nil
    case []byte:
        // bonus code to read text field of format '2014-12-31 14:21:01-0400'
        //
        str := string(src.([]byte))
        var y, m, d, hr, min, s, tzh, tzm int
        var sign rune
        _, e := fmt.Sscanf(str, "%d-%d-%d %d:%d:%d%c%d:%d",
            &y, &m, &d, &hr, &min, &s, &sign, &tzh, &tzm)
        if e != nil {
            return e
        }

        offset := 60 * (tzh*60 + tzm)
        if sign == '-' {
            offset = -1 * offset
        }

        loc := time.FixedZone("local-tz", offset)
        t1 := time.Date(y, time.Month(m), d, hr, min, s, 0, loc)
        *t = TimeStampUnix(t1.Unix())
        return nil
    default:
        return fmt.Errorf("Value '%s' of incompatible type '%T' found", string(src.([]byte)), src)
    }
}
0 голосов
/ 09 мая 2018

Я не знаком с gorm, но не следует ли определять временную метку типа datetime вместо text? Также: когда вы помечаете gorm:"time" имя столбца должно быть time, а не timestamp или тег gorm:"timestamp". Но вы можете оставить тег gorm.

Для простоты вы можете позволить gorm создать таблицу:

db, err := gorm.Open("sqlite3", "test.db")
db.CreateTable(&Timeline{})
...