如何将参数传递给spark.sql(""" """)?

Cau*_*der 6 apache-spark apache-spark-sql pyspark apache-zeppelin

我想将一个字符串传递给spark.sql

这是我的查询

mydf = spark.sql("SELECT * FROM MYTABLE WHERE TIMESTAMP BETWEEN '2020-04-01' AND '2020-04-08') 
Run Code Online (Sandbox Code Playgroud)

我想传递一个日期字符串。

我试过这段代码

val = '2020-04-08'

s"spark.sql("SELECT * FROM MYTABLE WHERE TIMESTAMP  BETWEEN $val  AND '2020-04-08'
Run Code Online (Sandbox Code Playgroud)

Pra*_*mna 8

Spark 3.4中引入了参数化SQL。您可以将args直接传递给spark.sql。这是一种更安全的参数传递方式(通过任意连接字符串输入来防止 SQL 注入攻击)。

例子 -

spark.sql(
    "SELECT * FROM range(10) WHERE id > {bound1} AND id < {bound2}", bound1=7, bound2=9

).show()
Run Code Online (Sandbox Code Playgroud)

有关更多示例,请参阅文档。


Shu*_*Shu 1

尝试使用 Python 字符串格式{},就像在 scala 中.format(val)一样$val

val = '2020-04-08'

spark.sql("SELECT * FROM MYTABLE WHERE TIMESTAMP  BETWEEN {}  AND '2020-04-08'".format(val)).show()
Run Code Online (Sandbox Code Playgroud)

Example:

In Pyspark:

spark.sql("select * from tmp").show()
#+----+---+
#|name| id|
#+----+---+
#|   a|  1|
#|   b|  2|
#+----+---+

id='1'

spark.sql("select * from tmp where id={}".format(id)).show()
#+----+---+
#|name| id|
#+----+---+
#|   a|  1|
#+----+---+
Run Code Online (Sandbox Code Playgroud)

In Scala:

用于string interpolation替换变量的值

val id=1
spark.sql(s"select * from tmp where id=$id").show()
//+----+---+
//|name| id|
//+----+---+
//|   a|  1|
//+----+---+
Run Code Online (Sandbox Code Playgroud)

  • 如果id是字符串,则可以用于SQL注入。 (8认同)
  • 扩展@Chris 的评论:使用这个答案时要非常小心。如果“id”的值是从用户输入中获取的,即使是间接获取的,您的数据库也很容易被最粗暴、最简单的方法攻击。(想象一下如果该值为“1; drop table tmp;”会发生什么。)您自己生成“id”的值,根据白名单检查它,或者确保转义任何特殊字符。 (6认同)
  • 您能否向我展示来自 PySpark 的具有多个变量的一个? (2认同)