Python/Azure 输出文件名



我是Azure和Python的新手,正在Databricks中创建一个笔记本来输出一段sql的结果。下面的代码生成预期的输出,但默认文件名长度约为 100 个字符。我希望能够为输出提供一个合理的名称并添加日期/时间以创建唯一性,例如 testfile20191001142340.csv。我上上下下地徘徊,找不到任何有用的东西,希望社区里有人能为我指出正确的方向。

%python
try:
dfsql = spark.sql("select * from dbsmets1mig02_technical_build.tbl_Temp_Output_CS_Firmware_Final order by record1") #Replace with your SQL
except:
print("Exception occurred")
if dfsql.count() == 0:
print("No data rows")
else:
dfsql.coalesce(1).write.format("com.databricks.spark.csv").option("header","false").option("delimiter","|").mode("overwrite").option("quote","u0000").save(
"/mnt/publisheddatasmets1mig/metering/smets1mig/cs/system_data_build/firmware/outbound/")   

命名单个文件的问题在于它几乎违背了火花的哲学。为了实现快速处理,Spark必须能够并行写入。对于镶木地板文件或其他自然支持并行化的输出,这不是问题。对于.csv文件,我们习惯于使用单个文件,因此会感到困惑。

长话短说,如果您不使用.coalesce(1)Spark会将您的数据写入一个文件夹中的多个.csv文件。由于只有一个分区,因此只有一个文件 - 但具有生成的名称。所以你在这里有两个选择:

  1. 之后使用Databricks utils或常规Python库重命名/移动文件
  2. .collect 结果并使用其他库保存(默认为csv包(

你可能有的一个明显问题是,为什么做一些像保存到单个文件这样简单的事情如此困难 - 答案是,因为这对Spark来说是一个问题。保存单个分区的方法的问题在于,如果数据多于驱动程序/执行程序内存中可容纳的数据,则重新分区到 1 个分区或将数据collect到执行器将失败并爆炸并出现异常。

为了安全地保存到单个.csv文件,您可以使用toLocalIterator方法,该方法一次只将一个分区加载到内存中,并在其迭代器中使用csv包将结果保存到单个文件中。

最新更新