Saltar al contenido

Crear una tabla de colmena usando metadatos de archivos de parquet

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *