如何在 Spark SQL 中访问 python 变量?

How can I access python variable in Spark SQL?

我在 Azure Databricks 的 jupyter notebook 文件中的 %python 下创建了 python 变量。我如何访问相同的变量以在 %sql 下进行比较。下面是示例:

%python

RunID_Goal = sqlContext.sql("SELECT CONCAT(SUBSTRING(RunID,1,6),SUBSTRING(RunID,1,6),'01_') 
FROM RunID_Pace").first()[0] 
AS RunID_Goal
%sql
SELECT Type , KPIDate, Value
FROM table
WHERE
RunID = RunID_Goal (This is the variable created under %python and want to compare over here)

当我 运行 这会抛出一个错误: SQL 语句中的错误:AnalysisException:无法解析给定输入列的“RunID_Goal”: 我是新的 azure databricks 和 spark sql 任何形式的帮助将不胜感激。

您无法访问此变量。在 documentation:

中有解释

When you invoke a language magic command, the command is dispatched to the REPL in the execution context for the notebook. Variables defined in one language (and hence in the REPL for that language) are not available in the REPL of another language. REPLs can share state only through external resources such as files in DBFS or objects in object storage.

一种解决方法是使用 Widgets 在单元格之间传递参数。例如,在 Python 一侧,它可能如下所示:

# generate test data
import pyspark.sql.functions as F
spark.range(100).withColumn("rnd", F.rand()).write.mode("append").saveAsTable("abc")

# set widgets
import random
vl = random.randint(0, 100)
dbutils.widgets.text("my_val", str(vl))

然后您可以在 SQL 代码中引用小部件的值:

%sql
select * from abc where id = getArgument('my_val')

会给你:

另一种方法是通过 Spark 配置传递变量。您可以像这样设置变量值(请注意变量应该有一个前缀 - 在本例中是 c.):

spark.conf.set("c.var", "some-value")

然后从 SQL 将变量引用为 ${var-name}:

%sql 
select * from table where column = '${c.var}'

这样做的一个优点是您还可以将此变量用于 table 名称等。缺点是您需要对变量进行转义,例如将字符串值放入单引号中。

这是另一个解决方法。

# Optional code to use databricks widgets to assign python variables
dbutils.widgets.text('my_str_col_name','my_str_col_name')
dbutils.widgets.text('my_str_col_value','my_str_col_value')
my_str_col_name = dbutils.widgets.get('my_str_col_name')
my_str_col_value = dbutils.widgets.get('my_str_col_value')

# Query with string formatting
query = """
select *
from my_table
where {0} < '{1}'
"""

# Modify query with the values of Python variable 
query = query.format(my_str_col_name,my_str_col_value)

# Execute the query
display(spark.sql(query))

快速补充回答。

您是否可以使用小部件将参数传递给另一个使用魔法的单元格 %sql,如前所述;

dbutils.widgets.text("table_name", "db.mytable")

在您将使用此变量的单元格中,您可以使用 $ 快捷方式吗 ~ getArgument 不受支持;

%sql
select * from $table_name