使用 Keys [Glue] 预定义 Redshift 表

Posted

技术标签:

【中文标题】使用 Keys [Glue] 预定义 Redshift 表【英文标题】:Pre-define Redshift table with Keys [Glue] 【发布时间】:2019-11-06 16:08:00 【问题描述】:

我想在第一次写入之前手动定义 Redshift 表。这是因为我想在定义的列上利用 distkeysortkey。 SQL 查询将是这样的:

my_sql_command = """
    create table if not exists my_db.my_schema.my_table(
        my_id                     VARCHAR(MAX) NOT NULL DISTKEY,
        type                      VARCHAR(MAX),
        my_timestamp  TIMESTAMP,
    )
    compound sortkey(my_timestamp, my_id);
    """

我将此 SQL 字符串称为 preactions 参数(提到 here,很遗憾找不到更好的文档),如下所示:

my_frame = DynamicFrame.fromDF(my_df, glue_context, "my_frame")

glue_context.write_dynamic_frame.from_jdbc_conf(
        frame=my_frame, catalog_connection=params['db_connection_name'],
        connection_options="preactions": my_sql_command, "dbtable": "my_schema.my_table", "database": "my_db",
        redshift_tmp_dir="s3://my_bucket/", transformation_ctx="my_ctx")

但我收到此错误消息:

py4j.protocol.Py4JJavaError: An error occurred while calling o227.pyWriteDynamicFrame.
: java.sql.SQLException: [JDBC Driver]String index out of range: 0
at java.lang.String.charAt(String.java:658)

我真的不知道如何解释。

是什么导致了这个异常?

【问题讨论】:

【参考方案1】:

异常的原因是因为内部 Glue 没有正确解析新行。所以将SQL命令改写为

my_sql_command = "create table if not exists my_db.my_schema.my_table("\
        "my_id         VARCHAR(MAX) NOT NULL DISTKEY, "\
        "type          VARCHAR(MAX), "\
        "my_timestamp  TIMESTAMP) "\
    "compound sortkey(my_timestamp, my_id);"\

解决了我遇到的异常。

进一步分析日志,看起来Glue preaction是在Glue自动生成CREATE TABLE IF NOT EXISTS之后执行的

19/11/11 11:11:11 INFO RedshiftWriter: 
CREATE TABLE IF NOT EXISTS my_schema.my_table (my_id VARCHAR(MAX), my_timestamp TIMESTAMP, type VARCHAR(MAX)) DISTSTYLE EVEN
19/11/11 11:11:11 INFO RedshiftWriter: Executing preAction: 
create table if not exists my_schema.my_table(my_id VARCHAR(MAX) NOT NULL DISTKEY, my_timestamp TIMESTAMP, type VARCHAR(MAX)) sortkey(id)

所以我用来解决这个不便的方法是使用psycopg2 创建一个连接并通过这个库执行 SQL 命令(here 解释了如何在 Glue Job 中导入它)

【讨论】:

以上是关于使用 Keys [Glue] 预定义 Redshift 表的主要内容,如果未能解决你的问题,请参考以下文章

AWS Glue:如何处理具有不同架构的嵌套 JSON

如何在 AWS-Glue 脚本中编写用户定义的函数?

使用 Glue 连接和 spark scala 覆盖 Mysql 表

AWS Glue - 从 sql server 表中读取并作为自定义 CSV 文件写入 S3

AWS Python Shell - 如何使用 Glue 目录连接

在 AWS Glue 作业中添加时间戳列