Nano Hash - криптовалюты, майнинг, программирование

Как записать данные в Redshift, которые являются результатом фрейма данных, созданного в Python?

У меня есть фрейм данных в Python. Могу ли я записать эти данные в Redshift как новую таблицу? Я успешно создал соединение БД с Redshift и могу выполнять простые запросы sql. Теперь мне нужно написать на него кадр данных.


  • Может быть, вы можете предоставить код, который у вас есть в настоящее время, чтобы упростить предоставление ответа. 15.07.2016

Ответы:


1

Вы можете использовать to_sql для отправки данных в базу данных Redshift. Я смог сделать это, используя соединение с моей базой данных через механизм SQLAlchemy. Просто не забудьте установить index = False в вызове to_sql. Таблица будет создана, если она не существует, и вы можете указать, хотите ли вы, чтобы вызов заменял таблицу, добавлял к таблице или терпел неудачу, если таблица уже существует.

from sqlalchemy import create_engine
import pandas as pd

conn = create_engine('postgresql://username:[email protected]:5439/yourdatabase')

df = pd.DataFrame([{'A': 'foo', 'B': 'green', 'C': 11},{'A':'bar', 'B':'blue', 'C': 20}])

df.to_sql('your_table', conn, index=False, if_exists='replace')

Обратите внимание, что вам может потребоваться pip install psycopg2, чтобы подключиться к Redshift через SQLAlchemy.

документация по_sql

