在尝试将数据从awss3加载到redshift时,我遇到了decimal类型的redshift表中任何列的问题。我可以在红移中加载非十进制数字,但不能加载像numeric(18,4)这样的数据类型。
s3中的df模式:a整数、b字符串、c十进制(18,4)、d时间戳
红移表模式:一个整数,b varchar(20),c numeric(18,4),d timestamp
stl\ U load\ U errors表格中的错误消息:
无效数字,值'',位置0,类型:decimal
红移试图添加的数据:
2|sample_string||2021-04-03|
为什么十进制列是空的或空的??如上所述,红移数据除十进制列为空外,所有数据的格式都正确。
这是我用来将数据从s3加载到redshift的代码:
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("App_name").getOrCreate()
spark.conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
spark.conf.set("spark.kryo.unsafe", "true")
spark.conf.set("spark.kryoserializer.buffer.max", "1024m")
df = spark.read.parquet(s3_input_path)
pre_query = """
begin;
create table {} (like {});
end;
""".format(temp_table,actual_table_name)
post_query = """
begin;
--some action
insert into {} select * from {};
end;
""".format(actual_table_name,temp_table)
df.write.format('com.databricks.spark.redshiftLib') \
.option("url", "jdbc:redshift://aws.redshift.amazonaws.sampleurl.com:5439/") \
.option("user","UserName") \
.option("preactions",pre_query) \
.option("password","Password") \
.option("dbtable","table_name" ) \
.option("extracopyoptions", "ACCEPTINVCHARS AS '?' TRUNCATECOLUMNS") \
.option("postactions",post_query) \
.options("tempformat", "CSV GZIP") \
.option("tempdir", "s3a://aws-bucket/") \
.option("csvseparator","|") \
.option("forward_spark_s3_credentials","true")\
.mode("append") \
.save()
1条答案
按热度按时间kokeuurv1#
我遇到问题了,我用的是spark 2.x。为了以csv格式保存tempdir,您需要spark 3.x。你可以使用最新版本,
3.0.0-preview1
.你可以升级你的spark
或
你可以像这样使用你的命令
spark-submit --packages com.databricks:spark-redshift_2.10:3.0.0-preview1....
说明:在写入redshift时,数据首先存储在s3的temp文件夹中,然后再加载到redshift。用于在apachespark和redshift之间存储temp数据的默认格式是spark avro。但是,spark avro将十进制存储为二进制,redshift将其解释为空字符串或空值。
但我想提高性能,并消除这个空白问题,为此目的,csv格式是最合适的。我使用的是spark2.x,它默认使用avrotempformat,即使我们在外部提到它。
所以在使用命令给出3.0.0-preview1包之后,它现在可以使用spark3.x中的特性了。
参考文献:
https://kb.databricks.com/data/redshift-fails-decimal-write.html
https://github.com/databricks/spark-redshift/issues/308