Kintoneのレコードを全件取得するプログラム【Python】

こんにちは、長塚電話工業所の佐藤です。

ところでみなさん、Kintoneしてますか?

業務アプリを視覚的に作成・操作できるのは非常に便利ですよね。弊社もヘビーユーザーでして、日々色々なチームが活用しております。

使っていく中で、登録したレコードのステータスや期限をユーザーに通知したい場面に遭遇しましたので、今回はそれを解決するプログラムを作成します。

Kintone側の機能にも似たような通知機能はあるのですが、ステータスが変更された瞬間にしかトリガーされなかったり、通知先が限定的だったりします。仕様として、別途プログラム側のDBにレコードを落とし込み、細かい処理を行っていくものになっていくため、より詳細なカスタマイズができるようになっています。

言語はPythonです。

ソースコード詳細

import json
import requests
import pandas as pd
from datetime import datetime

# Kintoneのドメイン、APIトークン、アプリIDを設定
KINTONE_DOMAIN = ‘xxxxxx.cybozu.com’
API_TOKEN = ‘your-api-token’
APP_ID = ‘app-id’
# APIのエンドポイントURL
url = f”https://{KINTONE_DOMAIN}/k/v1/records.json”

# ヘッダー

headers = {

    “X-Cybozu-API-Token”: API_TOKEN,

}

all_records = []

offset = 0

limit = 100  # 最大で一度に取得できるレコード数

while True:

    params = {

        ‘app’: APP_ID,

        ‘query’: f’order by $id asc limit {limit} offset {offset}’,  # クエリを指定

    }

    response = requests.get(url, headers=headers, params=params)

    data = json.loads(response.text)

    if ‘records’ in data:

        records = data[‘records’]

        all_records.extend(records)

        if len(records) < limit:

            break  # レコードがもう存在しない場面でループを抜ける

        offset += limit  # オフセットを更新

    else:

        print(f”Error occurred: {data[‘message’]}”)

        break

# pandas DataFrameに変換

df = pd.DataFrame.from_records(all_records)

for column in df.columns:

    df[column] = df[column].map(lambda x: x[‘value’] if isinstance(x, dict) else x)

print(df)

ちょっとだけ解説

ソースコードはほとんどKintoneのカスタマイズ仕様に則ったお作法のようなものなのですが、APIの呼び出し制限というものがあります。具体的には、一回のリクエストに対して返されるレコード数が500件までという縛りのことです。(参考:https://ascii.jp/elem/000/001/732/1732238/ )

ギリギリを攻めても仕方ないですし、どのみち何回かに分けてループを回すことを考えると、1回のリクエストあたり100件ほど取得できれば良いのではないかと考えました。

その実装が以下になります。While文で、レコードを最後まで読み切るまで.extendメソッドを利用し配列に値を追加します。

while True:

    params = {

        ‘app’: APP_ID,

        ‘query’: f’order by $id asc limit {limit} offset {offset}’,  # クエリを指定

    }

    response = requests.get(url, headers=headers, params=params)

    data = json.loads(response.text)

    if ‘records’ in data:

        records = data[‘records’]

        all_records.extend(records)

        if len(records) < limit:

            break  # レコードがもう存在しない場面でループを抜ける

        offset += limit  # オフセットを更新

    else:

        print(f”Error occurred: {data[‘message’]}”)

        break

私の所属するチームではこの後にもう少しソースコードを追加し、指定した条件に従って特定のユーザーにメールを送る処理を行っています。

Python側にデータを渡すことで、柔軟にカスタマイズができますね。

次回は、こちらのプログラムをAWS上で実行する方法について書いてみます。

ソースコード上で、平文で書かれているパスワードなどを安全に扱うためのベストプラクティスに沿っていきますので、お楽しみに。

今回は以上です。ここまでお読みいただき、ありがとうございました。