pandas .to_sql изтича с RDS

Имам .csv файл с 22 милиона реда (~850mb), който се опитвам да заредя в postgres db на Amazon RDS. Той се проваля всеки път (получавам грешка при изчакване), дори когато разделям файла на по-малки части (всеки от 100 000 реда) и дори когато използвам chunksize.

Всичко, което правя в момента, е да зареждам .csv като рамка с данни и след това да го записвам в db с помощта на df.to_sql(table_name, engine, index=False, if_exists='append', chunksize=1000)

Използвам create_engine от sqlalchemy, за да създам връзката: engine = create_engine('postgresql:database_info')

Тествах писането на по-малки количества данни с psycopg2 без проблем, но отнема около 50 секунди, за да напише 1000 реда. Очевидно за 22 метра редове това няма да работи.

Има ли нещо друго, което мога да опитам?


person e h    schedule 17.05.2015    source източник
comment
Ако просто искате да импортирате csv файла в базата данни, вероятно можете по-добре да използвате командата postgresql COPY, така че нямате нужда от двупосочно пътуване до обекти на python (което го прави по-бавно).   -  person joris    schedule 17.05.2015
comment
Освен това, какъв драйвер използвате? (psycopg2 ?) Тъй като 50s за 1000 реда е много по-бавно от това, което изпитвам с база данни postgres. Така че може би отчасти връзката с базата данни е бавна.   -  person joris    schedule 17.05.2015
comment
благодаря за коментара, опитах да използвам psycopg2. Ще актуализирам въпроса.   -  person e h    schedule 17.05.2015
comment
Изпробвахте ли подхода COPY? Ако не искате да използвате SQL команди, но останете в python, можете да погледнете odo, който използва команда COPY под капака за прехвърляне на данни от CSV към SQL: odo.readthedocs.org/en/latest/index.html   -  person joris    schedule 17.05.2015
comment
За AWS Postgres RDS се нуждаете от командата psql /copy, вижте тук: stackoverflow.com/questions/46969474/   -  person RobinL    schedule 31.10.2017


Отговори (2)


Методът pandas DataFrame.to_sql() е не е специално проектиран за големи вмъквания, тъй като не използва PostgreSQL COPY команда. Редовните SQL заявки могат да изтекат, това не е по вина на pandas, контролира се от сървъра на базата данни, но може да се променя за всяка връзка, вижте тази страница и потърсете „statement_timeout“.

Това, което бих ви препоръчал да направите, е да обмислите използването на Redshift, който е оптимизиран за съхраняване на данни и може да чете огромни изхвърляния на данни директно от S3 кофи с помощта на Копиране с червено отместване.

Ако не сте в състояние да използвате Redshift, все пак бих препоръчал да намерите начин да направите тази операция с помощта на PostgreSQL COPY команда, тъй като е измислена, за да заобиколи точно проблема, който изпитвате.

person firelynx    schedule 18.05.2015
comment
Добре, така че само за да бъде ясно, трябва да изхвърля данните си в кофа S3 и след това да използвам PostgreSQL COPY, нали? - person e h; 18.05.2015
comment
Да, ако командата PostgreSQL COPY ви позволява да посочите s3 контейнер за четене във версията на PostgreSQL, която използвате в RDS. Redshift позволява това и тъй като те са много тясно свързани, трябва да работи. - person firelynx; 18.05.2015

Можете да запишете рамката с данни в cString и след това да запишете това в базата данни, като използвате метода copy_from в Psycopg, който според мен изпълнява командата COPY на PostgreSql, която @firelynx споменава.

import cStringIO
dboutput = cStringIO.StringIO()
output = output.T.to_dict().values()   
dboutput.write('\n'.join([ ''.join([row['1_str'],'\t',
                                    row['2_str'], '\t',
                                    str(row['3_float'])
                                    ])   for row in output]))
dboutput.seek(0)
cursor.copy_from(dboutput, 'TABLE_NAME')
connenction.commit()

където изходът първоначално е рамка от данни на pandas с колони [1_str, 2_str, 3_float], които искате да запишете в базата данни.

person RoachLord    schedule 01.09.2016