Когда размер данных недостаточно велик для использования платформ распределенных вычислений (например, Apache Spark), обработка данных на машине с пандами является эффективным способом. Но как элегантно вставить данные в объект фрейма данных-это большая проблема. Как мы знаем, python имеет хороший набор инструментов для баз данных SQLAlchemy с хорошей интеграцией ORM и хорошей библиотекой обработки данных Pandas . Здесь мы рассмотрим некоторые различные реализации и обсудим плюсы и минусы в этой статье.
Проблема
С фреймом данных pandas с тысячами данных и сложным типом данных. Как быстро загрузить данные в целевую базу данных, и код должен быть простым в обслуживании.
Примечание. Здесь мы используем PostgreSQL в качестве целевой базы данных.
Простая идея – Используйте функцию Pandas df.to_sql
С помощью этой функции вы можете вставить свои данные с помощью pandas API df.to_sql , после чего вы выполнили работу!
Преимущества
Самый простой способ реализации.
Недостатки
- Очень медленно!
- Если вам нужно сначала усечь таблицу, это не самый разумный способ использовать эту функцию.
Еще Одна Простая Идея – Вставка Данных В CSV-Файлы
Еще одна наивная идея для решения этой проблемы-вывести фрейм данных в виде CSV-файла и использовать команду copy
или ту же реализацию в python для импорта данных в базу данных. Ниже приведен пример кода:
def bulkload_csv_data_to_database(engine, tablename, columns, data, sep=","): logging.info("Start ingesting data into postgres ...") logging.info("Table name: {table}".format(table=tablename)) logging.info("CSV schema: {schema}".format(schema=columns)) conn = engine.connect().connection cursor = conn.cursor() cursor.copy_from(data, tablename, columns=columns, sep=sep, null='null') conn.commit() conn.close() logging.info("Finish ingesting") df.to_csv(csv_path, index=False, header=False) buldload_csv_data_to_database(engine, tablename, columns, data)
Преимущества
Скорость загрузки быстрая!
Недостатки
Необходимо поддерживать и обрабатывать данные в формате CSV, чтобы библиотека целевой базы данных распознала их. Это сводит с ума, когда ваша схема довольно сложна (подумайте о данных с полями и массивами json …). Вам нужно будет очень тщательно рассмотреть формат между df.to_csv
и cursor.copy_from
.
Третья идея – Вставить данные с помощью SQLAlchemy ORM
Чтобы избавиться от огромных усилий по поддержанию формата CSV, другим решением является использование того же метода в Интернете: создание объекта таблицы с строкой pandas и добавление объекта в сеанс один за другим. Ниже приведен простой пример:
Session = sessionmaker(bind=conn) session = Session() for _, row in df.iterrows(): user = User(name=row["name"]) session.add(user) session.commit() session.close()
Преимущества
- Простота в обслуживании
- Наслаждайтесь преимуществами ORM
Недостатки
- Медленно, потому что ему нужно выполнить предложение один за другим.
Четвертая идея – Вставить данные с помощью Pandas и SQLAlchemy ORM
При исследовании документа SQLAlchemy мы обнаружили, что в компоненте SQLAlchemy ORM есть массовые операции . В этом документе мы нашли bulk_insert_mappings
можно использовать список словарей с сопоставлениями. С помощью этого мы можем легко разработать массовую вставку и поддерживаемый код с помощью фрейма данных pandas.
Вот пример кода:
Session = sessionmaker(bind=dest_db_con) session = Session() session.bulk_insert_mappings(MentorInformation, df.to_dict(orient="records")) session.close()
Преимущества
- Быстро
- Простой
- Простота в обслуживании
- Наслаждайтесь преимуществами ORM
Недостатки
С моей точки зрения, никакого беспокойства.
Заключение и обсуждение
Поскольку панды могут обрабатывать данные только на машине, стоит также подумать о том, как решить ту же проблему в распределенных средах. Существует множество фреймворков, таких как Apache Spark, для решения расширенной проблемы.
Но в данных размера одной машины использование pandas + SQLAlchemy-это мощный способ решить проблему приема данных!