卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34854本站已运行393

Go错误:time.Time未实现driver.Valuer(缺少方法Value)

go错误:time.time未实现driver.valuer(缺少方法value)

php小编子墨在使用Go语言开发过程中,可能会遇到一个常见的错误:“Go错误:time.Time未实现driver.Valuer(缺少方法Value)”。这个错误通常在将time.Time类型的值存储到数据库中时出现。它表明time.Time类型没有实现driver.Valuer接口,并且缺少Value方法。解决这个问题的方法有很多,我们可以通过自定义一个新的时间类型,或者使用第三方库来处理时间类型的存储。在本文中,我们将详细介绍这个错误的原因和解决方案,帮助开发者更好地理解和解决这个问题。

问题内容

我正在开发一个 Go 项目,在该项目中,我使用 sqlboiler 从我使用 setup.sh 脚本创建的 SQLite3 数据库生成代码。我遇到了一个似乎无法解决的错误。错误信息是:

graph/db/repositories.go:998:23: cannot use o.CreatedAt (variable of type string) as driver.Valuer value in argument to queries.MustTime: string does not implement driver.Valuer (missing method Value)
graph/db/repositories.go:999:23: cannot use &o.CreatedAt (value of type *string) as sql.Scanner value in argument to queries.SetScanner: *string does not implement sql.Scanner (missing method Scan)

当我尝试在 graph/db/repositories.go 文件中使用 time.Time 值时,会发生此错误。我正在为我的项目使用 golang:1.21-alpine3.18 Docker 映像。

我尝试更改 SQLite3 数据库的存储库表中的created_at 列类型。我已经使用 TEXT 和 TIMESTAMP 数据类型对其进行了测试,但错误仍然存​​在。

有谁知道可能导致此错误的原因以及如何解决它?

repositories.go

func (o *Repository) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
    if o == nil {
        return errors.New("db: no repositories provided for insertion")
    }

    var err error
    if !boil.TimestampsAreSkipped(ctx) {
        currTime := time.Now().In(boil.GetLocation())

        if queries.MustTime(o.CreatedAt).IsZero() {
            queries.SetScanner(&o.CreatedAt, currTime)
        }
    }

    if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
        return err
    }

    nzDefaults := queries.NonZeroDefaultSet(repositoryColumnsWithDefault, o)

    key := makeCacheKey(columns, nzDefaults)
    repositoryInsertCacheMut.RLock()
    cache, cached := repositoryInsertCache[key]
    repositoryInsertCacheMut.RUnlock()

setup.sh

#!/usr/local/bin/sh

set -eu

readonly DBFILE_NAME="mygraphql.db"

# Create DB file
if [ ! -e ${DBFILE_NAME} ];then
  echo ".open ${DBFILE_NAME}" | sqlite3
fi

# Create DB Tables
echo "creating tables..."
sqlite3 ${DBFILE_NAME} "
PRAGMA foreign_keys = ON;

CREATE TABLE IF NOT EXISTS users(
    id TEXT PRIMARY KEY NOT NULL,
    name TEXT NOT NULL,
    project_v2 TEXT
);

CREATE TABLE IF NOT EXISTS repositories(
    id TEXT PRIMARY KEY NOT NULL,
    owner TEXT NOT NULL,
    name TEXT NOT NULL,
    created_at TEXT NOT NULL DEFAULT (DATETIME('now','localtime')),
    FOREIGN KEY (owner) REFERENCES users(id)
);

CREATE TABLE IF NOT EXISTS issues(
    id TEXT PRIMARY KEY NOT NULL,
    url TEXT NOT NULL,
    title TEXT NOT NULL,
    closed INTEGER NOT NULL DEFAULT 0,
    number INTEGER NOT NULL,
    repository TEXT NOT NULL,
    CHECK (closed IN (0, 1)),
    FOREIGN KEY (repository) REFERENCES repositories(id)
);

