Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?
@YoshihikoTakeuchi

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

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

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

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
7
Help us understand the problem. What is going on with this article?