まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

IBM Bluemix からも提供されている NoSQL DBaaS である Cloudant 。このデータベースサービスにはベータベースの全文書を取得したり、複数データをバルクでインサートするような REST API が提供されており、これらを応用することで(curl を併用するなどして)バックアップやリストアを行うこともできることになっています。


ただこの方法にはいくつかの問題点もありました。個人的には以下の2点がちと無視できない制約でした:
(1) バックアップしたデータをバルクインサートすると、元のデータベース内にあった JSON ドキュメントとは異なる階層構造になってしまう
(2) バックアップデータには attachments(添付ファイル)情報が含まれない。そのためバルクインサートでリストアしても添付ファイルは復元されない


これらの問題を解決して API でバックアップ&リストアするための方法を考えていましたが、結論としては「専用ツールを作った方が早くて便利そう」でした。で、実際に作ってみました:
https://github.com/dotnsf/cdbtool


セットアップ方法や使い方は README.md にも書いておきましたが、動作前提に Node.js が必要です。お使いのシステムに併せて Node.js を導入しておいてくださいませ。

で、上記 URL からツール本体をダウンロード&展開するか、git clone します。

展開後のファイル一覧の中に settings.js というファイルがあります。このファイルをテキストエディタで開き、バックアップ&リストアの対象とする Cloudant サービスのユーザー名およびパスワードに該当部分を書き換えて保存します:
exports.cloudant_username = 'ここを Cloudant のユーザー名に書き換える';
exports.cloudant_password = 'ここを Cloundant のパスワードに書き換える';

なお、Cloudant のユーザー名およびパスワードは別途確認しておいてください。IBM Bluemix 環境の場合であればランタイムやサービスの資格情報から確認することができます:
2017032801


最後にこのツールが必要なライブラリをまとめてインストールします。package.json があるディレクトリで以下のコマンドを実行します:
$ npm install

これで準備完了!

ではまずは Cloudant データベースをダンプ(バックアップ)してみます。使うファイルは dump.js で、コマンドラインから以下のように入力します:
$ node dump (dbname) (dumpfilename)

最初の2つ(node dump)は「Node.js で dump.js を実行する」ことを指定しています。残りの2つはいわゆるコマンドラインパラメータです。

最初のコマンドラインパラメータの (dbname) は Cloudant 上のデータベースの名称です。例えば、現在 Cloudant のダッシュボードでデータベース一覧を見た時に以下のようになっているものとします:
2017032801


データベースが5つありますが、この中の一番下にある "spendb" データベース(文書数 53)のバックアップを取得するのであれば、このパラメータには spendb と指定することになります。

最後のパラメータ (dumpfilename) はダンプ結果を保存するファイル名を指定します。今回はここに spendb.dump と指定して、この名前のファイルをダンプファイルとして新たに作成することにします。つまりコマンドラインからは以下のように実行することになります:
$ node dump spendb spendb.dump

このコマンドが成功すると、実行時のディレクトリに spendb.dump という名前のファイルが作成されているはずです。

ではバックアップで作成したファイルを使って、新しいデータベースにリストアしてみましょう。リストア時は以下のようなコマンドを入力します:
$ node restore (newdbname) (dumpfilename)

ここでも後ろの2つがコマンドラインパラメータで、最初の (newdbname) はリストア先のデータベース名です。指定した名前のデータベースが存在していない場合は新たに作成され、存在している場合は一度削除されて新たに作成されます(文書データだけ上書き、ではありません)。 また (dumpfilename) には上記で作成したダンプファイル名を指定します。仮に上記で作成したダンプファイルを使って、newdb という名前のデータベースにリストアするのであれば、以下のように実行することになります:
$ node restore newdb spendb.dump

このコマンドが成功すると、Cloudant 上に newdb という名前のデータベースが新たに作成され、その中にドキュメントが(元データベースと同じ 53 文書)ロードされているはずです。文書ID も元のデータベースのものがそのまま使われ、元データベース内に添付ファイル(attachments)が含まれていた場合は添付ファイルも含めてリストアされる仕様です(これを実現したくて、このツールを作りました):
2017032802



今後はダンプファイルのサイズ圧縮とかにも対応しようかなあ。気が向いたら機能追加したりバグ修正したりもしますが、MIT ライセンスでオープンソース化しているので、何かあったら適当に(笑)対応していただけるとうれしいです。



Google ドライブのファイルシステム(?)を fuse を使って Linux にマウントする、というためのツールを使ってみました。今回は Google Drive ocamlfuse というツールを使って、Ubuntu 14.04 環境にマウントしてみました:
https://github.com/astrada/google-drive-ocamlfuse


なお、今回紹介する手順では途中でウェブブラウザを使った OAuth 認証を行うため、GUI 環境が必要です(コマンドライン環境だけでは最後までマウントできません)。GUI アクセスできる Ubuntu とウェブブラウザをご用意ください。

