1. psqlODBC とは

psqlODBCはオープンソースソフトウェアとして開発されている PostgreSQL の ODBC ドライバです。完全ではありませんが ODBC 3.0 に対応しています。ほかに商用製品のドライバも存在しますが、大部分の用途では psqlODBC を使用すれば十分といえます。psqlODBC の難点としては、公式ドキュメントの記述量が少ないこと、利用方法を解説した文書が少ない、あるいは、ひどく古いバージョンを前提とした公開文書が多く、取捨選択が難しいことがあります。

2018年 10月時点で、PostgreSQL 10.x に対応した psqlODBC 10.03.0000 がリリースされています。本文書は、PostgreSQL 9.6.2 と psqlODBC 09.06.0100 を使って、psqlODBC の Linux 上と Windows 上での使い方を解説します。

2. 導入方法 (Windows)

◆ パッケージの取得

psqlODBC ソフトウェアは以下ページから入手できます。ソースコード(src)に加えてバイナリファイルが MSI インストーラ(msi)、マージモジュール(mm)、DLL(dll)の各形式から選べます。単体で導入するなら MSI インストーラ、アプリケーションのインストーラに組み入れるならマージモジュールを、Windows のコンポーネント管理下に置かずに使用するなら DLL を選べば良いでしょう。

https://www.postgresql.org/ftp/odbc/versions/

◆ 32bit 版と 64bit 版

バイナリ配布については同バージョンでも 64bit (ファイル名に「-x64」が含まれます) と 32bit (ファイル名に「-x86」が含まれます/古いものは何もサフィックスがなければ 32bitです)の 2 種類があります。Windows が 32bit か 64bit かによって使い分けます。

64bit の Windows でも 32bit ビルドされたアプリケーションで ODBC を使うために 32bit 版を使用したい場合があります。この場合、インストールと使用は可能ですが、Windows の[コントロールパネル]→[管理ツール]→ [データソース(ODBC)]から 32bit 版 ODBC の設定画面(ODBC データ ソース アドミニストレーター )が開けません。この場合、Windows システムディレクトリ内にある 32bit 版の odbcad32.exe を直接実行する必要があります。

◆ ANSI 版と UNICODE 版

psqlODBC には ANSI 版と UNICODE 版の二つのドライバが含まれています。ODBC ドライバを使用する Windows アプリケーションのビルドオプションと合わせます。ANSI 版は Visual Studio における「マルチバイト文字セットを使用する」ビルドに対応します。

psqlODBC ドライバは UNICODE 版では PostgreSQL サーバとの間を UTF8 クライアント文字エンコーディングで通信します。データベース文字エンコーディングが UTF8 以外(EUC_JP など)である場合、アプリケーションから SQL として送られてくる文字列をデータベース文字エンコーディングに変換するのに失敗する可能性があります。最終的に格納可能な文字のみをデータとして投入するようにアプリケーション設計しておく必要があります。

ANSI 版の場合には、クライアント側 Windows のコードページを調べて、それに合わせて PostgreSQL のクライアント文字エンコーディングを宣言します。コードページが 932 なら SJIS になるはずです。どのクライアントエンコーディングであると宣言するかはデータソースの構成で上書き設定可能です。

3. 設定方法 (Windows)

◆ データソース作成

ODBC 接続を利用するには、Windows に ODBC 接続のデータソース定義を作り、そのデータソースをアプリケーションが利用します。インタラクティブにデータソース定義を加えるには、コントロールパネル]→[管理ツール]→ [データソース(ODBC)]から設定画面(ODBC データ ソース アドミニストレーター )を起動します。

「追加」ボタンを押して、PostgreSQL UNICODE または PostgreSQL ANSI のドライバを選択すると下記の ODBC セットアップ画面になります。ここでサーバホスト名、ポート番号、データベース名を指定します。ユーザ名・パスワードは必須ではありません。

図 1: ODBC セットアップ画面

図 1: ODBC セットアップ画面

「オプション(高度な設定)」の「データソース」から各種の設定ができます。次項にて詳細を説明します。

「全体設定」からは接続前に採取するログの種類とログ出力先ディレクトリが設定できます。「管理」からはANSI版ドライバ・UNICODE 版ドライバの切替ができます。
「SSL Mode」では SSL 接続について無効、考慮、優先、必須、必須:証明書認証、必須:証明書完全認証を指定できます。INI ファイルでのパラメータ名は SSLmode 、短縮名は CA です。選択肢の意味はそれぞれ libpq 接続ライブラリにおける sslmode オプションの disable 、 allow 、 prefer 、 require 、 verify-ca 、 verify-full に相当します(INI ファイルではこれら文字列で指定します)。

