AWS Glue IllegalArgumentException:'Invalid type name uuid'

AWS Glue IllegalArgumentException: 'Invalid type name uuid'

我正在尝试将一列中带有 UUID 的 table ETL 到 postgres table 但我正在努力将 UUID 列加载到目标 postgres table作为 UUID 类型。

使用以下代码行:

applymapping1 = ApplyMapping.apply(frame = foo, mappings = [("id", "string", "id", "uuid")], transformation_ctx = "applymapping1")

我在 运行 粘合作业时收到以下错误:

IllegalArgumentException: 'Invalid type name guid'

有谁知道如何将 ID 作为 UUID 存储在目标数据库中 table?

此外,我似乎找不到允许我在 ApplyMapping 调用中使用的支持数据类型的列表。有谁知道在哪里可以找到这些?

AWS Glue 不支持将 uuid 作为数据类型。以下文档详细介绍了 AWS glue ETL 中所有支持的数据类型,它们是 pyspark 类型的扩展:

AWS Glue datatypes

所以 AWS DynamicFrame 和底层 Spark DataFrame 都不支持处理 UUID 类型的对象。但是,Postgres 的 JDBC 驱动程序确实支持称为“stringtype”的 configuration property。当它设置为“未指定”时,它将导致 JDBC 驱动程序尝试将字符串转换为堆栈中较低的正确列类型,低于 Spark DataFrame 的级别。

您可以像这样在 AWS Glue pyspark 脚本中配置行为。

datasink = glueContext.write_dynamic_frame.from_jdbc_conf(frame = transform2, catalog_connection = "<<glue catalog connection>>", connection_options = {
    "url": "jdbc:postgresql://<HOST>?stringtype=unspecified"
    "customJdbcDriverClassName": "org.postgresql.Driver",
    "customJdbcDriverS3Path": "s3://<YOUR_S3_BUCKET>/postgresql-42.2.23.jar",
    "database": "<DATABASE_NAME>", 
    "dbtable": "<TABLE_NAME>"
}, transformation_ctx = "datasink")

显然,这是对该驱动程序配置参数的意外使用,因此这肯定是一种 hack,但它确实有效,并且可能是撰写本文时可用的最佳解决方案。

还值得注意的是,AWS DynamicFrame 和 Spark DataFrame 支持 BinaryType。因此,可以将您的 UUID 作为二进制缓冲区写入 DataFrame,然后使用 Postgres bytea(16) 列存储它们。这比将所有 uuid 列转换为 char(36) 更有效,并且不需要任何 JDBC 级别的 hack。当然,它确实需要迁移所有现有数据并调整应用程序逻辑以正确读取这个新列。所以总的来说,它比上面建议的变化要大得多,但如果你能做到的话,总体上可能“更正确”。