【问题标题】:Issue dealing with nested dictionary when working with woocommerce api order CSV使用 woocommerce api order CSV 时处理嵌套字典的问题
【发布时间】:2022-01-19 01:30:30
【问题描述】:

我遇到了一个程序问题。我正在使用 woocommere api 从网站导出每日订单,以便自动将它们输入到我们的内部订单系统。目标是获取从 api 生成的 csv,并以一种简单的方式格式化列,以便使用已经编写的 rpg 文件进行抓取。我的问题是,在列 R & S 中有嵌套的字典,我无法访问单元格中的这些键,然后将它们附加到 csv 中。希望这是有道理的,有人可以提供帮助。如有必要,我可以提供更多说明。

'''

import csv

#open a new input file
with open('buckorders.csv', 'r') as csv_file:
    csv_reader = csv.DictReader(csv_file)

    #open new output file
    with open('buck_reformatted_orders.csv', 'w') as new_file:
        #create column headers
        fieldnames = ['id', 'status', 'date_created', 'total', 'line_items', 'billing', 'shipping', 'payment_method', 'payment_method_title']
        csv_writer = csv.DictWriter(new_file, fieldnames=fieldnames)

        #write out the fieldnames
        csv_writer.writeheader()

        for line in csv_reader:

            billing_list = line['billing']
            print(type(billing_list))
            print(billing_list)

            #delete all unneeded columns
            del line['meta_data']
            del line['refunds']
            del line['shipping_tax']
            del line['order_key']
            del line['date_completed_gmt']
            del line['discount_total']
            del line['date_paid_gmt']
            del line['prices_include_tax']
            del line['tax_lines']
            del line['parent_id']
            del line['currency_symbol']
            del line['created_via']
            del line['_links']
            del line['date_modified']
            del line['discount_tax']
            del line['total_tax']
            del line['version']
            del line['date_paid']
            del line['customer_ip_address']
            del line['cart_hash']
            del line['customer_user_agent']
            del line['transaction_id']
            del line['date_completed']
            del line['fee_lines']
            del line['cart_tax']
            del line['currency']
            del line['customer_id']
            del line['customer_note']
            del line['shipping_total']
            del line['date_modified_gmt']
            del line['date_created_gmt']
            del line['shipping_lines']
            del line['coupon_lines']
            del line['number']

            csv_writer.writerow(line)

''' 链接到 csv 的谷歌表: buckorders.csv

【问题讨论】:

    标签: python api csv woocommerce


    【解决方案1】:

    好问题,到目前为止做得很好?

    我看到了尝试解析 billingshipping 列中的嵌套字典的大问题。我还看到,重组流程会对您有所帮助,尤其是所有那些 delete line[col_name] 行。

    我建议不要从阅读器的行开始并尝试删除您不想要的列添加新列,我建议“建立”到您的从无到有的最后一行,只添加您想要的列。这不仅仅是一个建议,如果您要使用 DictWriter 并动态添加嵌套字典中的列,这几乎是必需的。

    我将进一步讨论嵌套的字典,现在我想向您介绍更大的想法:

    import csv
    
    # Keys from DictReader to keep; omitted billing and shipping, don't copy those columns as they are
    fieldnames = ['id', 'status', 'date_created', 'total',
                  'line_items', 'payment_method', 'payment_method_title']
    
    # Accumulate your built-up rows
    new_rows = []
    
    with open('buckorders.csv', newline='') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        for row in csv_reader:
            new_row = {k: row[k] for k in fieldnames}  # build the base for your new row
    
            # Handle nested dicts here... adding to that base row
    
            new_rows.append(new_row)
    
    
    with open('buck_reformatted_orders.csv', 'w', newline='') as csv_file:
        writer = csv.DictWriter(csv_file, fieldnames=new_rows[0].keys())
        writer.writeheader()
        writer.writerows(new_rows)
    

    运行它,您将获得输入 CSV 减去您不想要的所有列。当我运行它时,我得到这些列:

    1: id
    2: status
    3: date_created
    4: total
    5: line_items
    6: payment_method
    7: payment_method_title
    

    对我来说,关键是在创建 DictWriter 时没有为 fieldnames= 参数使用预定义的字段名。您将从这些嵌套的 dicts 中添加很多字段,尝试预先定义所有这些字段并将其传递给 DictWriter 将需要大量工作。

    至于嵌套字典本身...我从 Google 表格下载了您的示例 CSV,如果我看到的正是您所看到的,那么您可能会遇到一些问题,但我不能肯定地说。

    我看到的是一个 Python 字典,字面意思是一个字符串;或者我看到的是 JSON,但所有双引号都转换为单引号。

    你称它为“嵌套字典”,更容易认为它是嵌套字典,所以我会走那条路......

    我检查了这个 SO,Convert a String representation of a Dictionary to a dictionary? 以供参考,我建议你也这样做(如果有帮助,记得点赞!)。正如那篇有用的帖子中所建议的,我将使用 ast.literal_eval 将每个单元格转换回 Python 字典。

    从那里,我可以在 dict 上使用标准的 .items() 方法来迭代一对键和值 (k, v)。我通过在键前面加上shipping_ 来构建一个新的列名,并将新的col_name 及其值添加到新行:

    ...
    for row in csv_reader:
        new_row = {k: row[k] for k in fieldnames}
    
        fixed_shipping = row['shipping'].replace("'", '"')
        shipping_dict = json.loads(fixed_shipping)
        for k,v in shipping_dict.items():
            col_name = f'shipping_{k}'
            new_row[col_name] = v
        
        ...
    ...
    

    其他一切都保持不变。

    当我根据您的输入运行时,我会在重新格式化的 CSV 中获得这些标题:

    1: id
    2: status
    3: date_created
    4: total
    5: line_items
    6: billing
    7: shipping
    8: payment_method
    9: payment_method_title
    10: shipping_first_name
    11: shipping_last_name
    12: shipping_company
    13: shipping_address_1
    14: shipping_address_2
    15: shipping_city
    16: shipping_state
    17: shipping_postcode
    18: shipping_country
    19: shipping_phone
    

    我将把它复制到 billing,并将 csv_reader 的行迭代器添加给您。

    【讨论】:

    • Zach,非常感谢您花时间解释更有效的方法。我可以看到将字段名写入新的 csv 文件是可行的,并且我可以在最终的 for 循环中访问字典键。我将开始处理运输和计费列字典并将这些值分配给新列。如果我再次卡住,如果你有空,我会联系你。再次感谢您,我非常感谢。
    猜你喜欢
    • 2022-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 2019-09-15
    相关资源
    最近更新 更多