2017-09-29 8 views
0

私は現在、REST APIからデータをクエリし、その結果の値をCSVに書き込むスクリプトを作成しています。データセットには、数十万のレコードが潜在的に含まれる可能性がありますが、データを100エントリのセットで返します。私の目標は、CSVの各エントリのすべてのキーを含めることです。大きなデータセットのCSVに不明なキーを書き込むにはどうすればよいですか?

は、私が持っているどのようなこれまでのところ(これは、この質問の目的のために単純化された構造である):

import csv 
resp = client.get_list() 

while resp.token: 
    my_data = resp.data 
    process_data(my_data) 
    resp = client.get_list(resp.token) 

def process_data(my_data): 
    #This section should write my_data to a CSV file 
    #I know I can use csv.dictwriter as part of the solution 
    #Notice that in this example, "fieldnames" is undefined 
    #Defining it is part of the question 
    with open('output.csv', 'a') as output_file: 
     writer = csv.DictWriter(output_file, fieldnames = fieldnames) 
     for element in my_data: 
      writer.writerow(element) 

問題:各エントリには、必ずしも同じキーを持っていません。キーを欠いている後のエントリはそれほど大きな取引ではありません。私の問題は、たとえば、全く新しい鍵を導入するエントリ364です。私はと考えられてきた

オプション:

  • 私はCSV出力に読ん新しいキーを、遭遇するたびに、ヘッダに新しいキーを追加し、それぞれの前の行にカンマを追加します。これは、ファイルI/OのTONにつながります。これは避けたいと考えています。
  • CSVに書き込むのではなく、生のJSONをファイルに書き込みます。一方、データを繰り返し処理する間に、すべての既知のキーのリストを構築します。 APIのクエリが終了したら、私が書いたJSONファイルを繰り返し処理し、作成したリストを使用してCSVを作成します。これにより、データ全体で2回の反復が行われ、不必要に複雑に感じられます。
  • 潜在的なキーのリストを事前にハードコードします。このアプローチは、いくつかの理由から不可能です。

これらの解決策のどれも私にとって特に優雅ではありません。それは私の疑問につながります。私がこの問題に近づく良い方法はありますか?私は明白な何かを見落としていますか?

+0

あなたが望むことをするには_requires_少なくとも2回データを渡します。最初はすべての可能なキーを決定し、もう1つはcsvファイルに関連するデータを書き込む。これを最適化するには、効率的なデータ構造を選択して2つのパスの間にデータを格納します(すべてをメモリに格納することはできませんが、最適化は必要ありません)。これを行うコードを記述するのに役立つかもしれない 'tempfile.NamedTemporaryFile()'の使用については、[my answer](https://stackoverflow.com/a/18550652/355230)を参照してください。 – martineau

答えて

1

オプション1と2の両方が妥当と思われます。

作成中にCSVを有効にして読み取り可能にする必要がありますか?そうでない場合は、APIからの読み込みを完了した後に、1回のパスで不足している列を追加することができます(2つの方法の組み合わせのようになります)。これを行う場合は、書き込み中に列の定義が大きくなるので、csv.DictWriterではなく、最初のパスで普通のcsv.writerを使用する必要があります。

全体的なファイルが大きいと予想される場合(例:メモリに収まらない場合)、ソリューションにはおそらくCSVでは簡単なストリーミングアプローチを使用する必要がありますが、JSON 。中間データ(例:XML、BSONなど)のJSONの代替フォーマットを調べることもできます。

関連する問題