【问题标题】:Loading data from AWS redshift using python使用 python 从 AWS redshift 加载数据
【发布时间】:2019-06-07 04:16:39
【问题描述】:

我面临着一项不可能将大量数据从 Amazone Redshift 提取到另一个表的任务。它肯定需要一种更有效的方法,但我是 SQL 和 AWS 的新手,所以决定向这个聪明的社区寻求建议。

这是我的初始 SQL 查询,需要很长时间:

-- STEP 1: CREATE A SAMPLE FOR ONE MONTH
SELECT DISTINCT at_id, utc_time, name
INTO my_new_table
FROM s3_db.table_x
WHERE type = 'create' 
AND (dt BETWEEN '20181001' AND '20181031');

最好的方法是什么?我正在考虑使用 python 和 sqlalchemy 创建具有 1m 行块的数据帧并将其插入新表(我需要事先创建)。这行得通吗?:

from sqlalchemy import create_engine
import os
import pandas as pd

redshift_user = os.environ['REDSHIFT_USER']
redshift_password = os.environ['REDSHIFT_PASSWORD']

engine_string = "postgresql+psycopg2://%s:%s@%s:%d/%s" \
% (redshift_user, redshift_password, 'localhost', XXXX, 'redshiftdb')
engine = create_engine(engine_string)

for df in pd.read_sql_query("""
                        SELECT DISTINCT at_id, utc_time, name
                        INSERT INTO my_new_table
                        FROM s3_db.table_x
                        WHERE type = 'create' 
                        AND (dt BETWEEN '20181001' AND '20181031');
                       """, engine, chunksize=1000000):

【问题讨论】:

  • 您正在将数据从一个红移表移动到另一个红移表?
  • 是的,没错。
  • 数据库操作最终会比去pandas再回redshift要快,问题是现在需要很长时间吗?
  • 完全正确 - 几乎不可能完成,因为我时不时地弄坏了管道,一切都松了。有没有办法在 SQL 中分块执行?
  • 您需要更详细地了解源表的结构。它是一个实际的 Redshift 表,还是正如名称“s3_db”所暗示的那样,它是一个 Spectrum 表?如果是后者,数据可能作为文件存在于 S3 中,而不是 Redshift 本身,您可以使用其他工具(例如 EMR/Spark、Athena 或 Glue)来创建新数据集。如果它是一个实际的 Redshift 表,那么检查源表的分布键和排序键是什么。如果您可以对排序键应用过滤器,这可能有助于加快查询速度。

标签: python-3.x pandas sqlalchemy amazon-redshift


【解决方案1】:

你应该使用CREATE TABLE AS

这允许您指定SELECT 语句并将结果直接存储到新表中。

非常比下载数据和重新上传更有效。

你也可以CREATE TABLE LIKE,然后用数据加载它。见:Performing a Deep Copy

您也可以将UNLOAD 数据传输到 Amazon S3,然后通过 COPY 再次加载,但使用 CREATE TABLE AS 绝对是最佳选择。

【讨论】:

  • 约翰,这是很好的一般逻辑,但在这种情况下,我的 OP 试图从 s3 复制到 redshift(我们需要澄清)
【解决方案2】:

请参阅 AWS 指南以了解 RedShift 和 Spectrum 最佳实践;我已将链接放在这篇文章的末尾。根据您的问题,我假设您想从基于 RedShift Spectrum 的表“s3_db.table_x”中提取、转换和加载大量数据到新的 RedShift 表“my_new_table”

以下是基于 AWS 建议的一些建议:

  1. 使用适当的分配键、排序键和压缩编码创建您的 RedShift 表。概括地说,“at_id”似乎最适合作为分区键,“utc_time”作为排序键最适合您的要求,但请务必参考 AWS 的 RedShift 表设计指南3

  2. 正如您所提到的,您的数据量很大,您可能希望根据“type”和“dt”列对 S3 源表“s3_db.table_x”进行分区(如频谱中第 4 点所建议的)最佳实践1)。

  3. 在来自 Spectrum 的选择查询中将 DISTINCT 替换为 GROUP BY(Spectrum Best Practices 1 中的第 9 点)。

  4. AWS 建议(Spectrum 最佳实践 1 中的第 7 点)使用 CREATE TABLE AS SELECTSELECT INTO 语句来简化您的 ETL 流程,其中您可以将转换逻辑放在选择组件中以直接加载数据从 S3 到 RedShift。

redshift spectrum best practices

redshift best practices

redshift table design playbook

【讨论】:

    【解决方案3】:

    现在看来,您的源数据存储在 Amazon S3 中,并且您一直使用 Redshift Spectrum 表(指向 S3 中的数据)作为源。

    首选方法是:

    • 使用 Amazon Redshift COPY 命令将数据加载到 Redshift 表中
    • 使用CREATE TABLE AS 命令将数据从新的 Redshift 表中提取 (ETL) 到所需的表中。如果您定期执行此操作,您可以在以后使用TRUNCATEINSERT INTO 重新加载表格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-14
      • 2019-11-12
      相关资源
      最近更新 更多