Go语言 pq驱动程序:准备语句不存在

avwztpqn  于 11个月前  发布在  Go
关注(0)|答案(4)|浏览(114)

我尝试在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"


(it总是“prepared statement \“1"",独立于我试图传递的查询)
这两种情况下的查询都简单地运行如下:

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


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

mwecs4sa

mwecs4sa1#

如果使用PgBouncer,则需要将binary_parameters=yes设置为数据库dsn连接的查询参数
试试这个:
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")

x33g5p2x

x33g5p2x2#

Package driver
第一个月

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

字符串
Queryer是可以由Conn实现的可选接口。
如果Conn没有实现Queryersql包的DB.Query将首先准备查询,执行语句,然后关闭语句。
我不知道lib/pq PostgreSQL驱动程序在哪里实现了Queryer。因此,DB.Query查询在执行之前就准备好了。
PgBouncer并不支持所有池化方法的CockE特性:池化模式的特性矩阵。

a0zr77ik

a0zr77ik3#

Postgres驱动程序现在有一个解决方案来解决这个问题:https://github.com/lib/pq/issues/389
它不在文档中,但可以按预期工作,包括启用PgBouncer和事务池。

ghhaqwfi

ghhaqwfi4#

从PgBouncer 1.21.0开始,它现在支持协议级别的命名准备语句,这几乎可以解决这个错误。你可以通过在PgBouncer的配置文件中将max_prepared_statements设置为非零值来打开这个支持。有关详细信息,请查看文档:https://www.pgbouncer.org/config.html#max_prepared_statements

相关问题