将新列从另一个表连接到 redshift/sql 表

Posted

技术标签:

【中文标题】将新列从另一个表连接到 redshift/sql 表【英文标题】:join new columns to redshift/sql table from another table 【发布时间】:2019-03-05 14:52:33 【问题描述】:

我是 sql/redshift 的新手,正在寻找合并到表的最佳方法。

我有一个红移的大(ish)表(大约 2k 列乘 50k 行)。该表有一个日期时间排序键。我将 sortkey 和其他 1 列迭代地拉入 python/pandas 数据框中,执行一些(相当复杂的)操作来生成新列。然后我将这个 pandas 数据框转换为另一个 redshift 表,我想将它与原始表合并,以便只附加新列(尽管如果整个事情被更新并不重要)。两个表都有相同的排序键,这应该很简单吧?只是基本上添加了一些新列? (请原谅我的幼稚)

表1

datetime, rainfall, windspeed, cloudcover
2000-01-01,5,5,5
2000-01-02,7,5,5
2000-01-03,1,5,5
2000-01-04,0,5,5

pandasdf1

datetime, rainfall, rainfall_movingAverage, other_calculation
2000-01-01,5,5,NaN
2000-01-02,7,6,4.56
2000-01-03,1,4.3,7.53
2000-01-04,0,3.75,3.55

这是我想要实现的目标:

datetime, rainfall, windspeed, cloudcover,rainfall_movingAverage, other_calculation
2000-01-01,5,5,5,5,NaN
2000-01-02,7,5,5,6,4.56
2000-01-03,1,5,5,4.3,7.53
2000-01-04,0,5,5,3.75,3.55

在 pandas 中,这非常简单,可以通过多种方式完成,其中一种方式是:

result = pd.concat([table1, pandasdf1], axis=1, sort=True)

但是,数据框的大小正在使 pandas 崩溃,并且数据会变得比现在大得多,因此我不得不将其迁移到 redshift。我尝试使用此命令进行合并:

SELECT * FROM table1
FULL OUTER JOIN pandasdf ON (table1.datetime = pandasdf.datetime)

这似乎有效(至少不会崩溃或返回错误),但原始表未更新。我似乎找不到额外的语法来更新原始表。请注意,我正在使用 python sql 引擎与 redshift 进行交互

import psycopg2
SQL="""
SELECT * FROM table1
FULL OUTER JOIN pandasdf ON (table1.datetime = pandasdf.datetime)
"""
def merge_redshift_tables(SQL):
    """merge the left and right tables"""
    success=False
    try:
        conn=None
        """Establish a connection to redshift"""
        conn=psycopg2.connect(dbname= 'mydb', host='myIP', port= 'myport', user= 'myusername', password= 'mypassword')
        """make a cursor object"""
        cur = conn.cursor()       
        cur.execute(SQL)
        success=True
    except psycopg2.Error as e:
        print(e)
    finally:
        if conn is not None:
            conn.close()

    return success

如果有人可以帮助我完成这一步,那将是很好的第一步。但是,我不确定这是否是对大约 2000 列中的每一列执行此类操作的最佳方法,因此如果有人可以分享一些关于最佳实践的智慧,那么我也将非常感激。我大致计划将工作分布在多个并行工作的计算节点上,但这取决于红移平滑合并所有这些新列的能力(我知道这可能是一个问题)。非常欢迎任何有关该领域最佳实践的建议。

非常感谢

##### 编辑

以下似乎运行没有错误,表明已成功创建具有所需列的新表:

SELECT t1.*, t2.new_col
INTO TABLE combined FROM table1 t1
LEFT JOIN pandasdf1 t2 ON t1.datetime = t2.datetime;

但是当我查询它返回一个错误提示没有新表:

def get_col(table, col='*'):
    """Gets all data from a column from a table"""
    coldata=None
    try:
        conn=None
        """Establish a connection to redshift"""
        conn=psycopg2.connect(dbname= 'mydb', host='myIP', port= 'myport', user= 'myusername', password= 'mypassword')
        coldata = pd.read_sql("select  FROM ".format(col, table), conn).set_index('gmt_reportedtime').dropna()
    except psycopg2.Error as e:
        print(e)
    finally:
        if conn is not None:
            conn.close()
    return coldata

check = get_col('combined')

返回:

pandas.io.sql.DatabaseError: Execution failed on sql 'select * FROM combined': relation "combined" does not exist
编辑

我现在已经解决了这个问题!使用 python 语句需要提交更改:

conn.commit()

【问题讨论】:

为什么有这么多列?您可以/应该将列转换为行吗? 它只是数据的大小,只是为了提供一些背景知识,我更习惯于使用数据框而不是数据库,我感觉它们彼此根本不同? 不是从根本上说,但通常会标准化表格,尤其是当您有 col1 col2 col3 col4 等时 - 您将创建一个新列并进行数据透视 你能解释一下你所说的标准化是什么意思吗? 你能分享一下你桌子上列的名字吗?我可以以此为例。 【参考方案1】:

你可以用这个命令“原始表没有更新”:

SELECT * FROM table1
FULL OUTER JOIN pandasdf ON (table1.datetime = pandasdf.datetime)

SQL 中的SELECT 命令返回 数据。它更新数据。

如果您想创建一个新的组合表,您可以使用:

SELECT *
INTO TABLE combined
FROM table1
JOIN pandasdf ON (table1.datetime = pandasdf.datetime)

见:SELECT INTO - Amazon Redshift

您需要使用新表,因为“原始”table1 仅定义为具有原始 4 列。虽然您可以修改表、添加列,然后运行 ​​UPDATE 命令,但创建一个新表是一个更好的主意(并且对于 Amazon Redshift 更有效)。

【讨论】:

感谢您的帮助,这似乎是我需要做的,但它给了我一个错误:pandas.io.sql.DatabaseError: Execution failed on sql 'select * FROM combined': 关系“组合“ 不存在。有没有办法在填充表格的同时动态创建表格? 当我尝试取回“组合”表时发生上述错误。上面的命令返回这个错误:psycopg2.ProgrammingError: relation "combined" does not exist 您是在提交还是自动提交您的更改?见:Python psycopg2 not inserting into postgresql table 再次感谢您的帮助,python 代码中有一条 no commit 语句导致错误,无论是 commit 还是 autocommit 都可以正常工作。

以上是关于将新列从另一个表连接到 redshift/sql 表的主要内容,如果未能解决你的问题,请参考以下文章

如何向 pandas df 添加一个新列,该列从另一个数据帧返回同一组中更大的最小值

我们可以从另一个数据框向数据框添加新列吗

将 Pyspark Dataframe 列从数组转换为新列

基于另一列从一列中删除单词,然后创建并将其放入新列

用单个列从另一个表更新一个表中的多个列?

Excel:如何根据键列从另一个工作表添加列?