libpq.dllはどこに?
開発PCにDockerがインストールされている環境では、PostgreSQL等のDBサーバーを立ち上げるのは比較的簡単です。
DBサーバーを立ち上げることは簡単になったものの、WindowsからPostgreSQLにアクセスする場合、Nimであればdb_postgres
モジュールを使えばアクセスできるわけではなく、db_postgres
が、libpq.dll
というDLLファイルに依存しており、このファイルが無いことには、PostgreSQLにはアクセスできません。
import db_postgres
let db = open("localhost:5432","user","password","database_name")
# Error
# could not load: libpq.dll
libpq.dllだけを落としてきてもダメ
今どきでは、libpq.dllを検索するとダウンロードサイトがいくつかヒットします。
ですが、Windows32ビット版だったりなど、なかなかうまく行きません。
結局のところ、PostgreSQLをダウンロードせよ
PostgreSQLの本体はインストールしたくないけど、クライアントツールのインストールさえできれば、DLLが手に入りそうなので、諦めて本家(https://www.enterprisedb.com/downloads/postgres-postgresql-downloads) から、PostgreSQLのインストーラをダンロードします(およそ200MBくらい)。
Let's インストール
ダウンロードしたファイルはExe形式になっているのでこれを実行し、インストーラを起動します。
コマンドラインツールだけを選択しインストール
PostgreSQL自体はDockerで導入するので、CommandLine Toolsをチェックし、インストールを継続します。
libpq.dllはどこに?(その2)
インストールされたフォルダを確認すると、C:\Program Files\PostgreSQL\11\bin
フォルダに、念願のlibpq.dllが入っています。
libpq.dllだけをコピって使おうとしてもやっぱりダメ
nimソースのあるフォルダにlibpq.dllファイルをコピーし、先のコードを実行しても、まだlibpq.dllが無いと怒られます。
この理由はlibpq.dllが更に他のDLL(binフォルダに配置されていたDLL)に依存しているからです。
これは、dependency walkerというツールを使うと確認できます。
そのために取れる手段としては、以下の2つのうちのどれかとなります。
- インストール先のbinフォルダへPathを通す
- binフォルダ内のすべてのdllファイルを(nimインストール先のbin)コピーする
まとめ的な何か
PostgreSQLのインストール先\binにパスを通し、以下のソースを実行してみます。
import db_postgres
const host_port = "localhost:5432"
const user_name = "username"
const password = "password"
const db_name = "postgres"
block:
let db = open(host_port,user_name,password,db_name)
echo "opened"
defer:
db.close
echo "closed"
for x in db.fastRows(sql"select current_schema()") :
echo x
結果はこちら。
opened
@["public"]
closed
この手の方法はその他DB(Oracle/MySQL)でも同様で、クライアントツール等のインストールを行い必要なDLLへのパスを通すなどの作業は必要です。
当初はlibpq.dllだけが必要ならそれだけ落としてこれば良いかと思って始まった勘違いの旅路でした。