【问题标题】:How to extract tables with data from .sql dumps using Spark?如何使用 Spark 从 .sql 转储中提取包含数据的表?
【发布时间】:2019-02-06 02:04:21
【问题描述】:

我有大约四个 *.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 自包含文件中直接将其读入 hive 吗?

更新 1:我正在根据 Ajay 给出的输入为此编写解析器

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

【问题讨论】:

  • 如果 sql 包含多个表,您如何设想它变成 1 个数据帧/数据集?否则你应该写自己的数据源格式hackernoon.com/…
  • 已编辑。我想为一张表做数据框。编辑问题以更好地反映这一点。谢谢
  • sql转储中的条目(表定义和行)之间的分隔符是什么?
  • 你有一个 create table 语句,后面跟着一堆 insert into table 语句。所以给定转储我写的代码可以提取所有表并将它们枚举到数据集中
  • 我被困在所有创建语句都被提取到 RDDArray[String] 中,需要对其进行解析以便为多个表创建空数据集结构。使用解析器如何做到这一点?

标签: mysql scala apache-spark


【解决方案1】:

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

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

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

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

ParserInterface 可用作 sqlParserSessionState

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

【讨论】:

  • 嗨,Jacek 谢谢你的参考。这些似乎是处理 sql 语句的单独命令。没有为 mysql 转储指定进程。如果你能指导我,我不介意在这里构建它供其他人使用。
  • 没错。 ParserInterface 一次处理一条 SQL 语句。
  • 这仅有助于与 HIVE SQL 兼容的语句,否则您会收到“输入时没有可行的替代方案”错误。我正在积极面对 MYSQL 查询解析器。
  • 好吧,对于此类错误,您必须找到替代解决方案(甚至自己进行 SQL 解析)。 Spark SQL 至少可以提供一点帮助,因此您不必解析所有内容(只是“边缘”案例)。
【解决方案2】:

你需要自己解析。它需要以下步骤 -

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

【讨论】:

  • 酷。我认为这是一个老问题,所以会有人写一个脚本来分享。 :)
  • 因为表很大..每个表都有多个INSERT语句。
猜你喜欢
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多