6
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)

Im using pandas read_sql function to safely pass arguments to my query string. I would like to return the final query string with the arguments replaced as well as the results. So for example, return the string:

select *
from tbl 
where metric = 'sales'
;

Any way to do this?

4 Answers 4

2

OK, in that case try this:

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']
Sign up to request clarification or add additional context in comments.

3 Comments

how does this return the query string? (It also throws an error)
wait, are you just trying to format the query string, or do you want to input the resulting data from the query into a pandas DataFrame (which is what read_sql is for)?
I want both. I want to pass parameters to read_sql, but also get the query string back. With the arguments substituted.
0

If you are using psycopg2, then you could try using your mysql_conn instance to create a cursor, then mogrify q.

This worked for me:

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)

Comments

0

I don't think read_sql has that option but you can reconstitute what the query would look like with regular expressions.

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
 ;

This only works with one parameter per query. If you have more you could create a list of params found using re.findall as above and iterate over them to replace

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
 ;

Comments

0

To extend and fix some issues in @tvashtar 's answer

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)

After processing through the list of params, actual_q will have the value replaced query string

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.