用于解析JSON模式文件的SQL DDL

问题描述 投票:1回答:3

可以将SQL DDL语句解析为简单的JSON模式文件,如下所示,而不使用任何工具,只使用Scala / Python / shell脚本编写?

CREATE TABLE TEMP (
      ID INT,
      NAME STRING)

[
  {
    "tableName": "temp",
    "columns": [
      {
        "columnname": "id",
        "datatype": "int"
      },
      {
        "columnname": "name",
        "datatype": "string"
      }
    ]
  }
]
python-3.x scala shell apache-spark
3个回答
1
投票

您可以使用以下逻辑(Scala代码)从DDL创建JSON表单中的字符串。一旦字符串被制作,它将被转换为Dataframe。然后使用Dataframe内置的API(称为Dataframe's)将此write.json保存为HDFS / Amazon S3作为JSON文件

import org.apache.spark.sql.types._
import spark.implicits._
val createSql = "CREATE TABLE TEMP (ID INT, NAME STRING)"
var jsonString = """[{"tableName":"""" + createSql.split(" ")(2).toLowerCase + "\"," + "\"columns\":["
createSql.split(s"\\(")(1).split(s"\\)")(0).split(",").map(r => {
jsonString += "{" + "\"columnname\": " + "\"" + r.trim.split(" ")(0).toLowerCase + "\"," + "\"datatype\": " + "\"" + r.trim.split(" ")(1).toLowerCase + "\"},"
})
jsonString = jsonString.patch(jsonString.lastIndexOf(','), "", 1) + "]}]"
val schema: StructType = null
val reader = spark.read
Option(schema).foreach(reader.schema)
val df = reader.json(sc.parallelize(Array(jsonString)))
df.coalesce(1).write.json("<targetlocation>")

请让我知道,如果你有任何问题。


0
投票

有一些匹配,如下所述:How to pattern match using regular expression in Scala?,这个代码可能如下所示,假设你的初始表达式是作为行序列传入的(注意下面使用的JSONObject已被弃用,所以用一些替代方法替换它)。

object Parser {

    implicit class Regex(sc: StringContext) {
      def r = new util.matching.Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
    }

    def toJson(tablename: String, columns: Seq[(String,String)]): String = {
      val columnList: List[JSONObject] = columns.toStream.map(x => JSONObject(Map("columnname" -> x._1, "datatype" -> x._2))).toList
      JSONArray(List(JSONObject(Map("tableName" -> tablename, "columns" -> JSONArray(columnList))))).toString()
    }

    def parse(lines: Seq[String]): (String, Seq[(String,String)]) = {
      lines.mkString("").toLowerCase match {
        case r"create\s+table\s+(\S+)${tablename}\s+\((.+)${columns}\).*" =>
          val columnWithType: immutable.Seq[(String, String)] = columns.split(",").toStream
            .map(x => x.split("\\s+"))
            .map(x => (x.head.toLowerCase, x(1).toLowerCase))
          (tablename, columnWithType)
        case _ => ("",Seq.empty)
      }
    }
  }

要使用测试字符串进行测试:

val data: (String, Seq[(String, String)]) = Parser.parse(Seq("CREATE TABLE TEMP (", "ID INT,", "NAME STRING)"))
      println(Parser.toJson(data._1, data._2))

0
投票

使用scala.util.parsing.combinator包,你可以用这样的DDL定义你的Lexer和Grammer解析器,

import scala.util.parsing.combinator._

class JSON extends JavaTokenParsers {
  def value: Parser[Any] = obj | arr | stringLiteral | floatingPointNumber | "null" | "true" | "false"
  def obj: Parser[Any] = "{"~repsep(member, ",")~"}"
  def arr: Parser[Any] = "["~repsep(value, ",")~"]"
  def member: Parser[Any] = stringLiteral~":"~value
} 

上面的代码将用于将JSON字符串解析为lexel流以进行进一步处理。阅读文档,您将能够定义您的SQL DDL解析器。


0
投票

我们刚刚在https://github.com/deepstartup/jsonutils发布了这个软件包。可能你会发现它很有用。如果您需要我们更新某些内容,请打开JIRA。

尝试:

    pip install DDLJ
    from DDLj import genddl
    genddl(*param1,param2,*param3,*param4)

Where
param1= JSON Schema File
param2=Database (Default Oracle)
Param3= Glossary file
Param4= DDL output script
© www.soinside.com 2019 - 2024. All rights reserved.