13

I understand that the correct way to format a sql query in Python is like this:

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3)

so that it prevents sql injection. My question is if there is a way to put the query in a variable and then execute it? I have tried the example below but receive an error. Is it possible to do this?

sql="INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(sql)
asked Oct 27, 2009 at 20:02

4 Answers 4

28

Here is the call signature for cursor.execute:

Definition: cursor.execute(self, query, args=None)
 query -- string, query to execute on server
 args -- optional sequence or mapping, parameters to use with query.

So execute expects at most 3 arguments (args is optional). If args is given, it is expected to be a sequence. so

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(*sql_and_params)

is not going to work, because

cursor.execute(*sql_and_params)

expands the tuple sql_and_params into 4 arguments (and again, execute only expects 3).

If you really must use

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3

then you'll have to break it apart when feeding it to cursor.execute:

cursor.execute(sql_and_params[0],sql_and_params[1:])

But I think it feels much more pleasant to just use two variables:

sql = "INSERT INTO table VALUES (%s, %s, %s)"
args= var1, var2, var3
cursor.execute(sql, args)
answered Oct 27, 2009 at 20:51
Sign up to request clarification or add additional context in comments.

Comments

6

You're pretty close.

sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)", var1, var2, var3
cursor.execute(*sql_and_params)

The asterisk means that the variable isn't to be considered as one parameter but instead unpacked into many parameters.

answered Oct 27, 2009 at 20:05

2 Comments

why did you use , instead of %? For example to do this: sql_and_params = "INSERT INTO table VALUES (%s, %s, %s)" % (var1, var2, var3)
@bzupnick using simple string formatting (the % operator), or substitution, would potentially allow SQL injection, not to mention failing to add quotation marks to the literals if needed. Parameterized queries are highly superior to formatted/substituted queries.
1

This worked for me. Querying Microsoft SQL Server using pyodbc.

cusotmer_list = ['ABC', '123']
# parameterized query placeholders
placeholders = ",".join("?" * len(customer_list))
# query table
query = 
"""
SELECT
[ID],
[Customer]
FROM xyz.dbo.abc
WHERE [Customer] IN (%s)
""" % placeholders
# read query results in pandas dataframe
df = pd.read_sql(sql=query, con=cnxn, params=customer_list)
answered Aug 7, 2020 at 18:40

Comments

1

the best way for pass parameters to SQL query in Python is:

"INSERT INTO table VALUES (:1, :2, :3) ", [val1, val2, val3]

or another example:

"UPDATE table T SET T.column2 = :1 where T.column1= :2 ", [val1,val2]
Nolequen
4,7178 gold badges49 silver badges67 bronze badges
answered Oct 31, 2021 at 8:44

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.