如何从同一个数据库中读取许多表并将它们保存到自己的CSV文件中?

时间:2017-05-25 10:32:26

标签: python csv apache-spark apache-spark-sql pyspark-sql

以下是连接到SQL服务器的工作代码,并将1个表保存为CSV格式文件。

conf = new SparkConf().setAppName("test").setMaster("local").set("spark.driver.allowMultipleContexts", "true");
sc = new SparkContext(conf)
sqlContext = new SQLContext(sc)
df = sqlContext.read.format("jdbc").option("url","jdbc:sqlserver://DBServer:PORT").option("databaseName","xxx").option("driver","com.microsoft.sqlserver.jdbc.SQLServerDriver").option("dbtable","xxx").option("user","xxx").option("password","xxxx").load()

df.registerTempTable("test")
df.write.format("com.databricks.spark.csv").save("poc/amitesh/csv")
exit()

我有一个场景,我必须通过pyspark代码一次性保存4个不同文件中CSV格式的4个表。无论如何我们能达到目的吗?或者,这些拆分是在HDFS块大小级别完成的,所以如果你有一个300mb的文件,并且HDFS块大小设置为128,那么你得到3块128mb,128mb和44mb?

1 个答案:

答案 0 :(得分:3)

  

在哪里我必须通过pyspark代码一次以4种不同的文件以CSV格式从同一数据库中保存4个表。

您必须为数据库中的每个表编码转换(读取和写入)(使用sqlContext.read.format)。

特定于表的ETL管道之间的唯一区别是每个表有不同的dbtable选项。获得DataFrame后,将其保存到自己的CSV文件中。

代码可能如下所示(在Scala中,所以我将其转换为Python作为主页练习):

val datasetFromTABLE_ONE: DataFrame = sqlContext.
  read.
  format("jdbc").
  option("url","jdbc:sqlserver://DBServer:PORT").
  option("databaseName","xxx").
  option("driver","com.microsoft.sqlserver.jdbc.SQLServerDriver").
  option("dbtable","TABLE_ONE").
  option("user","xxx").
  option("password","xxxx").
  load()

// save the dataset from TABLE_ONE into its own CSV file
datasetFromTABLE_ONE.write.csv("table_one.csv")

对要保存为CSV的每个表重复相同的代码。

完成!

100表案例 - 公平调度

解决方案要求另一个:

  

当我有100张或更多桌子时会怎么样?如何为此优化代码?如何在Spark中有效地做到这一点?任何并行化?

我们用于ETL管道的SparkContext后面的

SparkSession是线程安全的,这意味着您可以从多个线程使用它。如果你考虑每个表的一个线程是正确的方法。

你可以产生尽可能多的线程,就像拥有表一样,比如100,并启动它们。然后Spark可以决定执行什么以及何时执行。

这是Spark使用Fair Scheduler Pools做的事情。对于这种情况,Spark的特征并不是非常广为人知:

  

在给定的Spark应用程序(SparkContext实例)中,如果从单独的线程提交多个并行作业,则它们可以同时运行。通过“作业”,在本节中,我们指的是Spark操作(例如,保存,收集)以及需要运行以评估该操作的任何任务。 Spark的调度程序是完全线程安全的,并支持此用例,以支持提供多个请求的应用程序(例如,查询多个用户)。

使用它,您的加载和保存管道可能会变得更快。