Итак ... Проблема заключается в том, что csv
писатель не понимает понятие "subdictionaries", как Монго возвращает его.
Если я правильно понял, то при запросе Монго, Вы получаете словарь, как это:
{
"_id": "a hex ID that correspond with the record that contains several answers",
"answers": [ ... a list with a bunch of dicts in it... ]
}
Так что, когда csv.DictWriter
пытается писать, что это только писать один словарь (самый верхний). Он не знает (или не заботится) о том, что answers
- это список, содержащий словари, значения которых также должны быть записаны в столбцах (доступ к полям в словарях с использованием точечной нотации, такой как answers.order
, понимается только Монго, а не автором csv)
Насколько я понимаю, вы должны сделать так, чтобы «пройти» список ответов и создать один словарь из каждой записи (каждого словаря) в этом списке. Если у вас есть список «сплющенные» словарей, которые вы можете передавать их и записать их в файл csv
:
cursor = client.stack_overflow.stack_039.find(
{}, {'_id': 1, 'answers.order': 1, 'answers.text': 1, 'answers.answerId': 1})
# Step 1: Create the list of dictionaries (one dictionary per entry in the `answers` list)
flattened_records = []
for answers_record in cursor:
answers_record_id = answers_record['_id']
for answer_record in answers_record['answers']:
flattened_record = {
'_id': answers_record_id,
'answers.order': answer_record['order'],
'answers.text': answer_record['text'],
'answers.answerId': answer_record['answerId']
}
flattened_records.append(flattened_record)
# Step 2: Iterate through the list of flattened records and write them to the csv file
with open('stack_039.csv', 'w') as outfile:
fields = ['_id', 'answers.order', 'answers.text', 'answers.answerId']
write = csv.DictWriter(outfile, fieldnames=fields)
write.writeheader()
for flattened_record in flattened_records:
write.writerow(flattened_record)
Whatch для использования существительных. answers_record
отличается answer_record
Это создает файл, как это:
$ cat ./stack_039.csv
_id,answers.order,answers.text,answers.answerId
580f9aa82de54705a2520833,0,{u'en': u'Yes'},527d65de7563dd0fb98fa28c
580f9aa82de54705a2520833,1,{u'en': u'No'},527d65de7563dd0fb98fa28b
EDIT:
Ваш запрос (тот, который делает cursor = db.questions.find ({},{'_id':1, 'answers.order':1, 'answers.text':1, 'answers.answerId':1})
) вернет все записи в questions
коллекции. Если эта коллекция очень большая, вы можете использовать cursor
как iterator.
Как вы, возможно, уже поняли, первый цикл for
в моем коде выше помещает все записи в список (список flattened_records
). Вы можете выполнять ленивую загрузку, итерации через cursor
(вместо того, чтобы загружать все элементы в памяти, извлекать их, делать с ними что-то, получать следующее, что-то делать с ним ...).
Это немного медленнее, но больше памяти.
cursor = client.stack_overflow.stack_039.find(
{}, {'_id': 1, 'answers.order': 1, 'answers.text': 1, 'answers.answerId': 1})
with open('stack_039.csv', 'w') as outfile:
fields = ['_id', 'answers.order', 'answers.text', 'answers.answerId']
write = csv.DictWriter(outfile, fieldnames=fields)
write.writeheader()
for answers_record in cursor: # Here we are using 'cursor' as an iterator
answers_record_id = answers_record['_id']
for answer_record in answers_record['answers']:
flattened_record = {
'_id': answers_record_id,
'answers.order': answer_record['order'],
'answers.text': answer_record['text'],
'answers.answerId': answer_record['answerId']
}
write.writerow(flattened_record)
Он будет производить тот же .csv
файл, как показано выше.
Не могли бы вы изменить свой вопрос, чтобы показать правильно отформатированный код? Кроме того, это поможет, если вы добавите пример того, как выглядят данные, которые вы получаете от Mongo. – BorrajaX
, пожалуйста, помогите мне. – user7070824