2016-10-05 2 views
1

Я пытаюсь экспортировать большой файл из Netezza (используя Netezza ODBC + pyodbc), это решение бросает памятьError, если я петлю без «списка», это ОЧЕНЬ медленно. есть ли у вас какое-либо представление о промежуточном решении, которое не убивает мой сервер/процесс python, но может работать быстрее?Экспорт 2Gb + SELECT в CSV с Python (из памяти)

cursorNZ.execute(sql) 
archi = open("c:\test.csv", "w") 
lista = list(cursorNZ.fetchall()) 
for fila in lista: 
    registro = '' 
    for campo in fila: 
     campo = str(campo) 
     registro = registro+str(campo)+";" 
    registro = registro[:-1] 
    registro = registro.replace('None','NULL') 
    registro = registro.replace("'NULL'","NULL") 
    archi.write(registro+"\n") 

---- Редактировать ----

Спасибо, я пытаюсь это: Где "SQL" является запрос, cursorNZ является

connMy = pyodbc.connect(DRIVER=.....) 
cursorNZ = connNZ.cursor() 

chunk = 10 ** 5 # tweak this 
chunks = pandas.read_sql(sql, cursorNZ, chunksize=chunk) 
with open('C:/test.csv', 'a') as output: 
    for n, df in enumerate(chunks): 
     write_header = n == 0 
     df.to_csv(output, sep=';', header=write_header, na_rep='NULL') 

Имейте это : AttributeError: объект 'pyodbc.Cursor' не имеет атрибута 'cursor' Есть идеи?

+0

Возможный дубликат http://stackoverflow.com/questions/17707264/iterating- over-pyodbc-result-without-fetchall, особенно ссылка на [fetchmany] (http://code.google.com/p/pyodbc/wiki/Cursor#fetchmany). – tdelaney

+1

передайте 'read_sql' ваше соединение. Я отредактирую свой ответ, чтобы отразить это. –

ответ

4

Не используйте cursorNZ.fetchall().

Вместо петли через курсор непосредственно:

with open("c:/test.csv", "w") as archi: # note the fixed '/' 
    cursorNZ.execute(sql) 
    for fila in cursorNZ: 
     registro = '' 
     for campo in fila: 
      campo = str(campo) 
      registro = registro+str(campo)+";" 
     registro = registro[:-1] 
     registro = registro.replace('None','NULL') 
     registro = registro.replace("'NULL'","NULL") 
     archi.write(registro+"\n") 

Лично я бы просто использовать панды:

import pyodbc 
import pandas 

cnn = pyodbc.connect(DRIVER=.....) 
chunksize = 10 ** 5 # tweak this 
chunks = pandas.read_sql(sql, cnn, chunksize=chunksize) 

with open('C:/test.csv', 'a') as output: 
    for n, df in enumerate(chunks): 
     write_header = n == 0 
     df.to_csv(output, sep=';', header=write_header, na_rep='NULL') 
+3

Решение 'pandas' будет иметь большой объем памяти. – tdelaney

+0

@tdelaney 'read_sql' может принимать аргумент' chunksize', который мог бы помочь в этом. –

+2

Но у вас все еще есть 2GB + dataframe в памяти. Преимущество скорости в том, чтобы делать это в «пандах», конечно, возможно, какой-то внешний цикл, который строит меньшие кадры. – tdelaney

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