使用 JDBC 写入编写 AWS Glue DynamicFrame 时出现 PostreSQL 枚举问题

Posted

技术标签:

【中文标题】使用 JDBC 写入编写 AWS Glue DynamicFrame 时出现 PostreSQL 枚举问题【英文标题】:Issue with PostreSQL Enum when writing an AWS Glue DynamicFrame with JDBC write 【发布时间】:2022-01-14 06:12:26 【问题描述】:

我正在尝试使用 JDBC 写入在 PostgreSQL 数据库中编写 AWSGlue DynamicFrame。目标表包含 Enum 类型的一列。

我首先从底层 PySpark DataFrame 中选择感兴趣的列,然后将 DataFrame 转换为 DynamicFrame:

# Select columns of interest
final_df = df.select("id", "my_struct.*")

# Convert back to DynamicFrame
dyf = DynamicFrame.fromDF(final_df, context, "final_dyf")

插入是使用以下代码完成的:

glue_context.write_dynamic_frame.from_options(
    frame=dyf,
    connection_type="postgresql",
    connection_options=
        "url": "jdbc:postgresql://my_db_url",
        "user": POSTGRES_USER,
        "password": POSTGRES_PASSWORD,
        "dbtable": table_name,
        "stringtype": "unspecified",
    ,
    transformation_ctx=f"write_dyf_to_table_name_table",
)

插入数据时,我收到以下错误消息:

ERROR: column "x" is of type x_enum but expression is of type character.
Hint: You will need to rewrite or cast the expression.

我看过这篇文章:Problem writting an enun on PostgreSQL using a PySpark Dataframe with jdbc write,它强调了同样的问题。建议的答案建议在 JDBC 连接选项中添加 "stringtype": "unspecified"

我做到了,但我仍然遇到问题。我怀疑问题出在这样一个事实,即在这种特殊情况下,整列xNULL。 PostgreSQL 表中的枚举列是NULLABLE

我找到了使用 DropNullFields.apply 的解决方法,但我希望尽可能避免这样做。

以前有没有人遇到过这个问题或有什么建议?

非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

您面临的问题是 Postgres 的类型非常严格。这意味着变量必须是声明的数据类型。 (是的,Postgres 会尝试一些隐式转换,但依赖它们通常是一个糟糕的计划。)转换为正确的数据类型通常要安全得多。尽管 NULL 对几乎任何数据类型都有效,但它不会自动成为所需的类型。我不知道您特定的模糊方言,因此将直接为铸造提供 SQL。有两种方法:(见demo)

    Postgres 强制转换运算符。从::到 SQL 标准强制转换函数。演员表(从作为到)

您应该能够合并其中之一。

【讨论】:

感谢您的回复。我知道 Postgres 的 Cast 运算符,但我不确定如何在 PySpark 中使用它。我会看看,看看我可以如何尝试。

以上是关于使用 JDBC 写入编写 AWS Glue DynamicFrame 时出现 PostreSQL 枚举问题的主要内容,如果未能解决你的问题,请参考以下文章

AWS Glue-如何在 S3 中将动态帧编写为 .txt 文件并使用“|”作为分隔符

AWS Glue to Redshift:是否可以替换,更新或删除数据?

AWS Glue:如何使用 JDBC 连接 oracle db

在AWS Glue上使用JDBC连接Trino

如何从 AWS Glue 中的 JDBC 编目连接加载部分数据?

Python/Pyspark 迭代代码(用于 AWS Glue ETL 作业)