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

使用Gorm操作SQLite时time字段扫描报错的解决方案咨询

Fixing "unsupported Scan, storing driver.Value type []uint8 into type *time.Time" in Gorm + SQLite

Let's break down why this error pops up and how to fix it properly:
SQLite doesn't have a native time/datetime type—you're storing your timestamp as a text field with a formatted string (2018-03-17 10:50:59.548+01:00), but Gorm can't automatically convert the raw byte array ([]uint8) returned by SQLite into a *time.Time value out of the box. The gorm:"time" tag you tried won't work here because that's designed for SQL-standard TIME type fields, not SQLite's TEXT-stored timestamps.

Here are the most reliable solutions:

This is the most flexible approach—define a custom time type that handles parsing your exact timestamp format during reads, and formatting it correctly during writes.

First, create a custom type wrapping *time.Time:

import (
    "database/sql/driver"
    "fmt"
    "time"
)

type CustomTime struct {
    *time.Time
}

// Scan parses the raw database value into our CustomTime
func (ct *CustomTime) Scan(value interface{}) error {
    if value == nil {
        ct.Time = nil
        return nil
    }

    byteVal, ok := value.([]uint8)
    if !ok {
        return fmt.Errorf("expected []uint8 for timestamp, got %T", value)
    }

    timeStr := string(byteVal)
    // Match your exact timestamp format: YYYY-MM-DD HH:MM:SS.sss±ZZZZ
    parsedTime, err := time.Parse("2006-01-02 15:04:05.000-07:00", timeStr)
    if err != nil {
        return fmt.Errorf("failed to parse timestamp: %w", err)
    }

    ct.Time = &parsedTime
    return nil
}

// Value converts our CustomTime back to a string for storage
func (ct CustomTime) Value() (driver.Value, error) {
    if ct.Time == nil {
        return nil, nil
    }
    // Use the same format for consistent storage
    return ct.Time.Format("2006-01-02 15:04:05.000-07:00"), nil
}

Then update your struct to use this custom type:

type Timeline struct {
    ID        string     `json:"id"`
    Timestamp CustomTime `json:"timestamp" gorm:"type:text"`
}

This will handle both reading from and writing to the text timestamp field seamlessly.

2. Use Gorm Callbacks (Alternative)

If you don't want to create a custom type, you can register a Gorm callback to parse the timestamp after querying:

func init() {
    // Register a post-query callback for the timelines table
    gorm.DefaultCallback.Query().After("gorm:query").Register("parse_timeline_timestamp", func(db *gorm.DB) {
        if db.Error != nil {
            return
        }

        var results []Timeline
        if err := db.Result().Scan(&results); err != nil {
            db.Error = err
            return
        }

        // Parse each timestamp string into *time.Time
        for i := range results {
            if results[i].Timestamp == nil {
                // Extract the timestamp string from the row (adjust based on your query)
                var timeStr string
                if err := db.Row().Scan(&results[i].ID, &timeStr); err == nil {
                    parsedTime, err := time.Parse("2006-01-02 15:04:05.000-07:00", timeStr)
                    if err == nil {
                        results[i].Timestamp = &parsedTime
                    }
                }
            }
        }

        db.Result().SetRows(results)
    })
}

Note: This approach is more cumbersome and less maintainable than using a custom type, so it's only recommended if you can't modify the struct type.

3. Adjust the Database Field Type (If Feasible)

While SQLite doesn't have a native datetime type, you can alter the field to use DATETIME (SQLite will still store it as text under the hood, but Gorm will recognize it and attempt automatic parsing):

ALTER TABLE timelines ALTER COLUMN timestamp TYPE DATETIME;

Then update your struct with the appropriate Gorm tag:

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

This works for most standard datetime formats, but it's less reliable than the custom type approach if you have a non-standard timestamp format.


内容的提问来源于stack exchange,提问作者tiagodll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:44:19