pyspark:创建数据帧时模式中指定的数据类型不会反映在数据中

时间:2018-02-05 17:53:29

标签: csv apache-spark pyspark spark-dataframe aws-glue

我在Spark中创建了一个数据框,我已经按如下方式定义了模式:

SCHEMA = StructType([StructField('s3_location', StringType()),
                     StructField('partition_date', StringType()),
                     StructField('table_name', StringType()),
                     StructField('column_name', StringType()),
                     StructField('data_type', StringType()),
                     StructField('number_of_nulls', LongType()),
                     StructField('min', DoubleType()),
                     StructField('max', DoubleType()),
                     StructField('mean', DoubleType()),
                     StructField('variance', DoubleType()),
                     StructField('max_length', LongType())])

我有一堆遵循这个确切模式的行,我正在创建数据帧,如下所示:

DF = SPARK.createDataFrame(ROWS, schema=SCHEMA)

然后我将此数据帧写入AWS S3中的CSV文件:

DF.repartition(1).write.mode('append').partitionBy('partition_date').csv(SAVE_PATH,
                                                                      header=True)

此过程成功并在S3中创建CSV文件。现在,我在AWS Glue中抓取这个S3位置,它以不同的方式推断出架构。我指定为DoubleType()的所有字段都被推断为string。因此,如果我想使用类似QuickSight的东西对这些值运行任何聚合函数,我就不能。

为什么会这样?有办法解决吗?

2 个答案:

答案 0 :(得分:0)

CSV是一种无类型文件,包含文本 - 即字符串。

如果您告诉AWS Glue该表包含数值,那么它将读取这些值是数字,但AWS Glue爬虫无法识别您的数值。这可能是因为您有一个标题行,或者可能是因为列被引用,或者因为您没有指定。

如果您在Glue中手动创建表格,您将能够指定列的数据类型。以下是您可以从Athena控制台执行此操作的方法。

  1. 点击名称表旁边的垂直省略号,然后选择Generate Create Table DDL
  2. 使用此查询的结果,在CREATE TABLE查询中修改数字列的数据类型 - you might use FLOAT, DOUBLE, or DECIMAL
  3. 删除表格(例如DROP TABLE myschema.mytable;
  4. 运行修改后的CREATE TABLE脚本。保留Glue最初添加的所有表属性非常有用,这样任何下游进程都能理解继续以相同的方式识别表。
  5. 您是否可以在文件中包含数据类型,并避免告诉Glue有关数据类型的信息?是! Use one of Glue's more structured file formats,例如Parquet(Spark最喜欢的)或ORC。

答案 1 :(得分:0)

导入CSV文件时,Crawler会自动指定列名称。这可以通过以下方式解决:

  1. 架构编辑并保存。

    在第一次抓取后在Glue控制台中编辑表架构。请使用必要的数据类型保存模式。

  2. 更改抓取工具设置。

    由于您已指定未来运行的架构没有变化,因此在第二次运行之前更新/编辑爬虫的输出配置选项(可选)(在修复之后)架构 - 改为加倍。)

  3. 选择忽略更改并且不要修改数据目录。

  4. 再次运行抓取工具。它不会显示正在更新或添加的表格,但您的数据将以所需格式填充。