ニフティクラウドmobile backend (NCMB) エバンジェリストの小山です。
Parse.comのサービス終了日2017年1月28日まで、あと3ヶ月ほどに迫ってきました。すでに代替サービスへの移行作業を進めている方も多いと思います。
今回 NCMB 向けに、Parse.comの データを移行するツール「parse2ncmb」を作成しました。これは Parse.com のエクスポートデータを読み込んで、値を一部修正しながら NCMB のデータストアに書き込むツールです。
その使い方を手順を追って書いていきます。
Parse.com のエクスポートデータを用意する
Parse.com では OSS で公開した Parse Server 向けに、Parse.com のデータをエクスポートする機能を提供しています。以下のやり方でエクスポートデータを取得します。
- Parse.com のダッシュボードから
- 「App Settings」
- → 「General」
- → 「Export app data」
- → 「Export Data」ボタンを押します。
- 「Your app is being exported! We'll email you a link when it's ready.」という
メッセージが表示されるので、登録メールアドレスにリンクが届くのを待ちます。 - メールが届いたら、そこに書かれている URL からデータをダウンロードします。
エクスポートデータは、複数の JSON ファイルをまとめた zip ファイルになっています。
parse2ncmb の準備
- まずは手元に parse2ncmb のコード一式を用意するために、git clone します。
$ git clone git@github.com:NCMBMania/parse2ncmb.git
- 移行先のNCMBアプリの app_key/client_key を config/default.yaml に登録します。
- config-dist.yaml に雛形がありますので、それをコピーして使うと良いでしょう。
$ cd parse2ncmb/config
$ cp config-dist.yaml config.yaml
$ vi config.yaml
config.yaml は以下のようなファイルです。
config:
app_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
client_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- 使用している npm モジュールをインストールします。
$ cd ..
$ npm install
parse2ncmb の実行
parse.com のエクスポートデータを適当なディレクトリに展開します。仮にここでは /var/parse_export としておきます。
$ cd /var/parse_export
$ unzip /some/path/xxxxxxxx-xxxxxxx_export.zip
parse2ncmb ディレクトリに移動してツールを起動します。
DataObject のインポート
Parse.com で登録されていたオブジェクトIDのまま NCMB に登録することはできません。NCMB に登録する際にかならず新規のオブジェクトIDが発行されてしまいますので、Parse と NCMB の2つのオブジェクトIDの対応表を作らなければいけません。その変換処理のために、2段階のフェーズに分けてツールを実行します。
まずはID変換の必要のない DataObject 等のインポートを行います。これには --phase オプションに 1 を指定してコマンドを起動します。
$ cd parse2ncmb
$ ./parse2ncmb --phase 1 /var/parse_export
リレーション、ポインタのインポート
次にID変換の必要なリレーション、ポインター等のインポートを行います。フェーズ1の実行で、db ディレクトリに ID 対応を記述したファイルができていますので、それを読み込んで ID を変換しながら、リレーションとポインタの設定を追加していきます。
$ ./parse2ncmb --phase 2 /var/parse_export
制約事項
parse2ncmb は Parse.com に登録されたデータを全くそのままの形で NCMB データストアに再現するものではありません。仕組み的にどうしても変更を余儀なくされる情報があります。
objectId が変わる。
すでに述べたように、Parse 側の objectId のままでの登録はできませんので、objectId は新規に発行されます。Parse の objectId は parseObjectId という項目に保存されます。
タイムスタンプ
同様に Parse の createdAt, updateAt フィールドは、parseCreatedAt, parseUpdateAt という項目にそれぞれ保存されます。
ポインタについて
Parse のデータモデルでは一つのプロパティに複数のポインタを登録できますが、NCMB では一つのプロパティに登録できるポインタは一つのみです。変換元データに複数のポインタがあった場合は、最初のデータのみポインタとして登録します。
ユーザへのポインタについて
ユーザ情報へのポインタは現時点ではサポートしていません。これは NCMB では新規にユーザを作成した際に、標準で本人のみ読み書き可という ACL が設定されてしまい、そのためポインタの登録ができないためです。
作ってみた感想
Node.js の同期/非同期まわりにはかなり苦労して、当初考えていたよりずいぶん時間がかかってしまいました。基本的には Promise を用いて非同期処理をすればよいわけですが、同時実行数を制限した並列を行おうとして throat を用いたあたりから Promise への内部構造への理解不足が露呈し始め、色んなやり方を試しては思うように動かない試行錯誤を繰り返しました。ある程度複雑な手順をすべて Promise ベースで行うのは、自分には荷が重かったようです。