如何使用Pyspark在所有文件中使用Spark变量



我上个月开始使用Pyspark。我正在使用JupyterLab,并且只在本地执行代码。我试图编写一个使用Spark和Python的项目,但我开始在Spark变量方面遇到一些问题。当我说Spark变量时,我指的是这些变量:

from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession
conf = SparkConf().setAppName('local').setMaster('local')
sc =  SparkContext(conf=conf)
spark = SparkSession(sc)

这是我的项目中的目录示例

例如,我创建了SparkUtils.py文件,以便在笔记本电脑上启动Spark,而不需要之前注释的conf、sc和Spark的调用。这很好用。当我想在其他文件中使用spark变量时,问题就开始了,例如DataProviders.py中的代码片段:

sku = spark.read.format("csv")
.option("header", "true")
.option("inferSchema", "true")
.load(path_to_sku)
.drop("_c0")

spark是如何在笔记本中启动的,DataProviders函数范围中没有变量spark。如果我使用Scala,我会构建一些特性,并将DataProviders类扩展到这个特性,因此Spark上下文和特性将是隐式的。但我不知道如何使用Python做同样的事情,也不知道是否有其他方法可以做到这一点。我目前解决这个问题的方法是,当函数需要使用spark变量时,我只需在每个代码上添加这一行:

spark = SparkSession.getActiveSession()

但这远不是最好的解决方案,我重复代码,这也远不是最佳实践。。。有人知道另一种解决方法吗?

SparkSession是一个单例,因此SparkSession.getActiveSession()通常每次调用它都会返回相同的会话。我可以理解避免代码重复的愿望,但这是一个简短的1行,具有非常清晰的行为。我不确定这种方法是否还有其他问题,但每次想要访问SparkSession时都可以调用getActiveSession()

最常见的替代方案是在一个python模块(也称为文件(中定义spark,并在其他模块中从该模块导入spark

例如,如果utils.SparkUtils.py定义了火花变量,则可以将以下内容添加到etl.building.DataProviders.py中:

from utils.SparkUtils import conf, sc, spark

如果您来自Scala,我建议您将每个Python模块视为Scala单例object的粗略等价物。它是一个命名空间,您可以在其中定义可以从其他模块导入和调用的变量和函数。

最新更新