8

我正在尝试使用 Go 中的pq 驱动程序连接到 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 中做到这一点,我不确定它是否受支持。任何帮助(甚至是完全使用其他东西的建议)将不胜感激。

4

3 回答 3

4

包驱动

type Queryer

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

Queryer是一个可选接口,可由 Conn.

如果 aConn没有实现QueryersqlDB.Query将首先准备一个查询,执行该语句,然后关闭该语句。

我没有看到lib/pq PostgreSQL 驱动程序在哪里实现Queryer。因此,DB.Query查询是在执行之前准备好的。

PgBouncer不支持所有池化方法的 PREPARE 功能:池化模式的特征矩阵

于 2013-07-12T15:52:17.860 回答
4

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

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

于 2016-01-25T09:54:16.547 回答
3

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

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

于 2018-11-09T11:39:57.983 回答