Solución:
Aquí hay una solución que se me ocurrió para obtener los metadatos de los archivos de parquet para crear una tabla Hive.
Primero inicie un spark-shell (O compílelo todo en un Jar y ejecútelo con spark-submit, pero el shell es MUY más fácil)
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.DataFrame
val df=sqlContext.parquetFile("/path/to/_common_metadata")
def creatingTableDDL(tableName:String, df:DataFrame): String={
val cols = df.dtypes
var ddl1 = "CREATE EXTERNAL TABLE "+tableName + " ("
//looks at the datatypes and columns names and puts them into a string
val colCreate = (for (c <-cols) yield(c._1+" "+c._2.replace("Type",""))).mkString(", ")
ddl1 += colCreate + ") STORED AS PARQUET LOCATION '/wherever/you/store/the/data/'"
ddl1
}
val test_tableDDL=creatingTableDDL("test_table",df,"test_db")
Le proporcionará los tipos de datos que Hive usará para cada columna a medida que se almacenan en Parquet. P.EJ: CREATE EXTERNAL TABLE test_table (COL1 Decimal(38,10), COL2 String, COL3 Timestamp) STORED AS PARQUET LOCATION '/path/to/parquet/files'
Me gustaría ampliar la respuesta de James Tobin. Hay una clase StructField que proporciona los tipos de datos de Hive sin hacer reemplazos de cadenas.
// Tested on Spark 1.6.0.
import org.apache.spark.sql.DataFrame
def dataFrameToDDL(dataFrame: DataFrame, tableName: String): String = {
val columns = dataFrame.schema.map { field =>
" " + field.name + " " + field.dataType.simpleString.toUpperCase
}
s"CREATE TABLE $tableName (n${columns.mkString(",n")}n)"
}
Esto resuelve el problema de IntegerType.
scala> val dataFrame = sc.parallelize(Seq((1, "a"), (2, "b"))).toDF("x", "y")
dataFrame: org.apache.spark.sql.DataFrame = [x: int, y: string]
scala> print(dataFrameToDDL(dataFrame, "t"))
CREATE TABLE t (
x INT,
y STRING
)
Esto debería funcionar con cualquier DataFrame, no solo con Parquet. (por ejemplo, estoy usando esto con un JDBC DataFrame).
Como ventaja adicional, si su DDL de destino admite columnas que aceptan valores NULL, puede ampliar la función marcando StructField.nullable
.