字符串提取和格式化以执行SQL代码段

问题描述

我在字符串中键入了一些参数,这些参数需要使用字符串format()函数进行提取和替换。代码段如下:

# Filter list (output from another script)
filters ='recipient_id=100,reporting_date=2020-10-12'

# Fetch sql file from location
sql_file = 'configs/sql_files/{sql_name}.sql'.format(sql_name=sql_name)
file_path = os.path.realpath(__file__)
final_file_path = "/".join(file_path.split("/")[:-2]) + "/" + sql_file

with open(final_file_path) as sql_file:
    # Pass in filters to the sql snippet. The sql snippet has two parameters
    # recipient_id & reporting_date
    sql = sql_file.read().format(filters)

try:
     sf = get_sql_client()
except Exception as e:
     print("Error connecting to the DB!")
     sys.exit()

df = sf.fetch_df(sql)

由于将“过滤器”作为字符串传递,因此代码段失败。

sql_file.read().format('recipient_id=100,reporting_date=2020-10-12')

相反,应按以下方式进行传递:

sql_file.read().format(recipient_id=100,reporting_date='2020-10-12')

有没有一种方法可以提取“过滤器”字符串并按上述格式对其进行格式化?

sql文件示例:

    SELECT columns..
FROM A
join B on <condition>
WHERE true
   AND REPORTING_LEVEL_1_ID = '{recipient_id}'  
   AND date_trunc('day',delivered_date_pt) >= DATEADD(day,-7,last_day('{reporting_date}'::date,'week') + 1)
   AND date_trunc('day',delivered_date_pt) <= last_day('{reporting_date}'::date,'week')

解决方法

尝试像这样使用双引号...

filters ="recipient_id=100,reporting_date='2020-10-12'"
,

假设sql文件具有类似的内容并用于过滤信息格式(如图所示(作为一系列名称和值对,用逗号和空格字符分隔)),则可以从后者创建字典,然后将其传递给{如图所示的{1}}方法(使用format()前缀来解压缩其中的项目)。

**

输出:

filter_data = 'recipient_id=100,reporting_date=2020-10-12'
final_file_path = 'sql_file'

with open(final_file_path) as sql_file:
    pairs = (pair.split('=') for pair in filter_data.replace(',','').split())
    mapping = {k: v for (k,v) in pairs}
    sql = sql_file.read().format(**mapping)
    print(sql)