まずはターミナルを開き、Google Drive ocamlfuse を apt-get でインストールできるようにするため、リポジトリを追加します:
$ sudo add-apt-repository ppa:alessandro-strada/ppa
$ sudo apt-get update

そして apt-get install を実行します:
$ sudo apt-get install google-drive-ocamlfuse

準備の最後に Google Drive をマウントする先のマウントポイントとなるディレクトリ(以下の例では ~/googledrive)を用意しておきます:
$ mkdir ~/googledrive

では Goodle Drive ocamlfuse を使って実際にマウントしてみます。初回のみコマンドラインから引数なしで実行します:
$ google-drive-ocamlfuse

するとウェブブラウザが起動し、Google の OAuth 認証が行われます。Google ドライブを使うためのユーザーおよびパスワードでログインします:
2017032201


オフラインアクセスのための許可が求められるので「許可」をクリック:
2017032202


以下のようなメッセージが表示されれば OAuth 認証完了です:
2017032203


再びターミナル画面に戻り、今度はマウントポイントを指定して google-drive-ocamlfuse を実行します。これで OAuth 認証時に使ったユーザーの Google ドライブが指定ディレクトリにマウントされます:
$ google-drive-ocamlfuse ~/googledrive


この状態で df -h コマンドを実行すると、指定したディレクトリに Google Drive がマウントされていることが確認できます:
2017032204


ls コマンドなどでこのディレクトリ内を確認すると、Google Drive 内のドキュメントが odt 等のフォーマットで存在していることを確認できます:
2017032205


アンマウントする場合は fusermount コマンドを -u オプションを付けて(アンマウントポイントを指定して)実行します:
$ fusermount -u ~/googledrive


Google ドライブがマウントできると Boostnote のドキュメント共有が異なるシステム間でも可能になったりできて、ますます便利です。



(参考)
http://o2t.hatenablog.com/entry/2014/09/08/143621
 

IBM Bluemix からも提供されている、スケーラブルな NoSQL DBaaS である Cloudant 。データの読み書きには REST API が提供されており、ウェブアプリケーションだけでなく、スマホのネイティブアプリなど色々なアプリケーションから利用することができます。
2017032101


この Cloudant はいわゆる「JSON ドキュメント」を格納するデータベースなのですが、バイナリデータ(というかファイル)を扱う機能("attachement")も持っています。

以下にバイナリデータを格納する方法を紹介します。まずは JSON データを無視して「バイナリデータだけを新たに格納する場合」は以下のような JSON データを新規作成します(赤字はコメント):
{
  "_id": "D001",  Cloudant 上でのドキュメントID、省略した場合は作成時に自動的に割り振られる
  "_attachments": { この _attachments オブジェクトがバイナリ保存時の肝
    "A001": {     任意に付ける Attachment 名、取り出し時のURLに指定する
      "content_type": "image/jpeg",  バイナリデータの Content-Type
      "data": (バイナリデータを Base64 エンコードしたテキストデータ)
    }
  }
}

上記のデータを(普通の JSON ドキュメントと同様に)以下の URL に対して POST リクエストすると、このバイナリデータを含むドキュメント(と attachment )が新規に Cloudant 内に作成されます:
https://(Cloudant のホスト名)/(データベース名)


また、作成したバイナリデータを取り出す場合は、以下の URL に対して GET リクエストを実行します:
https://(Cloudant のホスト名)/(データベース名)/(ドキュメント ID)/(Attachment 名)


バイナリデータだけのドキュメントを作成する場合は上記の方法でした。一方、バイナリデータも含む JSON データを保存する場合は、以下のような JSON データを用意して、同様に POST します:
{
  "_id": "D001",
  "myname": "abc",   この2つの値が普通の JSON データとして扱われる部分
  "myvalue": 123,
  "_attachments": {
    "A001": { 
      "content_type": "image/jpeg",  
      "data": (バイナリデータを Base64 エンコードしたテキストデータ)
    }
  }
}

取得時には content_type で指定したデータ型が有効になってレスポンスが返ってきます。なので、例えばバイナリデータとして JPEG 画像データを格納し、その際の cotent_type 値に "image/jpeg" などの正しい型が指定されていれば、取得 URL にブラウザでアクセスすればそのまま画像を表示することができます:
2017032102

(↑ Cloudant 上に格納した画像データを直接 URL 指定で表示している様子)


一般的にはファイルなどのバイナリデータをネット上のストレージに格納する場合は Object Storage などを使うことが多いと思っています。が、Content-Type を意識して取り出したり、「(添付ファイルなどの)JSON ドキュメントに紐付いたバイナリデータ」として利用する場合に便利な機能だと思っています。


なお、Cloudant の Attachment 関連 API についてはこちらを参照ください:
https://docs.cloudant.com/attachments.html
 

このページのトップヘ