Драйвер pq: подготовленный оператор не существует
Я пытаюсь подключиться к базе данных postresql с драйвером pq в Go. Когда я делаю это на локальной копии базы данных, со строкой подключения, как
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() {
...
}
Googling предлагает отключить готовые заявления, но я не знаю, как это сделать в Go, и я не уверен, что это вообще поддерживается. Любая помощь (даже предложение использовать что-то еще полностью) будет принята с благодарностью.
4 ответа
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 для всех методов объединения: матрица функций для режимов объединения.
Если вы используете PgBouncer, вам нужно установить binary_parameters=yes
к вашей базе данных подключение dsn в качестве параметра запроса
попробуй это:DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")
Драйвер Postgres теперь имеет решение для устранения этой проблемы: https://github.com/lib/pq/issues/389
Его нет в документации, но он работает как положено, в том числе с включенными PgBouncer и пулами транзакций.
Начиная с версии PgBouncer 1.21.0, он теперь поддерживает именованные операторы уровня протокола, что почти наверняка устранит эту ошибку. Вы можете включить эту поддержку, установивmax_prepared_statements
на ненулевое значение в файле конфигурации PgBouncer. Подробную информацию можно найти в документации: https://www.pgbouncer.org/config.html#max_prepared_statements .