26.09.2016
  • if_exists='replace' работает на вас? это ничего не делает для меня 10.11.2016
  • Да, если таблица уже существует, содержимое таблицы заменяется содержимым фрейма данных. 10.11.2016
  • @ Эндрю, использует ли метод to_sql в пандах преимущества архитектуры MPP Redshift? Я заметил, что копирование DF с 22 тыс. строк занимает немного времени. 12.01.2017
  • @lollerskates, насколько мне известно, нет. Pandas даже не знает, что он общается с Redshift, поскольку вы передаете объект соединения/движка в метод. Одна из возможных причин медленной вставки заключается в том, что когда pandas отправляет команду SQL, она не выполняет одну вставку с записями 22 КБ; он вставляет каждую запись отдельно. Я смог ускорить процесс, исправив pandas с помощью обезьяны, чтобы она выполняла массовую вставку, как описано здесь: github.com/pandas-dev/pandas/issues/8953 13.01.2017
  • @ Эндрю У меня возникли проблемы с настройкой вашей ссылки postgresql://username:[email protected]:5439/yourdatabase Не могли бы вы предоставить более подробную информацию о том, как заменить каждый элемент, используя мои учетные данные? 29.11.2018

  • 2
    import pandas_redshift as pr
    
    pr.connect_to_redshift(dbname = <dbname>,
                            host = <host>,
                            port = <port>,
                            user = <user>,
                            password = <password>)
    
    pr.connect_to_s3(aws_access_key_id = <aws_access_key_id>,
                    aws_secret_access_key = <aws_secret_access_key>,
                    bucket = <bucket>,
                    subdirectory = <subdirectory>)
    
    # Write the DataFrame to S3 and then to redshift
    pr.pandas_to_redshift(data_frame = data_frame,
                            redshift_table_name = 'gawronski.nba_shots_log')
    

    Подробности: https://github.com/agawronski/pandas_redshift

    02.08.2017

    3

    Я пытался использовать pandas df.to_sql(), но это было очень медленно. Мне потребовалось более 10 минут, чтобы вставить 50 строк. См. эту открытую проблему (на момент написания)

    Я пытался использовать odo из экосистемы blaze (согласно рекомендациям в обсуждении проблемы), но столкнулся с ProgrammingError который я не удосужился исследовать.

    Наконец, что сработало:

    import psycopg2
    
    # Fill in the blanks for the conn object
    conn = psycopg2.connect(user = 'user',
                                  password = 'password',
                                  host = 'host',
                                  dbname = 'db',
                                  port = 666)
    cursor = conn.cursor()
    
    # Adjust ... according to number of columns
    args_str = b','.join(cursor.mogrify("(%s,%s,...)", x) for x in tuple(map(tuple,np_data)))
    cursor.execute("insert into table (a,b,...) VALUES "+args_str.decode("utf-8"))
    
    cursor.close()
    conn.commit()
    conn.close()
    

    Да, старый добрый psycopg2. Это для массива numpy, но преобразование из df в ndarray не должно быть слишком сложным. Это дало мне около 3 тыс. строк в минуту.

    Тем не менее, самое быстрое решение в соответствии с рекомендациями других товарищей по команде — использовать команду COPY после сброса фрейма данных в виде TSV/CSV в кластер S3 и последующего копирования. Вам следует изучить это, если вы копируете действительно огромные наборы данных. (Я обновлю здесь, если и когда попробую)

    18.07.2017
  • таким образом вставьте 100 тыс. строк за 1 минуту 06.02.2019
  • Не могли бы вы объяснить, что нужно поставить на ... места в ваших двух строках args_str и cursor.execute? 16.04.2020
  • Привет @JonasPalačionis, это заполнитель для количества столбцов в ваших данных. Для 2 столбцов это будет (%s,%s), а cursor.execute будет (a,b) при условии, что ваши столбцы называются a и b. 16.04.2020
  • Я получаю эту ошибку при попытке этого sol: SyntaxError: синтаксическая ошибка в таблице LINE 1 или рядом с ней: вставить в таблицу (id, type, customer, customer_id, Generation_d... ^ 22.03.2021

  • 4

    Раньше я полагался на функцию pandas to_sql(), но она слишком медленная. Недавно я переключился на следующие действия:

    import pandas as pd
    import s3fs # great module which allows you to read/write to s3 easily
    import sqlalchemy
    
    df = pd.DataFrame([{'A': 'foo', 'B': 'green', 'C': 11},{'A':'bar', 'B':'blue', 'C': 20}])
    
    s3 = s3fs.S3FileSystem(anon=False)
    filename = 'my_s3_bucket_name/file.csv'
    with s3.open(filename, 'w') as f:
        df.to_csv(f, index=False, header=False)
    
    con = sqlalchemy.create_engine('postgresql://username:[email protected]:5439/yourdatabase')
    # make sure the schema for mytable exists
    
    # if you need to delete the table but not the schema leave DELETE mytable
    # if you want to only append, I think just removing the DELETE mytable would work
    
    con.execute("""
        DELETE mytable;
        COPY mytable
        from 's3://%s'
        iam_role 'arn:aws:iam::xxxx:role/role_name'
        csv;""" % filename)
    
    

    роль должна разрешать доступ Redshift к S3, см. здесь для более подробной информации

    Я обнаружил, что для файла размером 300 КБ (фрейм данных 12000x2) это занимает 4 секунды по сравнению с 8 минутами, которые я получал с помощью функции pandas to_sql().

    10.01.2019

    5

    Для целей этого разговора Postgres = RedShift У вас есть два варианта:

    Вариант 1:

    От Pandas: http://pandas.pydata.org/pandas-docs/stable/io.html#io-sql

    Модуль pandas.io.sql предоставляет набор оболочек запросов, чтобы упростить извлечение данных и уменьшить зависимость от API, специфичного для БД. Абстракция базы данных предоставляется SQLAlchemy, если она установлена. Кроме того, вам понадобится библиотека драйверов для вашей базы данных. Примерами таких драйверов являются psycopg2 для PostgreSQL или pymysql для MySQL.

    Написание фреймов данных

    Предполагая, что следующие данные находятся в данных DataFrame, мы можем вставить их в базу данных, используя to_sql().

    id  Date    Col_1   Col_2   Col_3
    26  2012-10-18  X   25.7    True
    42  2012-10-19  Y   -12.4   False
    63  2012-10-20  Z   5.73    True
    
    In [437]: data.to_sql('data', engine)
    

    В некоторых базах данных запись больших фреймов данных может привести к ошибкам из-за превышения ограничений размера пакета. Этого можно избежать, установив параметр chunksize при вызове to_sql. Например, следующий код записывает данные в базу данных пакетами по 1000 строк за раз:

    In [438]: data.to_sql('data_chunked', engine, chunksize=1000)
    

    Вариант 2

    Или вы можете просто сделать свой собственный. Если у вас есть фрейм данных, называемый данными, просто переберите его, используя iterrows:

    for row in data.iterrows():
    

    затем добавьте каждую строку в свою базу данных. Я бы использовал копирование вместо вставки для каждой строки, так как это будет намного быстрее.

    http://initd.org/psycopg/docs/usage.html#using-copy-to-and-copy-from

    18.07.2016
  • Спасибо за ваш ответ, но фреймы данных создают индексы. Redshift не поддерживает индексы, поэтому не уверен, что мы можем записывать данные в Redshift как dataframe. 18.07.2016

  • 6
  • Я использую то же решение для сброса более миллиона строк. Я разбиваю их на 100 тыс. строк за раз в CSV-файл, а затем использую манифест для импорта на ходу. Единственная проблема в том, что я не смог сжать файлы, чтобы ускорить копирование. 08.03.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..