Python 3.x 从工作人员处访问SparkSession的正确方式是什么

Python 3.x 从工作人员处访问SparkSession的正确方式是什么,python-3.x,apache-spark,pyspark,azure-databricks,Python 3.x,Apache Spark,Pyspark,Azure Databricks,我刚刚意识到我多次调用以下代码,这似乎不正确: spark = SparkSession.builder.getOrCreate() 我的代码的某些步骤在工作上下文上运行。因此,在驱动程序中创建的spark会话对工作人员不可用 我知道getOrCreate()方法检查是否有任何全局会话可供使用,因此它可能并不总是创建新会话,但这迫使我一次又一次地请求spark会话 我四处查看,看到有人将会话作为UDF或foreach函数的参数发送,但找不到太多关于它的信息 那么,在工作人员内部访问spark的

我刚刚意识到我多次调用以下代码,这似乎不正确:

spark = SparkSession.builder.getOrCreate()
我的代码的某些步骤在工作上下文上运行。因此,在驱动程序中创建的spark会话对工作人员不可用

我知道getOrCreate()方法检查是否有任何全局会话可供使用,因此它可能并不总是创建新会话,但这迫使我一次又一次地请求spark会话

我四处查看,看到有人将会话作为UDF或foreach函数的参数发送,但找不到太多关于它的信息

那么,在工作人员内部访问spark的正确方法是什么

编辑:在下面添加我的用例/更改步骤详细信息

下面的列表可能会让我的用例更加清晰:

 1. Get data from eventhub. 
 2. Save data to delta table
 3. Query distinct IDs
 4. Foreach ID
  4.1. Query other database to get info about the body based on the ID
  4.2. For each row using UDF function (CSV)
   4.2.1. Transform csv into dataframe and return list of tuples
  4.3. Merge all dataframes using flatMap on the rows
  4.4. Write to somewhere
我正在接收来自eventhub的消息,每条消息都有一个CSV正文和一个ID


每个消息可能与另一个消息完全不同,如果是这样,最后,我将把每个消息保存在不同的DW表中

为此,我选择了以下策略:

首先,将所有CSV主体和ID保存在一个通用的增量表中,就像它们一样(我按ID分区)

现在,我可以逐个查询与每个ID相关的所有数据,这样就可以在单个批次中处理与该ID相关的所有数据

当我查询特定ID的所有主体数据时,我有X行,我需要迭代它们,将每行的CSV主体转换为数据帧

之后,我将所有数据帧合并为一个,并将其保存到DW中的正确表中

对于每个dinstinct ID,我使用spark来获取有关身体的信息,并且每次读取CSV或写入DW都是从工作人员内部执行的

编辑:为人物添加了一些代码

4 Foreach ID

# dfSdIds is a dataframe containing all distinct ids that I want to iterate over
dfSdIds.rdd.foreach(SaveAggregatedBodyRows)
4.2对于使用自定义项功能(CSV)的每一行

4.2.1将csv转换为数据帧并返回元组列表

def ConvertCSVToDF(body, mapping): 

...

spark = SparkSession.builder.getOrCreate()           
csvData = spark.sparkContext.parallelize(splittedBody)

df = (spark.read
.option("header", True)
.option("delimiter", delimiter)
.option("quote", quote)
.option("nullValue", nullValue)
.schema(schema)
.csv(csvData))

return list(map(tuple, df.select('*').collect()))
4.3使用行上的flatMap合并所有数据帧

# mapSchema is the same as argSchema but without ArrayType
flatRdd = dfConvertedBody.rdd.flatMap(lambda x: x).flatMap(lambda x: x)      
dfMerged = flatRdd.toDF(mapSchema)
4.4写信到某处

(dfMerged.write
   .format(savingFileFormat)
   .mode("append")
   .option("checkpointLocation", checkpointLocation)
   .save(tableLocation)) 
我知道这段代码还有很多需要改进的地方,但我正在学习pyspark

这个问题比我想象的要严重得多,但问题的关键是我打了电话

spark = SparkSession.builder.getOrCreate() 
在驱动程序中,方法SaveAggregatedBodyRows和方法ConvertCSVToDF内部


人们说它不起作用,但它确实起作用。

这是一个有趣的用例,我以前从未遇到过。你介意更详细地描述一下你想要完成的事情吗?当然!我将把它分成几个评论,这样我可以更详细地解释它。我正在接收来自eventhub的消息。每条消息可能与另一条完全不同,如果是这样,每条消息将保存在不同的DW表中。但是,所有消息都有一个正文和一个Id。因此策略是:将它们都保存在一个通用的增量表中,这样我就可以按Id查询它,并批量处理正文。每个主体是一个CSV,大约有200个lines@FlavioDiasPs:听起来您想使用嵌套的RDD/dataframe(在每个迭代中循环并创建另一个)?这在Spark中是不允许的,例如:。这是一个有趣的用例,我以前从未遇到过。你介意更详细地描述一下你想要完成的事情吗?当然!我将把它分成几个评论,这样我可以更详细地解释它。我正在接收来自eventhub的消息。每条消息可能与另一条完全不同,如果是这样,每条消息将保存在不同的DW表中。但是,所有消息都有一个正文和一个Id。因此策略是:将它们都保存在一个通用的增量表中,这样我就可以按Id查询它,并批量处理正文。每个主体是一个CSV,大约有200个lines@FlavioDiasPs:听起来您想使用嵌套的RDD/dataframe(在每个迭代中循环并创建另一个)?这在Spark中是不允许的,请参见示例:。
spark = SparkSession.builder.getOrCreate()