将一个数组插入到Postgresql数据库中。

22

我希望能够在使用Go进行历史记录的表中编写bigint数组。不幸的是,当我这样做时会抛出错误sql:converting Exec argument #1's type: unsupported type []int64, a slice。以下是我为了简洁而编辑过的代码:

type Card struct {
    cid int64
}

type Transaction struct {
        tid, cardid int64
        productids []int64
        salepoint int
        cardkey string
}

func logPurchase(card *Card, t *Transaction) {
     _, err := db.Exec("INSERT INTO history VALUES ($1, $2, $3, $4)", rand.Int63(), t.productids, card.cid, t.salepoint);
}

这是我想要插入的表格结构: tid bigint 主键,productids bigint[] 非空,cardid bigint 非空,salepoint int 请注意保留HTML标签。

1
看起来你的值列表中有一个额外的值。 - jmaloney
很好的发现,不确定我是如何把它放在那里的。在我遇到这个问题的源代码中不存在这个问题。相应地更新了问题。 - ShrekTheDinosaur
数组类型是特定于PostgreSQL的。您可能需要使用专门针对PostgreSQL的库,例如:https://github.com/go-pg/pg - dyoo
截至目前为止,似乎 lib/pq 库当前不处理数组类型,尽管有一个功能请求:https://github.com/lib/pq/issues/49 - dyoo
建议在该功能被添加后更新已接受答案为 https://dev59.com/ml8d5IYBdhLWcg3wiip9#41337887。 - user3.1415927
2个回答

30

自2016年8月6日起github.com/lib/pq支持数组。 OP的说法可以写成:

_, err := db.Exec(
    "INSERT INTO history VALUES ($1, $2, $3, $4)", 
    rand.Int63(), 
    pq.Array(t.productids),   // <------- 
    card.cid, 
    t.salepoint,
)

12

使用自定义类型实现 database/sql/driver.Valuer:

type int64array []int64

func (a int64array) Value() (driver.Value, error) {
    // Format a in PostgreSQL's array input format {1,2,3} and return it as as string or []byte.
}

1
嗨Andy,很棒的答案。但是如何实现相反的操作呢?我需要实现哪个函数来执行psql数组->切片的转换? - STE
1
对于反向操作,您需要实现 database/sql.Scanner 接口。为此,您需要使用指针接收器。 - andybalholm
如果您愿意的话,将其添加到您的答案中以供参考会很有用 - 无论如何感谢您! - STE
1
已经在里面了,你只需要在productids字段中使用pg.Int64Array类型即可。 - user2563451

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接