当JSON某些记录包含不同的密钥时,如何导出到CSV

问题描述 投票:0回答:1

我正在使用API​​来获取JSON结果,然后转换为CSV。但是,我在结果中看到一些记录缺少密钥。结果是CSV的值已移至错误的列

我已经运行了我的脚本并在Postman中运行了API,并且JSON输出是相同的。我使用https://json-csv.com/将JSON转换为CSV,并将其与我的输出进行比较。 https://json-csv.com/输出显示数据在正确的列中,使我相信在后台有一些代码检测到缺少的键/值,并用空值填充它。

import json
import requests
import csv

def get_data():
    group_id = 9039
    api_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
    api_url = 'https://api.samsara.com/v1'
    endpoint_url = api_url + '/fleet/drivers'

    my_params = {"access_token": api_token}
    my_data = {"groupId": group_id}
    resp = requests.post(url = endpoint_url, params = my_params, json = my_data)
    array = resp.json()
    text = json.dumps(array)

    return text


def write_file(filename, text):
    dataset = json.loads(text)
    drivers = dataset['drivers']

    csvFile = open(filename,'w')
    csvwriter = csv.writer(csvFile)

    # write header
    if len(drivers) > 0:
        keys = drivers[0].keys()
        csvwriter.writerow(keys)

    # write data
    for line in drivers:
       csvwriter.writerow(line.values())

    csvFile.close()

text = get_data()
write_file('drivers.csv', text)

从JSON输出,这是一个部分结果。

{
    "drivers": [
        {
            "id": 158830,
            "groupId": 9039,
            "vehicleId": 212014918234731,
            "currentVehicleId": 212014918431705,
            "username": "rdoherty",
        },
        {
            "id": 134808,
            "groupId": 9039,
            "vehicleId": null,
            "username": "sbermingham",
        }

    ]
}

请注意,第二个记录没有“currentVehicleId”键:值。结果是,当我转换为CSV时,如果存在缺失值,则所有其他值都将移动到应该位于其左侧的列。

id  groupId vehicleId   currentVehicleId    username
158830  9039    2.12015E+14 2.12015E+14 rdoherty
134808  9039    null    sbermingham 

我希望CSV转换确保所有缺少的值都替换为null。

python-3.x export-to-csv
1个回答
1
投票

我建议修改字典并为任何缺失的键插入drivers[key] = Nonedrivers[key] = ''

第1步:获取所有可能的密钥

如果您已经知道所有可能的按键,这很容易。只需将所有键存储在列表中即可。 如果没有,您将必须遍历每个驱动程序并找到所有唯一键。

# write header
driver_keys = []
for d in drivers:
    for key in d.keys():
        if key not in driver_keys:
            driver_keys.append(key)
csvwriter.writerow(driver_keys)

第2步:随时将空值添加到每一行。由于我们每次都在相同的列表上进行迭代(而不是修改它),我们可以保证相同的顺序,因此值应该与列标题匹配。

# write data
for line in drivers:
    for key in driver_keys:
        if key not in line.keys():
            line[key] = None  # or line[key] = '' if you like
    csvwriter.writerow(line.values())

csvFile.close()
© www.soinside.com 2019 - 2024. All rights reserved.