如何使用Spark从.sql转储中提取包含数据的表?

时间:2018-08-31 04:55:48

标签: mysql scala apache-spark

我大约有四个* .sql自包含转储(每个约20GB),我需要将其转换为Apache Spark中的数据集。

我尝试使用InnoDB安装和制作本地数据库并导入转储,但这似乎太慢了(用了大约10个小时)

我直接使用读取文件到Spark

import org.apache.spark.sql.SparkSession

var sparkSession = SparkSession.builder().appName("sparkSession").getOrCreate()
var myQueryFile = sc.textFile("C:/Users/some_db.sql")

//Convert this to indexed dataframe so you can parse multiple line create / data statements. 
//This will also show you the structure of the sql dump for your usecase.

var myQueryFileDF = myQueryFile.toDF.withColumn("index",monotonically_increasing_id()).withColumnRenamed("value","text") 


// Identify all tables and data in the sql dump along with their indexes

var tableStructures = myQueryFileDF.filter(col("text").contains("CREATE TABLE"))
var tableStructureEnds = myQueryFileDF.filter(col("text").contains(") ENGINE"))

println(" If there is a count mismatch between these values choose different substring "+ tableStructures.count()+ " " + tableStructureEnds.count())

var tableData = myQueryFileDF.filter(col("text").contains("INSERT INTO "))

问题在于转储包含多个表,每个表都需要成为数据集。对于这一点,我需要了解我们是否可以为一张桌子做到这一点。有没有为Scala Spark编写的.sql解析器?

有更快的解决方法吗?我可以直接从.sql自包含文件中将其读取到蜂巢中吗?

更新1:我正在基于Ajay给出的Input编写解析器

更新2:按照建议将所有内容更改为基于数据集的代码以使用SQL解析器

2 个答案:

答案 0 :(得分:3)

  

有没有为scala spark编写的.sql解析器?

是的,有一个,您似乎已经在使用它。那就是Spark SQL本身!惊讶吗?

SQL解析器接口(ParserInterface)可以从SQL语句的文本表示形式创建关系实体。这几乎是您的情况,不是吗?

请注意,ParserInterface一次只处理一条SQL语句,因此您必须以某种方式解析整个转储并找到表定义和行。

ParserInterface作为sqlParser中的SessionState

scala> :type spark
org.apache.spark.sql.SparkSession

scala> :type spark.sessionState.sqlParser
org.apache.spark.sql.catalyst.parser.ParserInterface

Spark SQL附带了几种提供接口入口点的方法,例如SparkSession.sqlDataset.selectExpr或只是expr标准功能。您也可以直接使用SQL解析器。


无耻的插件,您可能需要阅读Mastering Spark SQL图书中的ParserInterface — SQL Parser Contract

答案 1 :(得分:1)

您需要自己解析。它需要执行以下步骤-

  1. 为每个表创建一个类。
  2. 使用textFile加载文件。
  3. 过滤掉除插入语句以外的所有语句。
  4. 然后根据插入语句中存在的表名,使用过滤器将RDD分为多个RDD。
  5. 对于每个RDD,使用map解析插入语句中存在的值并创建对象。
  6. 现在将RDD转换为数据集。