2016-08-18 3 views
0

У меня есть 1.6 ГБ для использования в процессе python. Я пишу большой файл csv, данные которого поступают из базы данных. Проблема заключается в следующем: после записи файла память (> 1,5 ГБ) не будет выпущена немедленно, что приведет к ошибке в следующем бите кода (выделение памяти не удастся из-за того, что ОС не может найти достаточно памяти для выделения).Как я могу освободить память после использования csv.writer в python?

Существует ли какая-либо функция, которая поможет мне освободить эту память? Или у вас есть лучший способ сделать это?

Это сценарий, я использую для записи файла, пишет на куски, чтобы иметь дело с проблемой памяти:

size_to_read = 20000 
sqlData = rs_cursor.fetchmany(size_to_read) 

c = csv.writer(open(fname_location, "wb")) 
c.writerow(headers) 

print("- Generating file %s ..." % out_fname) 

while sqlData: 
    for row in sqlData: 
    c.writerow(row) 
    sqlData = rs_cursor.fetchmany(size_to_read) 
+0

Является ли код ошибкой после последней строки? или это последняя строка, на которой он ошибается? – Adam

+0

Нет, это идет hundres строк вниз, которые используют низкую память, и ошибка появляется в этой строке: file_obs = int (subprocess.check_output (["cat% s /% s | wc -l"% (locationToUpload, filename)], shell = True)) – ebertbm

+0

Возможно, я ошибаюсь, но ... 'sqlData = rs_cursor.fetchmany (size_to_read)' в последней строке? Все, что вы только что написали в файле (который вы еще не закрыли), вы загружаете все это снова? – roganjosh

ответ

1

Я имею в виду вопрос в том, что вы никогда не закрыли файл. Сделайте это выстрелом.

size_to_read = 20000 
sqlData = rs_cursor.fetchmany(size_to_read) 

with open(fname_location, "wb")) as f: 
    c = csv.writer(f) 
    c.writerow(headers) 

print("- Generating file %s ..." % out_fname) 

while sqlData: 
    with open(fname_location, "a") as f: # "a" means to append 
     c = csv.writer(f) 
     for row in sqlData: 
      c.writerow(row) 
    sqlData = rs_cursor.fetchmany(size_to_read) 

С помощью with вы автоматически закрывает файл и освобождает память. Избегает явного называть c.close()

Кроме того, я полагаю, вы можете избежать цикл, как так ...

while sqlData: 
    with open(fname_location, "wb") as f: 
     c = csv.writer(f) 
     c.writerows(sqlData) # .writerows 
    sqlData = rs_cursor.fetchmany(size_to_read) 

Трудно повторить, так как у меня нет данных :(

EDIT

Я знаю, что это не совсем ответ, но проверить пакет memory_profiler, чтобы сделать линию по оценке линии, чтобы увидеть, где вы используете много мем. https://pypi.python.org/pypi/memory_profiler

EDIT 2

Вот пример использования генератора, чтобы держать использование памяти низко.

def results_iter(cursor, n=10000): 
    while True: 
     results = cursor.fetchmany(n) 
     if not results: 
      break 
     for result in results: 
      yield result 

with open('file.csv') as f: 
    c = csv.writer(f) 
    for result in results_iter(rs_cursor, size_to_read) 
     c.writerow(result) 

через http://code.activestate.com/recipes/137270-use-generators-for-fetching-large-db-record-sets/

Если все это работает, дайте нам знать!

+0

Да, я действительно не знаю, возможно, как я сказал, не знаю, как выглядят данные. Или что он означает 'size_to_read'. но спасибо за проголосовать! – Adam

+0

Я бы сказал, многократно открывая его в случае событий между ними (т. Е. Захватывая больше данных), занимая тонну памяти и разбивая приложение. Но да, сфера охвата петель сбивает с толку. И публикация чего-то неправильного имеет ценность, потому что люди могут выбрать проблемы, о которых вы не думали. – Adam

+0

В принципе, я использую цикл, потому что без него в процессе записи файла будет отсутствовать память. Итак, у меня была идея написать куски данных, как только все будет завершено. Size_to_read - это количество строк, которые записывает процесс для каждого цикла. – ebertbm

Смежные вопросы