Python pandas read_sql返回带有传递参数的查询字符串

Python pandas read_sql返回带有传递参数的查询字符串,python,sql,pandas,Python,Sql,Pandas,我使用pandas read_sql函数安全地将参数传递给我的查询字符串。我想返回最终的查询字符串,并替换参数和结果。例如,返回字符串: import pandas as pd q = """ select * from tbl where metric = %(my_metric)s ; """ params = {'my_metric':'sales'} pd.read_sql(q, mysql_conn, params=params)

我使用pandas read_sql函数安全地将参数传递给我的查询字符串。我想返回最终的查询字符串,并替换参数和结果。例如,返回字符串:

import pandas as pd
q = """
     select *
     from tbl 
     where metric = %(my_metric)s
     ;
     """
params = {'my_metric':'sales'}
pd.read_sql(q, mysql_conn, params=params)

有什么方法可以做到这一点吗?

好的,在这种情况下,请尝试以下方法:

select *
from tbl 
where metric = 'sales'
;

如果您使用的是psycopg2,那么您可以尝试使用
mysql\u conn
实例创建游标,然后使用
q

这对我很有用:

import pandas as pd    
q = """
 select *
 from tbl 
 where metric = %s
 ;
 """
params = {'my_metric': 'sales'}
df = pd.read_sql(q, mysql_conn, params=[params['my_metric']])
query_string = q % params['my_metric']

我不认为read_sql有这个选项,但您可以用正则表达式重新构造查询

import pandas as pd
q = """
     select *
     from tbl 
     where metric = %(my_metric)s
     ;
     """
params = {'my_metric':'sales'}

cur = mysql_conn.cursor()

print cur.mogrify(q, params)
pd.read_sql(q, mysql_conn, params=params)
这只适用于每个查询一个参数。如果您有更多的参数,您可以像上面那样使用re.findall创建一个参数列表,并对它们进行迭代以替换

import re
actual_q = re.sub('%\(.*\)s',params[re.findall('%\(.*\)s',q)[0].strip('%(').strip(')s')],q)
print(actual_q)

 select *
 from tbl 
 where metric = sales
 ;

扩展并修复@tvashtar答案中的一些问题

q_params = re.findall('%\(.*\)s',q)
for param in q_params:
    actual_param = param.strip('%(').strip(')s')
    actual_q = re.sub('%\({}\)s'.format(actual_param), params[actual_param],q)
print(actual_q)

 select *
 from tbl 
 where metric = sales
 ;

通过参数列表进行处理后,
actual_q
将替换查询字符串的值

这如何返回查询字符串?(它还抛出一个错误)等等,你只是想格式化查询字符串,还是想将查询的结果数据输入pandas DataFrame(这就是它的用途)?我两者都想要。我想传递参数来读取sql,但也要返回查询字符串。用替换的论据。
actual_q = query_string
for param in q_params:
    actual_param = param.strip('%(').strip(')s')
    # 'param1'
    form_param = '%\({}\)s'.format(actual_param)
    # '%s\\(param1\\)s'
    value = str(params[actual_param]) if params[actual_param] else "\'\'"
    # '' if no value else the str of param1
    actual_q = re.sub(form_param, value, actual_q)
    print(actual_q)