Edited at

kintoneへのデータ移行 ~ SDKで文字とファイルを登録 ~

More than 3 years have passed since last update.

システムのデータを移行する際には文字データだけでなく、ファイルデータも移行することが多いと思います。

kintoneではAPIを使うことで文字データだけでなく、ファイルデータも登録できますし、APIの仕様も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

$

上手くいきました!文字だけでなくファイルも登録できました!

result.jpg

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開発者ライセンス

移行の検証にも使える無料の開発者ライセンスはこちら