AWS Glue DynamicFrame 尝试将空字符串写为 null
AWS Glue DynamicFrame tries to write empty string as null
我有一个 AWS Glue 作业将数据从 RDS table 移动到 Redshift。
两者 table 具有相同的架构:
-- RDS
CREATE TABLE my_table (
id varchar(256) not null primary key
col1 varchar(256) not null
)
-- Redshift
CREATE TABLE my_table (
id varchar(256) not null
col1 varchar(256) not null
) sortkey(id)
我抓取了这两个模式并编写了一个简单的工作来将 DynamicFrame
从 RDS 源写入 Redshift 接收器。
val datasource = glueContext.getCatalogSource(
database = "my_rds",
tableName = "my_table",
redshiftTmpDir = ""
).getDynamicFrame()
glueContext.getCatalogSink(
database = "my_redshift",
tableName = "my_table",
redshiftTmpDir = "s3://some-bucket/some-path"
).writeDynamicFrame(datasource)
但是对于空字符串值为 col1
的行作业失败,其中:
java.sql.SQLException:
Error (code 1213) while loading data into Redshift: "Missing data for not-null field"
Table name: my_table
Column name: col1
Column type: varchar(254)
Raw line: 3027616797,@NULL@
Raw field value: @NULL@
当我用 glue-spark-shell
调试它时,我可以验证该值是一个空字符串 ""
.
scala> datasource.toDF().filter("id = '3027616797'").select("col1").collect().head.getString(0)
res23: String = ""
如何让胶水区分空字符串 ""
和 NULL
s?
看起来这是 Databricks Datasource for Redshift (docs 中的一个问题)(显然 AWS Glue 在内部使用它)。有关于这个问题的公开票,但他们已经一年多没有被触及了:
- https://github.com/databricks/spark-redshift/issues/331
- https://github.com/databricks/spark-redshift/issues/49
我试过那个代码,但结果完全一样:
datasource
.toDF()
.write
.format("com.databricks.spark.redshift")
.option("url", "<RS_JDBC_URL>?user=<USER>&password=<PASSWORD>")
.option("dbtable", "my_table")
.option("tempdir", "s3://S_PATH")
.option("forward_spark_s3_credentials", "true")
.save
我有一个 AWS Glue 作业将数据从 RDS table 移动到 Redshift。
两者 table 具有相同的架构:
-- RDS
CREATE TABLE my_table (
id varchar(256) not null primary key
col1 varchar(256) not null
)
-- Redshift
CREATE TABLE my_table (
id varchar(256) not null
col1 varchar(256) not null
) sortkey(id)
我抓取了这两个模式并编写了一个简单的工作来将 DynamicFrame
从 RDS 源写入 Redshift 接收器。
val datasource = glueContext.getCatalogSource(
database = "my_rds",
tableName = "my_table",
redshiftTmpDir = ""
).getDynamicFrame()
glueContext.getCatalogSink(
database = "my_redshift",
tableName = "my_table",
redshiftTmpDir = "s3://some-bucket/some-path"
).writeDynamicFrame(datasource)
但是对于空字符串值为 col1
的行作业失败,其中:
java.sql.SQLException:
Error (code 1213) while loading data into Redshift: "Missing data for not-null field"
Table name: my_table
Column name: col1
Column type: varchar(254)
Raw line: 3027616797,@NULL@
Raw field value: @NULL@
当我用 glue-spark-shell
调试它时,我可以验证该值是一个空字符串 ""
.
scala> datasource.toDF().filter("id = '3027616797'").select("col1").collect().head.getString(0)
res23: String = ""
如何让胶水区分空字符串 ""
和 NULL
s?
看起来这是 Databricks Datasource for Redshift (docs 中的一个问题)(显然 AWS Glue 在内部使用它)。有关于这个问题的公开票,但他们已经一年多没有被触及了:
- https://github.com/databricks/spark-redshift/issues/331
- https://github.com/databricks/spark-redshift/issues/49
我试过那个代码,但结果完全一样:
datasource
.toDF()
.write
.format("com.databricks.spark.redshift")
.option("url", "<RS_JDBC_URL>?user=<USER>&password=<PASSWORD>")
.option("dbtable", "my_table")
.option("tempdir", "s3://S_PATH")
.option("forward_spark_s3_credentials", "true")
.save