Pyspark:使用参数动态准备 pyspark-sql 查询

问题描述 投票:0回答:2

动态绑定参数和准备 pyspark-sql 语句有哪些不同的方法。

示例:

动态查询

query = '''SELECT column1, column2
           FROM ${db_name}.${table_name}
           WHERE column1 = ${filter_value}'''

上面的动态查询有 ${db_name}、${table_name} 和 ${filter_value} 变量,这些变量将从运行时参数获取值。

参数详情:

db_name = 'your_db_name'
table_name = 'your_table_name'
filter_value = 'some_value'

动态查询绑定参数后预期查询

SELECT column1, column2
FROM your_db_name.your_table_name
WHERE column1 = some_value  
apache-spark pyspark apache-spark-sql
2个回答
0
投票

这里有一些通过绑定参数准备 pyspark-sql 的选项。

Option#1 - 使用字符串插值/f 字符串 (Python 3.6+)

db_name = 'your_db_name'
table_name = 'your_table_name'
filter_value = 'some_value'

query = f'''SELECT column1, column2
           FROM {db_name}.{table_name}
           WHERE column1 = {filter_value}'''

Option#2 - 使用字符串格式 (str.format)

query = '''SELECT column1, column2
           FROM {}.{}
           WHERE column1 = {}'''

db_name = 'your_db_name'
table_name = 'your_table_name'
filter_value = 'some_value'

query.format(db_name, table_name, filter_value)

选项#3 - 使用模板字符串

query = '''SELECT column1, column2
           FROM ${db_name}.${table_name}
           WHERE column1 = ${filter_value}'''

db_name = 'your_db_name'
table_name = 'your_table_name'
filter_value = 'some_value'

from string import Template
t = Template(query)
t.substitute(db_name=db_name, table_name=table_name, filter_value=filter_value)      
    如果您有,建议使用
  • 字符串插值/f-字符串(选项#1) python 3.6+ 否则使用字符串格式化 str.format (Option#2)

  • 模板字符串对于处理用户提供的字符串更有用 (选项#3)


0
投票

虽然这个问题被标记为“已回答”,但我想帮助防止答案提供的剪切粘贴不安全代码的传播。

PySpark 的 SQL 命令的文档显示,从版本 3.4 开始,您现在可以添加位置参数:

spark.sql("SELECT column1, column2 FROM your_db_name.your_table_name WHERE column1 = ?", args=['some_value'])
参数化 SQL 不允许替换数据库、表名或列名。  如果您确实需要这个,那么 Spark API 允许使用 kwargs 进行简单的 f 字符串样式替换:

spark.sql("SELECT column1, column2 FROM {db_name}.{table_name} WHERE column1 = ?", args=['some_value'], db_name='your_db_name', table_name='your_table_name')
但是,这只是使用简单的Python f 字符串替换,并且

并不能防止SQL注入攻击。 如果您确实需要此功能,那么您必须确保 db_name 和 table_name 参数来自安全(即用户不可篡改)来源。 根据 OWASP 指南,“手动转义 SQL 查询输入中的字符会有所帮助,但它不会使您的应用程序免受 SQL 注入攻击。”

© www.soinside.com 2019 - 2024. All rights reserved.