pq驱动程序:预处理语句不存在

时间:2013-07-12 11:58:53

标签: postgresql go prepared-statement pgbouncer

我正在尝试使用Go中的pq driver连接到postresql数据库。当我在数据库的本地副本上执行此操作时,使用类似

的连接字符串
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable")

一切都运作良好。

但是,当我切换到连接通过pgbouncer的生产服务器时:

DB, err = sql.Open("postgres", "user=user password=pwd host=/var/run/pgbouncer port=port dbname=mydb sslmode=disable")

我对所有查询都会遇到同样的错误,无论多么简单:

Database error: pq: S:"ERROR" M:"prepared statement \"1\" does not exist" C:"26000" F:"prepare.c" L:"519" R:"FetchPreparedStatement"

(它始终是“预备语句”1 \“”,独立于我试图传递的查询)

两种情况下的查询都按如下方式运行:

res_rows, err := DB.Query(query)
if err != nil {
    log.Printf("Database error: %s\n", err)
}
for res_rows.Next() {
    ...
}

谷歌搜索建议关闭准备好的语句,但我不知道如何在Go中这样做,我不确定它是否得到支持。任何帮助(甚至建议完全使用其他东西)都将非常感激。

3 个答案:

答案 0 :(得分:2)

  

Package driver

     

type Queryer

type Queryer interface {
    Query(query string, args []Value) (Rows, error)
}
     

Queryer是一个可选的接口,可以由a实现   Conn

     

如果Conn未实现Queryer,则sql包   DB.Query将首先准备查询,然后执行该语句   关闭声明。

我没看到lib/pq PostgreSQL驱动程序实现Queryer的位置。因此,DB.Query查询在执行之前就已准备好了。

PgBouncer不支持所有汇集方法的PREPARE功能:Feature matrix for pooling modes

答案 1 :(得分:2)

Postgres驱动程序现在有一个解决方案可以解决此问题:https://github.com/lib/pq/issues/389

它不在文档中,但按预期工作,包括启用PgBouncer和事务池。

答案 2 :(得分:0)

如果您使用的是PgBouncer,则需要将binary_parameters=yes设置为数据库dsn连接的查询参数

尝试:
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")