将数据从PySpark加载到Redshift时如何执行列编码

时间:2016-07-22 18:57:13

标签: pyspark amazon-redshift

我正在尝试使用pyspark直接加载以镶木地板格式在S3上的数据到红色版本。我能够做到这一点,但是当我在表定义中看到列的编码时,它是一致的。我想让它保持一致,特别是我希望它们都是lzo。下面是单表中具有不一致性的数据类型列表。

+-------------------------------+-------------------+
|    data_type                  |  encoding         |
+-------------------------------+-------------------+
| bigint                        | delta             |
| bigint                        | delta32k          | 
| character varying(256)        | lzo               |
| bigint                        | runlength         |
| bigint                        | bytedict          |
| timestamp without time zone   | bytedict          |
| integer                       | runlength         |
+-------------------------------+-------------------+

有人可以帮助我在pyspark中执行此操作。我在 com.databricks中看不到列编码的任何选项:spark-redshift_2.10:1.0.0

 x.write.format("com.databricks.spark.redshift")
.option("url","jdbc:redshift://<url>:<port>/<schema>?user=<user>&password=<pass>")
.option("dbtable","<tbl_nm>")
.option("diststyle","KEY").option("distkey","<key>")
.option("sortkeyspec","SORTKEY(<sort1>)")
.option("tempdir","<path>")
.mode("error").save()

1 个答案:

答案 0 :(得分:2)

我在PR 178中找到了用于指定列编码的相关位。

因此,您不必通过select之类的内容指定编码。您需要使用元数据创建一个模式对象,该元数据指定创建数据帧时的编码。在Python中,例如:

.read.option('encoding', 'lzo')

验证

%pyspark 

from pyspark.sql.types import IntegerType, StringType, StructType, StructField

metadata = {'encoding':'LZO'}

schema = StructType([
    StructField("id", IntegerType(), True, metadata),
    StructField("name", StringType(), True, metadata)])

df = spark.createDataFrame([(1, 'Alice')], schema)

df.write \
  .format("com.databricks.spark.redshift") \
  .option("url", "jdbc:redshift://example.com:5439/db_foo?user=user_bar&password=pass_baz") \
  .option("dbtable", "foo") \
  .option("tempdir", "s3a://foo/bar") \
  .mode("error") \
  .save()