【问题标题】:pq driver: prepared statement does not existpq 驱动程序:准备好的语句不存在
【发布时间】:2013-07-10 23:14:17
【问题描述】:

我正在尝试使用 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 中执行此操作,我不确定它是否受支持。任何帮助(甚至是完全使用其他东西的建议)都将不胜感激。

【问题讨论】:

  • 您要求我们猜测您是如何运行产生错误的查询的。您执行了哪些 Query 和相关方法(例如 Prepare 方法)导致错误。
  • 抱歉,更新了帖子。我根本没有使用 Prepare,只是在 sql.Open 之后使用纯 DB.Query。

标签: postgresql go prepared-statement pgbouncer


【解决方案1】:

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 功能:Feature matrix for pooling modes

【讨论】:

  • 感谢您的解释!所以基本上这意味着我不能在这个设置中使用 Go?
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 2017-11-05
      • 2022-12-31
      • 2013-05-31
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多