CREATE TABLE IF NOT EXISTS projects(
    id TEXT PRIMARY KEY NOT NULL,
    title TEXT NOT NULL,
    url TEXT NOT NULL,
    owner TEXT NOT NULL,
    FOREIGN KEY (owner) REFERENCES users(id)
);

CREATE TABLE IF NOT EXISTS pullrequests(
    id TEXT PRIMARY KEY NOT NULL,
    base_ref_name TEXT NOT NULL,
    closed INTEGER NOT NULL DEFAULT 0,
    head_ref_name TEXT NOT NULL,
    url TEXT NOT NULL,
    number INTEGER NOT NULL,
    repository TEXT NOT NULL,
    CHECK (closed IN (0, 1)),
    FOREIGN KEY (repository) REFERENCES repositories(id)
);

CREATE TABLE IF NOT EXISTS projectcards(
    id TEXT PRIMARY KEY NOT NULL,
    project TEXT NOT NULL,
    issue TEXT,
    pullrequest TEXT,
    FOREIGN KEY (project) REFERENCES projects(id),
    FOREIGN KEY (issue) REFERENCES issues(id),
    FOREIGN KEY (pullrequest) REFERENCES pullrequests(id),
    CHECK (issue IS NOT NULL OR pullrequest IS NOT NULL)
);
"

# Insert initial data
echo "inserting initial data..."
sqlite3 ${DBFILE_NAME} "
PRAGMA foreign_keys = ON;

INSERT INTO users(id, name) VALUES
    ('U_1', 'hsaki')
;

INSERT INTO repositories(id, owner, name) VALUES
    ('REPO_1', 'U_1', 'repo1')
;

INSERT INTO issues(id, url, title, closed, number, repository) VALUES
    ('ISSUE_1', 'http://example.com/repo1/issue/1', 'First Issue', 1, 1, 'REPO_1'),
    ('ISSUE_2', 'http://example.com/repo1/issue/2', 'Second Issue', 0, 2, 'REPO_1'),
    ('ISSUE_3', 'http://example.com/repo1/issue/3', 'Third Issue', 0, 3, 'REPO_1')
;

INSERT INTO projects(id, title, url, owner) VALUES
    ('PJ_1', 'My Project', 'http://example.com/project/1', 'U_1')
;

INSERT INTO pullrequests(id, base_ref_name, closed, head_ref_name, url, number, repository) VALUES
    ('PR_1', 'main', 1, 'feature/kinou1', 'http://example.com/repo1/pr/1', 1, 'REPO_1'),
    ('PR_2', 'main', 0, 'feature/kinou2', 'http://example.com/repo1/pr/2', 2, 'REPO_1')
;
"

sqlboiler.toml

pkgname="db"
output="graph/db"
wipe=true
add-global-variants=false
no-tests=true

[sqlite3]
  dbname = "./mygraphql.db"

环境

・ MacBook Pro M1 Pro

解决方法

我会说更新 Go 中的存储库结构,将 CreatedAt 作为 time.Time 字段。 将值分配给 CreatedAt 时,请使用 time.Time 值。例如, currTime := time.Now() 让你的结构像这样

type Repository struct {
    ID        string    `boil:"id" json:"id" toml:"id" yaml:"id"`
    Owner     string    `boil:"owner" json:"owner" toml:"owner" yaml:"owner"`
    Name      string    `boil:"name" json:"name" toml:"name" yaml:"name"`
    CreatedAt time.Time `boil:"created_at" json:"created_at" toml:"created_at" yaml:"created_at"`
    // other fields...
}

然后设置 CreatedAt 值:

repository := &Repository{
    ID:        "some-id",
    Owner:     "owner-id",
    Name:      "repo-name",
    CreatedAt: time.Now(), // setting it as time.Time
}
卓越飞翔博客
上一篇: 在 Go 应用程序中使用服务帐户 json 密钥文件时获取“请求具有无效的身份验证凭据”
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