使用 Keys [Glue] 预定义 Redshift table
Pre-define Redshift table with Keys [Glue]
我想在第一次写入之前手动定义 Redshift table。这是因为我想在定义的列上利用 distkey
和 sortkey
。 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)
我真的不知道怎么解释。
是什么导致了这个异常?
异常的原因是因为内部 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
and execute the SQL command through this library ( 解释了如何将其导入 Glue Job)
创建连接
我想在第一次写入之前手动定义 Redshift table。这是因为我想在定义的列上利用 distkey
和 sortkey
。 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)
我真的不知道怎么解释。
是什么导致了这个异常?
异常的原因是因为内部 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
and execute the SQL command through this library (