Apache spark Spark(v2.3.2)dataframe正在以字符串类型读取ORC文件中的所有列。这是正常的行为吗?
我有一堆CSV文件,正在使用ETL工具Informatica以ORC格式加载到HDFS中。加载到HDFS后,我想提取ORC文件的元数据(列名、数据类型) 但是当我将ORC文件加载到Spark数据帧中时,所有列都被赋值为Apache spark Spark(v2.3.2)dataframe正在以字符串类型读取ORC文件中的所有列。这是正常的行为吗?,apache-spark,orc,Apache Spark,Orc,我有一堆CSV文件,正在使用ETL工具Informatica以ORC格式加载到HDFS中。加载到HDFS后,我想提取ORC文件的元数据(列名、数据类型) 但是当我将ORC文件加载到Spark数据帧中时,所有列都被赋值为stringtype 样本数据: ID|Course|Enrol_Date|Credits 123|Biology|21-03-2012 07:34:56|24 908|Linguistics|05-02-2012 11:02:36|15 564|Computer Science|
string
type
样本数据:
ID|Course|Enrol_Date|Credits
123|Biology|21-03-2012 07:34:56|24
908|Linguistics|05-02-2012 11:02:36|15
564|Computer Science|18-03-2012 09:48:09|30
341|Philosophy|23-01-2012 18:12:44|10
487|Math|10-04-2012 17:00:46|20
我使用以下命令来实现这一点:
df = sqlContext.sql("SELECT * FROM orc.`<HDFS_path>`");
df.printSchema()
我对Spark和HDFS完全是新手。我试图理解为什么每一列都是
string
类型的结果。这是否是使用csv源文件创建ORC时的正常行为(无论我们使用哪种工具)?还是我在spark中没有正确执行导致此问题的操作?在通过Informatica导入CSV
文件时,您应该cast
或使用schema
。由于SparkORC
格式不会像SparkCSV
格式那样自动推断模式。ORC格式按原样从源文件架构获取架构
由于您没有在Informatica中使用任何模式
,因此它以默认的字符串
数据类型写入数据,而ORC
将进一步采用该数据类型
有两种可能的解决方法:
Informatica
/Spark
中加载到ORC
中的String
以外的数据类型Struct
或Casting
更改所需列的ORC
文件的数据类型Schema
的示例演示。您可以将Informatica
中源CSV
文件的模式逻辑与Spark
中的逻辑相似,如下所示
案例1:默认加载CSV文件并写入ORC
案例2:转换/推断CSV文件的模式数据类型并写入ORC
默认情况下,spark将所有字段读取为StringType。您可以在下面尝试: 为了推断模式
val data = spark.read.format("csv").option("header", "true").option("inferSchema", "true").load("<path>.csv")
val data=spark.read.format(“csv”).option(“header”、“true”).option(“inferSchema”、“true”).load(“csv”)
用于提供自定义模式
import org.apache.spark.sql.types._
val customSchema = StructType(Array(
StructField("col1", StringType, true),
StructField("col2", IntegerType, true),
StructField("col3", DoubleType, true))
)
val data = spark.read.format("csv").option("header", "true").schema(customSchema).load("<path>.csv")
import org.apache.spark.sql.types_
val customSchema=StructType(数组(
StructField(“col1”,StringType,true),
StructField(“col2”,IntegerType,true),
StructField(“col3”,双类型,true))
)
val data=spark.read.format(“csv”).选项(“标头”、“true”).架构(customSchema).load(.csv”)
我刚刚尝试了这个方法,但它仍然将所有列都设置为string
type。这种情况可能有什么原因吗?你能检查一下你是如何通过Informatica加载数据的吗?你是否使用了任何模式?你能提供你的样本数据吗?编辑了这个问题,添加了样本数据及其输出。不,我没有在Informatica中使用任何模式。这是一个动态映射,使用参数选择每个文件。感谢您的输入。但是在我的例子中,提供一个自定义模式并不是一种有效的方法,因为我有很多列的文件。因此,我的目标是自动提取数据类型信息,而不是手动提供。我需要这些信息来在配置单元中创建外部表。实际上,即使有100个列,提供自定义模式也是有效的方法。因为,在推断模式时,spark会遍历每个数据点&推断,有效地读取整个数据。但是,当您提供模式时,实际上您节省了推断ok的时间。我不知道。谢谢你的澄清。我所说的低效是指我必须为这100列中的每一列手动键入数据类型。但是你所说的在减少spark的负载方面也是有意义的。在相关情况下,我会记住这一点。但现在,我不知道一个文件可能有多少列或它们的数据类型。我现在唯一的目的是使用这些信息在Hive中形成createexternaltable
语句
//Inferring Schema or Transform/casting of CSV data in Spark or Informatica respectively.
scala> val df = spark.read.format("csv").option("header","true").option("inferschema", "true").load("/spath/stack2.csv")
//Transformed Schema
scala> df.printSchema
root
|-- ID: integer (nullable = true)
|-- Course: string (nullable = true)
|-- Enrol_Date: string (nullable = true)
|-- Credits: integer (nullable = true)
//Have loaded same CSV file into ORC
scala> df.write.format("orc").mode("overwrite").save("/spath/AP_ORC")
scala> val orc = spark.read.format("orc").load("/spath/AP_ORC")
//Schema is same as Source CSV file
scala> orc.printSchema
root
|-- ID: integer (nullable = true)
|-- Course: string (nullable = true)
|-- Enrol_Date: string (nullable = true)
|-- Credits: integer (nullable = true)
val data = spark.read.format("csv").option("header", "true").option("inferSchema", "true").load("<path>.csv")
import org.apache.spark.sql.types._
val customSchema = StructType(Array(
StructField("col1", StringType, true),
StructField("col2", IntegerType, true),
StructField("col3", DoubleType, true))
)
val data = spark.read.format("csv").option("header", "true").schema(customSchema).load("<path>.csv")