1

我需要将分层数据(AVRO 数据,归结为 JSON)转换为表格数据(csv)。由于 AVRO 有严格的模式,我基本上知道 JSON 将采用什么形式,但我必须为许多不同的模式执行此操作,所以我正在寻找一种一致的、声明性的方式来表达我需要进行的转换。例如,如果我的传入数据看起来像这样……</p>

{
    "customers": [
        {
            "addresses": [
                {
                    "city": "Los Angeles", 
                    "country": "USA", 
                    "county": null, 
                    "postalCode": "90064", 
                    "stateOrProvince": "California", 
                    "street1": "11832 W. Pico Blvd.", 
                    "street2": "", 
                    "street3": "", 
                    "street4": "", 
                    "tags": [
                        "BILLING"
                    ]
                }
            ], 
            "company": "", 
            "dateCreated": "2009-04-24T11:42:31+00:00", 
            "dateOfBirth": null, 
            "doNotCall": null, 
            "email": {
                "emailAddress": "general@magentocommerce.com"
            }, 
            "emailOptOut": null, 
            "fullName": {
                "firstName": "Test", 
                "lastName": "General", 
                "middleName": "", 
                "prefix": "", 
                "suffix": ""
            }, 
            "gender": null, 
            "id": {
                "Id": "2", 
                "namespace": "1000020016"
            }, 
            "lastModified": "2009-05-08T23:33:06+00:00", 
            "primaryPhone": {
                "number": "866.4.VARIEN", 
                "type": "UNKNOWN"
            }, 
            "sourceIds": null
        }
    ], 
    "totalItemsFound": 3
}

…我可能需要为每个客户输出一行,如下所示:

MERCHANT ID|NUM CUSTOMERS|ID|FIRST NAME|LAST NAME|EMAIL|PHONE|STREET|CITY|STATE|ZIP|COUNTRY|EMAIL PREFERENCE
some.merch|3|1000020016-2|Test|General|general@magentocommerce.com|866.4.VARIEN|11832 W. Pico Blvd.|Los Angeles|California|90064|USA|N

我需要能够表达以下内容:

  1. 从给定键中获取所有值作为数组:所有出生日期
  2. 在每一行重复一个值:totalItemsFound,在每一行重复
  3. 在来自静态数据的每一行中重复一个静态值我已经知道商家渠道永远不会改变
  4. 还有一个棘手的问题:任意操纵传入的数据以产生所需的输出:
    • 将客户的 id 转换为 namespace-id
    • 反转 null/boolean 值并将其更改为 y/n,如 emailOptOut 到 EMAIL PREFERENCE
    • (重新)格式化日期或货币
    • ETC

我从jsonpath开始,但这只能解决上面的#1。我一直在慢慢地在 jsonpath 周围添加一种语言来服务 2 和 3,但是对于 4,我真的没有一个好的答案(除了 eval。,我真的很讨厌这样做)。我查看了JSON/T,但找不到它的 python 库。我什至认真考虑过编写一个中间件来将 JSON 转换为 XML,以便我可以使用 XSLT,但我希望 S/O 的某个人在我绝望之前有更好的解决方案。

4

1 回答 1

1

为什么不尝试进行功能分解,这与以下内容不同:

w = csv.writer(...)
for r in records: 
    l = {}
    for field in fields:
        f_ = rename(field)
        v_ = transform(field, r.get(field, default(field)))
        l[f_] = v_
    w.write(l)

whererename将旧字段名称映射到新字段名称,并transform根据字段的转换集转换字段的值,并default返回要分配给该字段的值。

因此,您只需要定义字段列表和函数:renametransformdefault.

对于您给出的示例:

def rename(field):
    t = {'emailOptOut':'EMAIL PREFERENCE'}
    return t.get(field, field)

def transform(field, data):
    t = {'emailOptOut': bool}
    return t.get(field, lambda a: a)(data)

def default(field)
    t = {'MERCHANT ID':11039215}
    return t.get(field, None)
于 2012-06-14T20:29:42.217 回答