◆ プログラムによるセットアップ

データソースをプログラム的に追加するには、SQLConfigDataSource ODBC API 関数が利用できます。

◆ データソース高度な設定

データソースの「高度な設定」画面は3ページに分かれています。多数のパラメータがあり、これらの大部分は接続文字列や INI ファイル指定でも与えられます。

図 2: 高度な設定 - 設定 1 画面

図 2: 高度な設定 – 設定 1 画面

設定1画面で指定できる項目は以下の通りです。INI ファイルでのパラメータ名、接続文字列に使える短縮形パラメータ名との対応付けも示します。なお、スクリーンショットの内容はデフォルトの値です。

GUI 設定項目 INI 設定名 / 短縮形 意味
ユニークインデックスを使う UniqueIndex / (短縮名なし) 通常、真(=1)にします。
SQLStatistics に影響します。
Declare ~ Fetch を使用する UseDeclareFetch / B6 明示的なカーソルを使って問い合わせ結果を取り出します。
一般ログ出力をする CommLog / B3 コミュニケーションログを出力するかを指定します。アプリケーションのデバッグに有用です。
ステートメントの構文解析を行う Parse / C0 真(= 1)にすると、SQLNumResultCols 、 SQLDescribeCol 、 SQLColAttributes についても文を解析するようになります。
詳細ログ出力をする Debug / B2 デバッグログを出力するかを指定します。MyLog とも呼ばれます。ドライバ自体のデバッグに有用です。
未知サイズ動作 UnknownSizes / A9 0:最大をとる 、1:特定しない:、2:最長をとる、の何れかをとります。SQLDescribeCol と SQLColAttributes が varchar などの可変長文字列データ型サイズをどう答えるかを指定します。0 はデータ型としての最大値、2 は存在する行の最大値を返し、1 は不明と返します。
text を長文字列として扱う TextAsLongVarchar / B7 真(= 1)なら text 型を SQL_LONGVARCHAR に対応付けます。偽(= 0)なら SQL_VARCHAR です。
不明を長文字列として扱う UnknownsAsLongVarchar / B8 真なら配列型などの決まった対応付けがない型を SQL_LONGVARCHAR に対応付けます。偽(= 0)なら SQL_VARCHAR です。
Char として Boolean を扱う BoolsAsChar / B9 真なら boolean 型を SQL_CHAR に対応付けます。偽(= 0)なら SQL_BIT です。
最大 Varchar MaxVarcharSize / B0 SQL_VARCHAR 型に対応付けされるデータ型の最大長。これはサイズを聞かれたときの答えであり、SQLGetData で指定値より長いカラム値の文字列取得も可能。
最大 LongVarChar MaxLongVarcharSize / B1 SQL_LONGVARCHAR に対応付けされるデータ型の最大長。これはサイズを聞かれたときの答えであり、SQLGetData で指定値より長いカラム値の文字列取得も可能。
SQL_NO_TOTAL に相当する -4 を設定して、サイズ不明という応答させることも可能。
キャッシュサイズ Fetch / A7 問い合わせ結果のデータを取得する際の一度に取得する行数。繰り返し少数行を取得するときにまとめて取得して高速化するための設定です。大量取得を少しずつの取得にして使用メモリ量を減らす設定ではありません。
システムテーブルプレフィックス ExtraSysTablePrefixes / C2 セミコロン(;)区切りでいくつか指定できます。このプレフィックスがあるとシステムテーブル扱いになります。
本欄に指定がなくとも「pg_」で始まるテーブルはシステムテーブル扱いになります。

図 3: 高度な設定 - 設定 2 画面

図 3: 高度な設定 – 設定 2 画面

設定2画面の設定項目は以下の通りです。

GUI 設定項目 INI 設定名 / 短縮形 意味
リードオンリィ ReadOnly / A0 真(= 1)なら読み込み専用になります。その場合も、更新を含む SELECT は実行可能です。
バージョン列表示 RowVersioning / A4 真なら、行が更新されたことを検知するために使われるバージョン列を有効にします。SQLColumns 結果に xmin 列が加わります。MS-ACCESS むけ機能です。
システムテーブルを表示 ShowSystemTables / A5 真なら SQLTables でシステムテーブルを通常テーブルと同様に返します。
LF <-> CR/LF 変換を行う LFConversion / C5 真なら 取得したテキストデータの LF を CR LF に変換します。逆向きの変換はありません。
-1 を真値とする TrueIsMinus1 / C6 真なら TRUE を ‘-1’ として返します。さもなくば ‘1’ です。
更新可能カーソル UpdatableCursors / C4 真なら更新可能カーソルをエミュレートします。
サーバ側 Prepare UseServerSidePrepare / C8 真ならサーバ側プリペアドステートメントを使用します。
bytea を LO として扱う ByteaAsLongVarBinary / C7 真(= 1) なら SQL_LONGVARBINARY に bytea 型を使います。他に lo ドメイン(実体は oid 型)が使用できます。
Int8 の代替定義 BI / (短縮名なし) 以下の値を取ります。

