给定一个表格设计不可为 null 的 uuid列和a可为空的 uuid列,如何使用 python 3.7.9 与 Pyspark 2.4.3 数据帧和 postgresql-42.2.18.jar 驱动程序进行插入?
table_df = spark.read.format('jdbc) \
.option('driver', 'org.postgresql.Driver') \
.option('dbtable', 'example_table') \
.load()
table_df.printSchema()
root
|-- id: string (nullable = false)
|-- created: timestamp (nullable = true)
|-- modified: timestamp (nullable = true)
|-- example_uuid: string (nullable = true)
from pyspark.sql.functions import when, lit, col
from pyspark.sql.types import NullType, StringType
def replace(column, value):
return when (column == value, lit(None).cast(NullType())).otherwise(column.cast(StringType()))
example_df = tasklog_df.withColumn("example_uuid", replace(col("example_uuid"), "NULL"))
example_df.write.mode('append').format('jbdc') \
.option('driver', 'org.postgresql.Driver')\
.option('stringtype', 'unspecified') \
.save()
这会导致 Pyspark 尝试插入
INSERT INTO example_table
("id",
"created",
"modified",
"example_uuid")
VALUES
('b49a90aa-a415-4aeb-a7ed-bfc42e43f5c7',
'2020-03-29 02:00:11.06534-07',
'2020-03-29 02:00:11.065361-07',
NULL)
这导致了臭名昭著的
ERROR: column "example_uuid" is of type uuid but expression is of type character
Hint: You will need to rewrite or cast the expression.
我已经投射了数据。 Pyspark 未生成正确的 INSERT 语句或 postgres 驱动程序正在处理该单词NULL
作为字符而不是关键字。我需要使用.option('stringtype', 'unspecified')
为了不让 Pyspark 抱怨id
列是一个uuid
.
The lit(None).cast(NullType())
似乎什么也没做。
pyspark.sql.types 中没有 uuid 类型的条目。
如果没有option('stringtype', 'unspecified')
然后 Pyspark 抛出错误:
Caused by: org.postgresql.util.PSQLException: ERROR: column "id" is of type uuid but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
剩下的唯一方法似乎是将数据帧拆分为两个数据帧,一个数据帧的 example_uuid 字段包含 NULL,另一个数据帧的 example_uuid 字段是 uuid。然后从数据帧中删除带有 NULL 的 example_uuid 字段,以便在保存到表时不会引发错误。当 Pyspark 应该只支持时,这似乎是浪费了很多精力uuid
类型。意见或建议?