英文:
pq driver: prepared statement does not exist
问题
我正在尝试使用Go中的<a href="https://github.com/lib/pq">pq驱动程序</a>连接到一个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"
(无论我尝试传递的查询是什么,它总是"prepared statement "1"")
在这两种情况下,查询都是简单地运行如下:
res_rows, err := DB.Query(query)
if err != nil {
log.Printf("Database error: %s\n", err)
}
for res_rows.Next() {
...
}
根据谷歌搜索的建议,关闭预处理语句,但我不知道如何在Go中做到这一点,而且我也不确定是否支持。任何帮助(甚至建议完全使用其他东西)将不胜感激。
英文:
I'm trying to connect to a postresql database with the <a href="https://github.com/lib/pq">pq driver</a> in Go. When I do it on a local copy of the database, with a connection string like
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable")
it all works well.
However, when I switch to a production server where the connection goes through pgbouncer:
DB, err = sql.Open("postgres", "user=user password=pwd host=/var/run/pgbouncer port=port dbname=mydb sslmode=disable")
I keep getting the same error for all queries, however simple:
Database error: pq: S:"ERROR" M:"prepared statement \"1\" does not exist" C:"26000" F:"prepare.c" L:"519" R:"FetchPreparedStatement"
(it's always "prepared statement "1"", independent of the query I'm trying to pass)
The query in both cases is run simply as follows:
res_rows, err := DB.Query(query)
if err != nil {
log.Printf("Database error: %s\n", err)
}
for res_rows.Next() {
...
}
Googling suggests to turn off prepared statements, but I don't know how to do that in Go and I'm not sure it is supported at all. Any help (even a suggestion to use something else entirely) would be greatly appreciated.
答案1
得分: 4
> Package driver
>
> type Queryer
>
> type Queryer interface {
> Query(query string, args []Value) (Rows, error)
> }
>
> Queryer
是一个可选的接口,可以由Conn
实现。
>
> 如果一个Conn
没有实现Queryer
,sql
包的DB.Query
将首先准备查询,执行语句,然后关闭语句。
我没有看到lib/pq PostgreSQL驱动程序实现了Queryer
。因此,在执行之前,DB.Query
查询会被准备好。
PgBouncer不支持所有连接池方法的PREPARE功能:连接池模式的功能矩阵。
英文:
> Package driver
>
> type Queryer
>
> type Queryer interface {
> Query(query string, args []Value) (Rows, error)
> }
>
> Queryer
is an optional interface that may be implemented by a
> Conn
.
>
> If a Conn
does not implement Queryer
, the sql
package's
> DB.Query
will first prepare a query, execute the statement, and then
> close the statement.
I don't see where the lib/pq PostgreSQL driver implements Queryer
. Therefore, the DB.Query
query is prepared before execution.
PgBouncer doesn't support the PREPARE feature for all pooling methods: Feature matrix for pooling modes.
答案2
得分: 4
Postgres驱动程序现在有一个解决此问题的解决方案:https://github.com/lib/pq/issues/389
虽然它没有在文档中提到,但它按预期工作,包括在启用了PgBouncer和事务池的情况下。
英文:
The Postgres driver now has a solution to fix this issue: https://github.com/lib/pq/issues/389
It isn't in the documentation but works as expected, including with PgBouncer and Transaction pooling enabled.
答案3
得分: 4
如果您正在使用PgBouncer,您需要将binary_parameters=yes
设置为数据库dsn连接的查询参数
尝试这样做:
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")
英文:
If you're using PgBouncer you need to set binary_parameters=yes
to your database dsn connection as a query parameter
try this:
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论