デフォルト 0
bigint(SQL_BIGINT) -5
numeric (SQL_NUMERIC) 2
varchar (SQL_VARCHAR) 12
double(SQL_REAL) 7
int4 (SQL_INTEGER) 4

int8 列がどのデータ型として報告されるかを指定します。
デフォルトは接続オプションで “Microsoft Jet” の指定がある場合だけ SQL_NUMERIC で、さもなくば SQL_BIGINT です。

エラー時のロールバック発行 Protocol / A1 以下の値を取ります。「7.4」部分はプロトコル指定ですが今日指定すべきは「7.4」だけです。その後のハイフン以降でロールバックの挙動を指定します。

7.4 : デフォルト(選択無し)
接続先が PostgreSQL 8.0 以上なら「文単位」、さもなくば「全キャンセル」になります。

7.4-0 : 無し
エラー時もドライバは ROLLBACK を発行しません。ロールバック発行はアプリケーションの責任となります。

7.4-1 : 全キャンセル
エラー時にドライバが ROLLBACK を発行します。

7.4-2 : 文単位
ドライバは暗黙に文ごとに SAVEPOINT を設定して、エラー時に直近 SAVEPOINT までの ROLLBACK を発行します。負荷が高い動作となります。

[ OID オプション] カラム列表示 ShowOidColumn / A3 真なら SQLColumns 、 SQLStatistics に OID 列を含めます。
[ OID オプション] インデックスを装う FakeOidIndex / A2 真なら OID 列がユニークキーであるように見せかけます。真の主キー列が無くて、アプリケーションが主キー列を要求する場合に使います。
特別なオプション AB / (短縮名なし) 以下の和を16進数で与えます。

1 BIT_FORCEABBREVCONNSTR
短縮形パラメータを必ず使用します。

2 BIT_FAKE_MSS
サーバがSQL Server であるかのように偽装します。

4 BIT_BDE_ENVIRONMENT
BDE(Borland Database Engine)に対応させます。

8 BIT_CVT_NULL_DATE
NULL日付を空文字列に変換します。FOXPROむけフラグ。

16 BIT_ACCESSIBLE_ONLY
SQLTables が参照可能なテーブルだけ返します。

32 BIT_IGNORE_ROUND_TRIP_TIME
往復時間を無視できることを示すフラグ。マルチSQLを分割発行するかの判断に使用。

接続時設定 ConnSettings / A6 接続時に実行する SQL 文を記述できます。「;」区切りで複数記述できます。
TCP KEEP ALIVE KeepaliveTime / D1
KeepaliveInterval / D2
OS の TCP KeepAlive 機能の待ち時間(= アイドル時間)と応答時間(= インターバル時間)を指定します。

図 4: 高度な設定 - 設定 3 画面

図 4: 高度な設定 – 設定 3 画面

設定3画面の設定項目は以下の通りです。

GUI 設定項目 INI 設定名 / 短縮形 意味
MSDTC リカバリ不可接続を許可? XaOpt / D4 MSDTC を使う場合に接続確認をするかどうかの設定です。「する」の方が接続確認をしない動作になります。

  1. する
  2. verify-ca 、verify-full モードの SSL なら拒絶
  3. しない
接続テスト 設定ではなく、この場で分散トランザクションによる接続テストをするボタンです。
libpq パラメータ pqopt / D5 PostgreSQL 接続文字列の形式(空白区切りで 項目 = 値 の並び)で libpq ライブラリに与えるパラメータを指定できます。sslrootcert や sslcert 、 sslkey を指定するに有用です。

◆ パラメータ設定のポイント

ほとんどのパラメータはデフォルトのままで問題ありません。
特定のアプリケーションで動作しないことに対する対策としてパラメータが追加された結果、パラメータ数が多数となっています。

4. 使用例 (Windows)

ODBC データソースは様々なアプリケーション、開発言語・環境にて使用できます。ここでは Microsoft Office の Excel を使って接続と SQL 実行のテストをしてみます。「その他のデータソース」の「 Microsoft Query 」を選択します。

