1

階層データ(JSONに要約されるAVROデータ)を表形式のデータ(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
}

…次のように、顧客ごとに1つの行を出力する必要がある場合があります。

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. すべての行で1つの値を繰り返します:totalItemsFound、すべての行で繰り返されます
  3. 静的データに由来するすべての行で静的な値を繰り返します。マーチャントチャネルが変更されないことはすでにわかっています。
  4. そしてトリッキーなもの:受信データを任意に操作して、目的の出力を生成します。
    • 顧客のIDをnamespace-idに変換します
    • emailOptOut to EMAIL PREFERENCEのように、null/ブール値をy/nに反転して変更します
    • 日付または通貨を(再)フォーマットする

私はjsonpathから始めましたが、それは上記の#1しか解決しません。私は2と3を提供するためにjsonpathの周りにゆっくりと言語を追加してきましたが、4については本当に良い答えがありません(evalを除いて、私は本当にそれをしたくありません)。JSON / Tを調べましたが、そのためのPythonライブラリが見つかりませんでした。XSLTを使用できるようにJSONをXMLに変換するミドルウェアを作成することも真剣に検討しましたが、必死になる前に、ここ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)

ここでrename、古いフィールド名を新しい名前にマップしtransform、フィールドの変換セットに応じてフィールドの値を変換し、defaultこのフィールドに割り当てられる値を返します。

renameそのため、フィールドのリストと関数 ( 、transform、および) を定義するだけで済みますdefault

あなたが与えた例について:

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 に答える