是否可以将SQL DDL语句解析为简单的JSON模式文件,如下所示,而无需使用任何工具,仅使用Scala/Python/shell脚本?
CREATE TABLE TEMP (
ID INT,
NAME STRING)
[
{
"tableName": "temp",
"columns": [
{
"columnname": "id",
"datatype": "int"
},
{
"columnname": "name",
"datatype": "string"
}
]
}
]
您可以使用以下逻辑(Scala 代码(从 DDL 创建 JSON 形式的字符串。一旦字符串被制作出来,它就会被转换成一个Dataframe
。然后将此Dataframe
作为 JSON 文件保存到 HDFS/Amazon S3 中,使用名为 write.json
的内置 API Dataframe's
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>")
如果您有任何问题,请告诉我。
有一些匹配,例如这里描述的:如何在 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"creates+tables+(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))
使用 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 解析器。
我们刚刚在 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