Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to string format SQL IN clause with Python

I am trying to create a statement as follows:

SELECT * FROM table WHERE provider IN ('provider1', 'provider2', ...)

However, I'm having some trouble with the string formatting of it from the Django API. Here's what I have so far:

profile = request.user.get_profile()
providers = profile.provider.values_list('provider', flat=True) # [u'provider1', u'provider2']
providers = tuple[str(item) for item in providers] # ('provider1', 'provider2')

SQL = "SELECT * FROM table WHERE provider IN %s"
args = (providers,)
cursor.execute(sql,args)

DatabaseError
(1241, 'Operand should contain 1 column(s)')
like image 238
David542 Avatar asked Jun 25 '12 19:06

David542


People also ask

What is %s in SQL Python?

As you can see, we are using a placeholder ( %s ) for the salary and id column. We need to supply values in placeholders ( %s ) before executing a query. Pass Python variables at the placeholder's position when we execute a query. We need to pass the following two arguments to a cursor.

Can you format a string in Python?

Python uses C-style string formatting to create new, formatted strings. The "%" operator is used to format a set of variables enclosed in a "tuple" (a fixed size list), together with a format string, which contains normal text together with "argument specifiers", special symbols like "%s" and "%d".

What does %d and %S mean in Python?

%s is used as a placeholder for string values you want to inject into a formatted string. %d is used as a placeholder for numeric or decimal values.

How do you change a string format in Python?

Use the format code syntax {field_name: conversion}, where field_name specifies the index number of the argument to the str. format() method, and conversion refers to the conversion code of the data type.


2 Answers

MySQLdb has a method to help with this:

Doc

string_literal(...) string_literal(obj) -- converts object obj into a SQL string literal. This means, any special SQL characters are escaped, and it is enclosed within single quotes. In other words, it performs:

"'%s'" % escape_string(str(obj))

Use connection.string_literal(obj), if you use it at all.
_mysql.string_literal(obj) cannot handle character sets.

Usage

# connection:  <_mysql.connection open to 'localhost' at 1008b2420>

str_value = connection.string_literal(tuple(provider))
# '(\'provider1\', \'provider2\')'

SQL = "SELECT * FROM table WHERE provider IN %s"
args = (str_value,)
cursor.execute(sql,args) 
like image 138
jdi Avatar answered Oct 08 '22 22:10

jdi


Another answer that I don't like particularly, but will work for your apparent use-case:

providers = tuple[str(item) for item in providers] # ('provider1', 'provider2')
# rest of stuff...

SQL = 'SELECT * FROM table WHERE provider IN {}'.format(repr(providers))
cursor.execute(SQL)
like image 42
Jon Clements Avatar answered Oct 08 '22 23:10

Jon Clements