Рубрики
Без рубрики

Изящный прием данных с помощью SQLAlchemy и панд

Когда размер данных недостаточно велик для использования платформ распределенных вычислений (например, Apache Spark), обработка данных на машине с пандами является эффективным способом. Но как вставить данные с помощью…

Автор оригинала: Bruce Kuo.

Когда размер данных недостаточно велик для использования платформ распределенных вычислений (например, 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-это мощный способ решить проблему приема данных!