mongo_fdw †
- EnterpriseDB社から提供されているオープンソースソフトウェア。
- PostgreSQLのForeign Data Wrapperを使って,PostgreSQLからMongoDBのデータに透過的にアクセスすることができる。
- 外部テーブルに対して,INSERTやUPDATE,DELETEなどのDMLを通じて,MongoDBに対して更新や削除も行なうことができる。
設定・使用方法 †
ビルド †
Mac OS X †
opensslをHomebrewでインストールした場合,opensslライブラリをリンクするビルドには以下のように明示的にインクルードパスとライブラリパスを指定するように警告されるのでautogen.shの以下を修正する。
$ brew link openssl --force Warning: Refusing to link: openssl Linking keg-only openssl means you may end up linking against the insecure, deprecated system OpenSSL while using the headers from Homebrew's openssl. Instead, pass the full include/library paths to your compiler e.g.: -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib
以下を修正する。具体的には,configureの引数にCFLAGSを追加している。
### # Configure and install the Mongo C Driver and libbson # function install_mongoc_driver { cd mongo-c-driver ./configure --with-libbson=auto --enable-ssl CFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" # ここに追加 make install cd .. }
これで以下のようにビルドできる。
sh autogen.sh --with-master make CFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" install
PostgreSQL側の準備 †
外部テーブルを作成する。
CREATE EXTENSION IF NOT EXISTS mongo_fdw; CREATE SERVER mongo_server FOREIGN DATA WRAPPER mongo_fdw OPTIONS (address '127.0.0.1', port '27017'); CREATE USER MAPPING FOR public SERVER mongo_server OPTIONS (username 'postgres', password '123456'); CREATE FOREIGN TABLE warehouse( _id NAME, -- ObjectIdが格納される id INT, name text ) SERVER mongo_server OPTIONS (DATABASE 'db', collection 'warehouse'); -- DROP FOREIGN TABLE WAREHOUSE; -- DROP USER MAPPING FOR public SERVER mongo_server; -- DROP SERVER mongo_server CASCADE;
MongoDB側の準備 †
ユーザーを登録し,コレクションにドキュメントをインサートする。
以下の例では,作成したユーザーに対してR/W権限とAdmin権限のロールを設定している。
> use db switched to db db > db.createUser({user: "postgres", pwd: "123456",roles:["readWrite", "dbAdmin"]}); Successfully added user: { "user" : "postgres", "roles" : [ "readWrite", "dbAdmin" ] } > db.warehouse.insert({"id": NumberInt(1),"name":"Tarou"}) WriteResult({ "nInserted" : 1 }) > db.warehouse.find() { "_id" : ObjectId("593173a3877efdec0848b3f0"), "id" : 1, "name" : "Tarou" }
クエリの実行 †
上記の準備ができた状態で,PostgreSQL側からクエリを発行してみると,以下のように結果が返ってくる。
foo=# SELECT * FROM warehouse WHERE id = 1; _id | id | name --------------------------+----+------- 593173a3877efdec0848b3f0 | 1 | Tarou (1 ROW)
ヒント
結果が空になる場合は,mongodのログを確認してみる。
よくあるのは認証に失敗しているケースだろう。
2017-06-02T23:06:10.464+0900 I NETWORK [thread1] connection accepted from 127.0.0.1:61268 #3 (3 connections now open) 2017-06-02T23:06:10.464+0900 I ACCESS [conn3] SCRAM-SHA-1 authentication failed for postgres on db from client 127.0.0.1:61268 ; UserNotFound: Could not find user postgres@db