システムのデータを移行する際には文字データだけでなく、ファイルデータも移行することが多いと思います。
kintoneではAPIを使うことで文字データだけでなく、ファイルデータも登録できますし、APIの仕様もdeveloper networkに掲載されています。
ただ、具体的な移行スクリプトの例がないので作ってみました。
- developer networkの説明
前提
今回はPHPとkintone API用のSDK(cybozu-http)を利用します。
- プログラムの実行環境(今回はRedhatを利用)
- PHP5.5以降がインストール済
- cybozu-httpがインストール済
- kintoneのフォーム設定は以下の通り
フィールド名 | フィールドタイプ | フィールドコード |
---|---|---|
登録日 | 日付 | date |
担当者 | ユーザー選択 | pic |
タイトル | 文字列(1行) | title |
添付ファイル | 添付ファイル | attacheFile |
- フォルダ構成は以下の通り
$ find ./migration.php ./migration -type f
./migration.php
./migration/2016-03-01/01/ex/IMG_0950.JPG
./migration/2016-03-01/01/プレゼンテーション.pptx
./migration/2016-03-01/01/info.csv
./migration/2016-03-02/01/IMG_0555.JPG
./migration/2016-03-02/01/info.csv
./migration/2016-03-02/02/ex/出張報告.xlsx
./migration/2016-03-02/02/info.csv
$ cat ./migration/2016-03-01/01/info.csv
"kintoneプレゼン","momota|tamai","ex/IMG_0950.JPG|./プレゼンテーション.pptx"
$ cat ./migration/2016-03-02/01/info.csv
"タイトルだよ""も大丈夫だよ","momota","./IMG_0555.JPG"
$ cat ./migration/2016-03-02/02/info.csv
"ガルーン新規構築","tamai","ex/出張報告.xlsx"
-
フォルダ構成の説明
- migration.phpが実行ファイル
- migrationフォルダ配下の年月日をフィールド「登録日」に登録
- info.csvにその他フィールドに登録する情報を記載
- info.csvの1列目はフィールド「タイトル」に登録
- info.csvの2列目はフィールド「担当者」に登録(複数の場合は「|」区切り)
- info.csvの3列目は添付ファイルへの相対パスで、フィールド「添付ファイル」にファイルの実体を登録(複数の場合は「|」区切り)
migration.phpのソースは以下の通り
migration.php
#!/usr/bin/env php
<?php
require 'vendor/autoload.php';
// 移行対象ディレクトリ
$migrationDir = './migration';
// cybozu.comのサブドメイン
$subDomain = 'xxxxxxxx';
// アプリID
$appId = 'oo';
// APIトークン
$apiToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$api = new \CybozuHttp\Api\KintoneApi(\CybozuHttp\Client::factory([
'domain' => 'cybozu.com',
'subdomain' => $subDomain,
'use_api_token' => true,
'token' => $apiToken
]));
$infoFileList = searchInfoFile($migrationDir);
foreach ($infoFileList as $infoFile) {
$pathList = explode(DIRECTORY_SEPARATOR, $infoFile);
$date = array_slice($pathList, -3)[0];
$csvFile = new SplFileObject($infoFile);
$csvFile->setFlags(SplFileObject::READ_CSV);
foreach ($csvFile as $row) {
// 空行はスキップ
if(is_null($row[0])) {
continue;
}
$title = $row[0];
$picList = $row[1];
$attacheList = $row[2];
$postRecord = [
'date' => [
'value' => $date
],
'title' => [
'value' => $title
],
'pic' => [
'value' => []
],
'attacheFile' => [
'value' => []
]
];
foreach (explode('|', $picList) as $pic) {
$postRecord['pic']['value'][] = ['code' => $pic];
}
foreach (explode('|', $attacheList) as $attache) {
$attacheFilePath = dirname($infoFile) . DIRECTORY_SEPARATOR . $attache;
$fileKey = $api->file()->post($attacheFilePath);
$postRecord['attacheFile']['value'][] = ['fileKey' => $fileKey];
}
$postRes = $api->record()->post($appId, $postRecord);
if (array_key_exists('revision', $postRes) !== true) {
echo 'ERROR' . $res;
}
}
}
// 移行対象ディレクトリ配下のinfo.csvを探索
function searchInfoFile($dir) {
$iterator = new RecursiveDirectoryIterator($dir);
$iterator = new RecursiveIteratorIterator($iterator);
$list = [];
foreach ($iterator as $fileinfo) {
if (($fileinfo->isFile()) && ($fileinfo->getfilename() === 'info.csv')) {
$list[] = $fileinfo->getPathname();
}
}
return $list;
}
?>
結果
migration.phpを実行すると・・・
$ ./migration.php
$
100行に満たないプログラムで特定ディレクトリ配下にあるデータを移行することができました。
簡単そうですよね。(エラー処理は入っていませんが・・・)
参考
ネットワークの転送速度にかなり依存しますが、参考までに登録にかかる時間を計ってみました。
-
100レコード、100ファイル(計150Mbyte)の登録にかかった時間
- 1回目 :24秒
- 2回目 :23秒
- 3回目 :25秒
- 3回の平均:24秒
-
100レコード、100ファイル(計7300Mbyte)の登録にかかった時間
- 1回目 :434秒
- 2回目 :434秒
- 3回目 :426秒
- 3回の平均:432秒
※APIを連続で実行する場合、可能であればアプリグループをPrivateにして実行しましょう。
PrivateアプリはAPIの実行回数にカウントされません。
kintone開発者ライセンス
移行の検証にも使える無料の開発者ライセンスはこちら