首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pgx在GO中批量插入Postgres

使用pgx在GO中批量插入Postgres
EN

Stack Overflow用户
提问于 2022-01-23 14:30:29
回答 2查看 6.5K关注 0票数 5

我正在尝试在db中大容量插入键,这里是代码Key Struct

代码语言:javascript
复制
type tempKey struct {
keyVal  string
lastKey int

}

测试键

代码语言:javascript
复制
data := []tempKey{
    {keyVal: "abc", lastKey: 10},
    {keyVal: "dns", lastKey: 11},
    {keyVal: "qwe", lastKey: 12},
    {keyVal: "dss", lastKey: 13},
    {keyVal: "xcmk", lastKey: 14},
}

插入部分

代码语言:javascript
复制
dbUrl := "db url...."
conn, err := pgx.Connect(context.Background(), dbUrl)
if err != nil {
    println("Errrorr...")
}
defer conn.Close(context.Background())
sqlStr := "INSERT INTO keys (keyval,lastval) VALUES "
dollars := ""
vals := []interface{}{}
count := 1
for _, row := range data {
    dollars = fmt.Sprintf("%s($%d, $%d),", dollars, count, count+1)
    vals = append(vals, row.keyVal, row.lastKey)
    count += 2
}
sqlStr += dollars
sqlStr = sqlStr[0 : len(sqlStr)-1]
fmt.Printf("%s \n", sqlStr)

_, erro := conn.Exec(context.Background(), sqlStr, vals)
if erro != nil {
    fmt.Fprint(os.Stderr, "Error : \n", erro)
}

运行时抛出错误:需要10个参数,得到1个

什么是正确的批量插入方式。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-23 15:04:03

您正在手工编写SQL语句,这很好,但是您没有利用pgx来帮助这一点(请参阅下面)。

像这样追加到SQL字符串对于大型输入来说效率很低。

代码语言:javascript
复制
dollars = fmt.Sprintf("%s($%d, $%d),", dollars, count, count+1)

但是,最后一个值有一个尾随的,,您需要一个终止字符;来指示语句的结尾。

顺便说一下,这条字符串截断行是多余的:

代码语言:javascript
复制
sqlStr = sqlStr[0 : len(sqlStr)-1] // this is a NOOP

无论如何,在制作长字符串时最好使用更多的表演性,比如strings.Builder

pgx文档中,使用pgx.Conn.CopyFrom

代码语言:javascript
复制
func (c *Conn) CopyFrom(tableName Identifier, columnNames []string, rowSrc CopyFromSource) (int, error)

CopyFrom使用PostgreSQL复制协议执行大容量数据插入。它返回复制的行数和一个错误。

副本的示例用法

代码语言:javascript
复制
rows := [][]interface{}{
    {"John", "Smith", int32(36)},
    {"Jane", "Doe", int32(29)},
}

copyCount, err := conn.CopyFrom(
    pgx.Identifier{"people"},
    []string{"first_name", "last_name", "age"},
    pgx.CopyFromRows(rows),
)
票数 13
EN

Stack Overflow用户

发布于 2022-01-23 14:54:00

使用批处理(test.go):

代码语言:javascript
复制
batch := &pgx.Batch{}
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q1", 1)
batch.Queue("insert into ledger(description, amount) values($1, $2)", "q2", 2)
br := conn.SendBatch(context.Background(), batch)
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70823061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档