df_name.to_sql('table_name',
schema = 'public',
con = engine,
index = False,
if_exists = 'replace')
Я пишу фрейм данных на 500 000 строк в базу данных postgres AWS, и на проталкивание данных уходит очень и очень много времени.
Это довольно большой SQL-сервер, и у меня отличное интернет-соединение, поэтому я исключил их как способствующие возникновению проблемы.
Для сравнения, csv2sql или использование cat и piping в psql в командной строке намного быстрее.
см. здесь: http://stackoverflow.com/questions/33816918/write-large-pandas-dataframes-to-sql-server-database
с SQLServer вам нужно импортировать через csv с массовой загрузкой для эффективности
вы можете найти это полезным: http://odo.pydata.org/en/latest/perf.html
ODO не работает для меня, он генерирует ошибки, которые я не смог исправить, но d6tstack работал нормально https://github.com/d6t/d6tstack/blob/master/examples-sql.ipynb. Вы можете выполнить предварительную обработку с помощью pandas, и он использует postgres COPY FROM для быстрого импорта. Хорошо работает с RDS postgres.
Добавьте этот код под engine = create_engine(connection_string)
:
from sqlalchemy import event
@event.listens_for(e, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
if executemany:
cursor.fast_executemany = True
cursor.commit()
В моем коде функция to_sql
выполнялась 7 минут, а теперь она занимает всего 5 секунд;)
Спасибо @llautert!
Это очень помогло!
# dont forget to import event
from sqlalchemy import event, create_engine
engine = create_engine(connection_string)
@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
if executemany:
cursor.fast_executemany = True
cursor.commit()
Я попытался запустить это исправление, но получил сообщение об ошибке:
AttributeError: 'psycopg2.extensions.cursor' object has no attribute 'fast_executemany'
Кто-нибудь знает, что происходит?
Привет, @ tim-sauchuk, тоже столкнулся с той же ошибкой, хотя я нашел решение, которое отлично работает, которое включает в себя небольшое редактирование файла pandas.io.sql.py (просто удалите файл .pyc из __pycache__ перед повторным импортом чтобы убедиться, что он записывает новую версию в сжатый файл)
Привет, @ tim-sauchuk, тоже столкнулся с той же ошибкой, хотя я нашел решение, которое отлично работает, которое включает в себя небольшое редактирование файла pandas.io.sql.py (просто удалите файл .pyc из pycache перед
8953
Проблема № 8953, упомянутая @ bsaunders23, также показывает способ «обезьяньего патча» (исправления во время выполнения). Я попробовал, и набор данных из 20 тыс., Загрузка которого заняла 10+ минут, заняла всего 4 секунды.
Спасибо @llautert!
Это очень помогло!# dont forget to import event from sqlalchemy import event, create_engine engine = create_engine(connection_string) @event.listens_for(engine, 'before_cursor_execute') def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany): if executemany: cursor.fast_executemany = True cursor.commit()
Кто-нибудь знает, как я могу реализовать это решение внутри класса с экземпляром self.engine?
Кто-нибудь знает, как я могу реализовать это решение внутри класса с экземпляром self.engine?
Работает для меня, ссылаясь на self.engine
Пример:
self.engine = sqlalchemy.create_engine(connectionString, echo=echo)
self.connection = self.engine.connect()
@event.listens_for(self.engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
print("Listen before_cursor_execute - executemany: %s" % str(executemany))
if executemany:
cursor.fast_executemany = True
cursor.commit()
У меня не работает. Какие панды и версию sqlalchemy вы используете?
Я пробовал запускать sqlalchemy: 1.2.4-py35h14c3975_0 и 1.2.11-py35h7b6447c_0
но я получаю
AttributeError: объект 'psycopg2.extensions.cursor' не имеет атрибута 'fast_executemany'
@ dean12 @llautert
Как в этом контексте выглядит вызов функции? Или, другими словами, что вы используете в качестве аргументов для успешной загрузки таблицы?
<# dont forget to import event
from sqlalchemy import event, create_engine
engine = create_engine(connection_string)
@event.listens_for(engine, 'before_cursor_execute')
def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany):
if executemany:
cursor.fast_executemany = True
cursor.commit()>``
Я пробовал запускать sqlalchemy: 1.2.4-py35h14c3975_0 и 1.2.11-py35h7b6447c_0
но я получаю
AttributeError: объект 'psycopg2.extensions.cursor' не имеет атрибута 'fast_executemany'
Вы используете psycopg2, драйвер postgresql. Эта проблема и исправление относятся к Microsoft SQL Server с использованием драйвера pyodbc.
как насчет добавления параметра 'dtype'
Кто-нибудь знает, как я могу реализовать это решение внутри класса с экземпляром self.engine?
Работает для меня, ссылаясь на
self.engine
Пример:
self.engine = sqlalchemy.create_engine(connectionString, echo=echo) self.connection = self.engine.connect() @event.listens_for(self.engine, 'before_cursor_execute') def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany): print("Listen before_cursor_execute - executemany: %s" % str(executemany)) if executemany: cursor.fast_executemany = True cursor.commit()
Вы узнали как?
Я думаю, что правильным ответом должно быть использование https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2 -batch-mode-fast-execution, если вы пытаетесь сэкономить pandas dataframe
в postgres
Новая версия pandas содержит параметр method
который можно выбрать как "multi". Это заставляет код работать намного быстрее.
fast_executemany
теперь можно выполнить за один шаг (sqlalchemy> = 1.3.0):
engine = sqlalchemy.create_engine(connection_string, fast_executemany=True)
Может, стоит упомянуть об этом где-нибудь в документации или на примере? Это частный случай, не связанный с пандами, но это небольшое дополнение, которое во многих случаях может значительно улучшить производительность.
Новая версия pandas содержит параметр
method
который можно выбрать как "multi". Это заставляет код работать намного быстрее.
Вы могли подумать, что установки параметра chunksize
будет достаточно для выполнения пакетной вставки to_sql
но нет.
Альтернативой для пользователей MS SQL является также использование turbodbc.Cursor.insertmanycolumns
, я объяснил это в связанной публикации StackOverflow: https://stackoverflow.com/a/62671681/1689261
Будущим читателям предлагается два варианта использования batch_mode для to_sql. Ниже приведены две комбинации:
create_engine(connection_string, executemany_mode='batch', executemany_batch_page_size=x)
или же
create_engine(connection_string, executemany_mode='values', executemany_values_page_size=x)
Подробную информацию об этих аргументах можно найти здесь: https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2 -fast-execution-helpers
Для пользователей postgres я рекомендую установить method
на вызываемый объект:
вызываемый с подписью (pd_table, conn, keys, data_iter): это можно использовать для реализации более производительного метода вставки, основанного на определенных функциях внутреннего диалекта.
и вызовите функцию из примера кода здесь https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#insertion -method и
Использование COPY FROM
действительно намного быстрее 🚀
Самый полезный комментарий
Добавьте этот код под
engine = create_engine(connection_string)
:В моем коде функция
to_sql
выполнялась 7 минут, а теперь она занимает всего 5 секунд;)