#python-3.x #csv #neo4j #py2neo
#python-3.x #csv #neo4j #py2neo
Вопрос:
Я выполняю запрос к серверу Neo4J, который, как я ожидаю, вернет gt;100 млн строк (но всего несколько столбцов), а затем запишет результаты в файл CSV. Это хорошо работает для запросов, которые возвращают до 10-20 миллионов строк, но становится сложнее, так как результирующие строки увеличиваются до 10^8 чисел.
Я думал, что запись результатов строка за строкой (в идеале буферизованная) должна быть решением, но csv.Writer
, похоже, запись на диск выполняется только после выполнения всего кода (т. Е. в конце итерации), а не по частям, как ожидалось. В приведенном ниже примере я попытался явно очистить файл (что не сработало). Я также не получаю никаких выходных данных в stdout, указывающих на то, что итерация выполняется не так, как предполагалось.
Однако использование памяти в этом процессе быстро растет, в последний раз я проверял более 12 гб. Это заставляет меня думать, что курсор пытается получить все данные перед началом итерации, чего он не должен делать, если только я чего-то не понял.
Есть какие-нибудь идеи?
from py2neo import Graph import csv cursor = g.run(query) with open('bigfile.csv', 'w') as csvfile: fieldnames = cursor.keys() writer = csv.Writer(csvfile) # writer = csv.DictWriter(csvfile, fieldnames=fieldnames) # writer.writeheader() i = 0 j = 1 for rec in cursor: # writer.writerow(dict(rec)) writer.writerow(rec.values()) i =1 if i == 50000: print(str(i*j) '...') csvfile.flush() i = 0 j =1
Ответ №1:
Разве главная проблема не в размере запроса, а не в способе записи результатов в CSV-файл? Если вы разделяете процесс записи, возможно, вам также следует разделить процесс запроса, поскольку результаты сохраняются в памяти во время записи файла.
Комментарии:
1. Я тоже думал об этом, но это должно быть на сервере, а не на клиенте, верно? На сервере гораздо больше памяти для игры, чем у меня на ноутбуке. Кроме того, фрагментация запроса также не обязательно является тривиальной, так как для того, чтобы использовать комбинацию ПРОПУСКОВ, необходимо УПОРЯДОЧИТЬ, чтобы также сначала требовалась обработка всех записей
2. Если единственной целью сервера является передача данных нескольким клиентам, это может сработать, но в противном случае объем данных может создать большую нагрузку на машину, поэтому могут пострадать другие процессы. Я бы все равно сказал, что лучшим подходом было бы выполнить условный выбор для количества записей, затем разделить его на части и записать результаты на стороне файлового сервера. После этого вы, возможно, захотите также передать содержимое этого временного файла клиенту, так как та же проблема возникнет при передаче данных между сервером и клиентом. В любом случае вы потеряете память или тактовые циклы.