python3でjsonファイルを読み込んでCSV形式に変換・出力する方法
概要
jsonファイルを読み込んでCSV形式に変換・出力する方法。
実際に利用したシーンとしては、Trello上のタスクをgoogle spreadsheetに移行するというタスクが発生した時にさくっと書いたものです。
なので、今回はTrelloからExportしたjsonファイルを元に実装します。
開発環境
- MacOS
- python 3.4.3
手順
- 取り出すデータを決める
- jsonの中身を確認
- 実装
取り出すデータを決める
そもそも何のデータを取り出す必要があるのかを決めます。
今回は以下のデータをTrelloから取り出すことにします。
項目名 | 値例 |
---|---|
リスト名 | "進行中"、"ToDo" |
カード名 | "Viewリファクタリング" |
説明 | "View部分のリファクタリングを進めます" |
担当者 | "hanako.yamada" |
更新日時 | "2017-09-15T11:30:46.376Z" |
jsonの中身を確認
欲しいデータが決まったところでTrelloからエクスポートできるjsonを見てみましょう。
{ //board情報
"id": "59b435arfaersgf686c2de62eb9",
"name": "board_name",
"desc": "",
"descData": null,
"closed": false,
...//board情報が続く
"actions": [ //チケット更新情報、今回は使用しない。
{
"id": "59b435arfaersgf686c2de62eb9",
"idMemberCreator": "59b435arfaersgf686c2de62eb9",
"data": {
"list": {
"name": "着手中",
"id": "59b64966caad5d9c7237c292"
},
...//各チケットの更新内容が続く
},
],
"cards": [ //★今回欲しいカード情報、ここから抽出する
{
"id": "59b435arfaersgf686c2de62eb9",
"checkItemStates": null,
"closed": true, //アーカイブされているカードはtrueになってる。
"dateLastActivity": "2017-09-12T01:11:42.261Z", //更新日時
"desc": "", //説明
"descData": null,
"idBoard": "59b435arfaersgf686c2de62eb9",
"idList": "59b435arfaersgf686c2de62eb9", // リストID
"idMembersVoted": [],
"idShort": 73,
"idAttachmentCover": null,
"limits": {
},
"idLabels": [],
"manualCoverAttachment": false,
"name": "Viewリファクタリング", //カード名
"pos": 15fa327,
"shortLink": "4or037I",
"badges": {
},
"dueComplete": false,
"due": null,
"idChecklists": [],
"idMembers": [
"59b75b3254eg6a0a535a2" //メンバーID、今回は担当者の概念
],
...
},
],
"members": [ //メンバー情報
{
"id": "sjfhkaefi738jfrhoiehu", //ID
"avatarHash": "c33cagagecd767a5ae882a5eef5",
"bio": "",
"bioData": null,
"confirmed": true,
"fullName": "hanako.yamada", //名前
"idPremOrgsAdmin": [],
"initials": "HY",
"memberType": "normal",
"products": [],
"status": "disconnected",
"url": "https://trello.com/hanakoyamada",
"username": "hanako.yamada"
},
],
"lists": [ //リスト情報
{
"id": "59b643f2e948122d702be91f", //リストID
"name": "ToDo", //リスト名
"closed": false,
"idBoard": "59ac257d5d0719548db78007",
"pos": 32767.5,
"subscribed": false,
"limits": {
"cards": {
"openPerList": {
"status": "ok",
"disableAt": 4750,
"warnAt": 4500
},
"totalPerList": {
"status": "ok",
"disableAt": 950000,
"warnAt": 900000
}
}
}
},
...
],
}
jsonを見たところ欲しい情報は取れそうなことがわかった。
ただし、担当者(Trelloのメンバー情報)とリスト名は、"members"・"lists"を使って名前を出す工夫が必要。
実装
1. ローカルにあるjsonファイルを読み込む。
import sys
# Load Json File from ComandLine argument
#
with open(sys.argv[1], 'r') as f:
data = json.load(f)
ファイル読み込み
sys.argvで、コマンドライン引数を取り出す事ができます。
例えば、$ python example.py 1
とターミナルで打った場合は、
sys.argvの中身は、["example.py", 1]
となります。
今回は、
$ python xxx.py xxx.json
でjsonファイルを指定する方式にします。
jsonファイルをロードして辞書型に変換
json.load()
を使うことでjsonファイルを扱いやすい辞書型に変換してくれます。
2. 値抽出
辞書型に変換したデータから必要な値を取得していきます。
担当者・リスト名取得
担当者(Trelloのメンバー情報)とリスト名を取得します。
これはカード情報("cards")内にあるIDから名前を逆引きする際の辞書として定義します。
#
# Set members Dictionary
#
members = {}
for member in data['members']:
member_id = member['id']
member_name = member['fullName']
members.update({member_id: member_name})
#
# Set lists Dictionary
#
lists = {}
for list in data['lists']:
list_id = list['id']
list_name = list['name']
lists.update({list_id: list_name})
カード情報を取り出す。
カード情報はcards配下のデータに対してループ処理を行います。
#
# Get cards value
#
tickets = [] #後ほどCSVに書き込む値を格納するための配列
for card in data['cards']:
closed = card['closed']
if (closed == False): #アーカイブされていない生きているカードのみ取得
updated_date = card['dateLastActivity']
desc = card['desc']
card_id = card['id']
title = card['name']
asigned_member_ids = card['idMembers']
list_id = card['idList']
# asigned_member_name
if len(asigned_member_ids) > 0:
asigned_member_id = asigned_member_ids[0] #カードに対して1メンバーのみ紐付いている前提です。
asigned_member_name = members[asigned_member_id]
else:
asigned_member_name = ""
# list_name
list_name = lists[list_id]
tickets.append([list_name, title, desc, asigned_member_name, updated_date])
3. CSV書き込み
抽出した値をCSVに書き込んでいきます。
import csv
#
# Write CSV
#
with open('trello_cards.csv', 'w', newline='') as csvFile:
csvwriter = csv.writer(csvFile, delimiter=',',quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
csvwriter.writerow(['リスト名', 'カード名', '説明', '担当者', '更新日時'])
for ticket in tickets:
csvwriter.writerow(ticket)
以上で完成です・・・!
ターミナル上で、$ python script名 Trelloからexportしたjson
を叩けば実行できます。
実行結果
"リスト名","カード名","説明","担当者","更新日時"
"ToDo","Viewリファクタリング","View部分のリファクタリングを進めます","hanako.yamada","2017-09-15T11:30:46.376Z"
...
最後に、ソースコード全量を以下に載せておきます。
#! /usr/bin/env python
# coding: utf-8
import sys
import json
import csv
#
# Load Json File from ComandLine argument
#
with open(sys.argv[1], 'r') as f:
data = json.load(f)
#
# Set members Dictionary
#
members = {}
for member in data['members']:
member_id = member['id']
member_name = member['fullName']
members.update({member_id: member_name})
#
# Set lists Dictionary
#
lists = {}
for list in data['lists']:
list_id = list['id']
list_name = list['name']
lists.update({list_id: list_name})
#
# Get cards value
#
tickets = []
for card in data['cards']:
closed = card['closed']
if (closed == False):
updated_date = card['dateLastActivity']
desc = card['desc']
card_id = card['id']
title = card['name']
asigned_member_ids = card['idMembers']
list_id = card['idList']
# asigned_member_name
if len(asigned_member_ids) > 0:
asigned_member_id = asigned_member_ids[0]
asigned_member_name = members[asigned_member_id]
else:
asigned_member_name = ""
# list_name
list_name = lists[list_id]
tickets.append([list_name, title, desc, asigned_member_name, updated_date])
#
# Write CSV
#
with open('trello_cards.csv', 'w', newline='') as csvFile:
csvwriter = csv.writer(csvFile, delimiter=',',quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
csvwriter.writerow(['リスト名', 'カード名', '説明', '担当者', '更新日時'])
for ticket in tickets:
csvwriter.writerow(ticket)
ソースコードはGithubにあげてます。