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

Connが を実装していない場合Queryersqlパッケージ DB.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 に答える