図 5: Excel 画面例

図 5: Excel 画面例

データソースの選択で作成した PostgreSQL のデータソースを選択します

図 6:データソース選択

図 6:データソース選択

クエリウィザードでテーブルを選択します。ここでは仮に 1テーブルだけ追加します。

図 7:クエリウィザード初期選択画面

図 7:クエリウィザード初期選択画面

テーブルの結合を GUI 操作で記述できます。ここで任意に SQL を追加したり、結合や選択条件を指定できます。

図 8:Microsoft Query 画面

図 8:Microsoft Query 画面

Microsoft Query で SQL 実行した結果を Excel に取り込むことができます。

図 9:データ取り込み結果

図 9:データ取り込み結果

5. Linux での使用

Linux や各種 UNIX 上で動作する ODBC API を提供するライブラリを使用して、 ODBC 接続をすることができます。オープンソースでよく使われているのが unixODBC と iODBC です。これらは RHEL / CentOS 6 や 7 で標準パッケージとして含まれています。本節では CentOS 6.x にて unixODBC を使用する例を説明します。

◆ インストール

unixODBC は以下のように OS パッケージからインストールします。

# yum install unixODBC unixODBC-devel

psqlODBC を unixODBC むけにソースコードからビルドする手順は以下のようになります。ただし、 psqlODBC はビルドしにくい部類のソフトウェアです。ODBC API ライブラリ(ここでは unixODBC )とのバージョン組み合わせにもよるのですが、エラーが発生し、ビルドを成功させるために CFLAGS 環境変数でプリプロセッサ変数を指定したり、Makefile の補正が必要になることがあります。

$ ./configure --with-unixodbc=/usr/lib64 \
    --with-libpq=/usr/pgsql-9.6
$ make
$ su -c 'make install'

お勧めは バイナリパッケージを使うことです。
PostgreSQL RPM Building Project のパッケージとして「 postgresql96-odbc 」という名前でパッケージが用意されています。「 96 」部分はリポジトリの PostgreSQL バージョン系列が 9.6 系であれば 96 、 9.5 系であれば 95 となります。依存関係はクライアントライブラリだけですので、 PostgreSQL サーバのパッケージを導入する必要がありません。

# yum install postgresql96-odbc

本パッケージでは UNICODE 版のドライバのみがインストールされます。

◆ 設定

unixODBC の設定方法を示します。
以下のようにドライバの定義を /etc/odbcinst.ini に記述します。32 bit 環境なら Driver64 でなく Driver にライブラリを指定します。FileUsage は必ず 1 です。 Threading はマルチスレッド動作での保護レベルの指定で、通常は接続単位で保護する 2 を指定します。

[PostgreSQL]
Description     = ODBC for PostgreSQL
Driver64        = /usr/pgsql-9.6/lib/psqlODBCw.so
FileUsage       = 1
Threading       = 2

データソースの定義を /etc/odbc.ini または、ユーザ毎の ~/.odbc.ini に以下のように記述します。ここで設定できる項目は、前節の設定一覧表で「 INI 設定名」として示したものとなります。

[PostgreSQL_DS1]
Description         = PostgreSQL Datasource 1
Driver              = PostgreSQL
Database            = db1
Servername          = dbhost.example.com
Port                = 5432
Protocol            = 7.4-2
CommLog             = 0
Debug               = 0

接続テストをするには unixODBC に付属する isql コマンドを使うのが簡単です。以下のように使用できます。

[host]$ isql PostgreSQL_DS1 dbuser pass
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> SELECT id FROM t1 ;
+------------+
| id         |
+------------+
| 1          |
| 2          |
| 3          |
+------------+
SQLRowCount returns 3
3 rows fetched
SQL> quit
[host]$

なお、ログファイルは /tmp 以下に出力されます。今のところログディレクトリは指定できません。CommLog = 1 なら psqlODBC_ で始まるログファイルが、Debug = 1 なら mylog_ で始まるログファイルが出力されます。

6. まとめ

本文書では psqlODBC について基本的な情報を取りまとめました。
このほか実際に使用するには、各アプリケーションあるいはアプリケーション開発言語・環境における ODBC 接続によるデータベースアクセスを行うライブラリ関数群の使用方法を把握する必要があります。これらは多岐にわたるため、本文書での説明は割愛しています。
特定アプリケーション、アプリケーション開発言語・環境にて動作しない場合については、 psqlODBC 公式ページにある FAQ や HOWTOs 文書の記載が役立つことがあります。これらも確認してください。