6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NimAdvent Calendar 2020

Day 12

WindowsでNimからPostgreSQLにアクセスする

Last updated at Posted at 2020-12-11

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くらい)。

2020-11-25 17.14.18 www.enterprisedb.com ca0e93a85381.png

Let's インストール

ダウンロードしたファイルはExe形式になっているのでこれを実行し、インストーラを起動します。
2020-11-25_17h41_20.png

コマンドラインツールだけを選択しインストール

PostgreSQL自体はDockerで導入するので、CommandLine Toolsをチェックし、インストールを継続します。

2020-11-25_17h42_10.png

libpq.dllはどこに?(その2)

インストールされたフォルダを確認すると、C:\Program Files\PostgreSQL\11\binフォルダに、念願のlibpq.dllが入っています。

2020-11-25_17h46_56.png

libpq.dllだけをコピって使おうとしてもやっぱりダメ

nimソースのあるフォルダにlibpq.dllファイルをコピーし、先のコードを実行しても、まだlibpq.dllが無いと怒られます。
この理由はlibpq.dllが更に他のDLL(binフォルダに配置されていたDLL)に依存しているからです。

これは、dependency walkerというツールを使うと確認できます。

2020-11-25_18h19_56.png

そのために取れる手段としては、以下の2つのうちのどれかとなります。

  • インストール先のbinフォルダへPathを通す
  • binフォルダ内のすべてのdllファイルを(nimインストール先のbin)コピーする

まとめ的な何か

PostgreSQLのインストール先\binにパスを通し、以下のソースを実行してみます。

pgsample.nim
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だけが必要ならそれだけ落としてこれば良いかと思って始まった勘違いの旅路でした。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?