2

I'm trying to execute a query using two parameters, one is a list and the other is a number.

Here is my code:

cursor.execute("SELECT cod_art, price_EU, price_third_country 
 FROM lt_gamma_articles 
 WHERE cod_art in (%s) AND cod_store = %d 
 ORDER BY cod_art, timestamp" 
 % format_strings, tuple(cod_art_int), int(shop) )

I get this error:

TypeError: not enough arguments for format string

I think the error is in the string formatting, but I don't know how to format it correctly and I've been stuck for a while.

ohmu
19.8k44 gold badges114 silver badges151 bronze badges
asked Feb 12, 2018 at 16:10

1 Answer 1

2

From the looks of your code, I'm gussing your basing it off of imploding a list for use in a python MySQLDB IN clause. Assuming that's the case, and format_strings is built similar to:

format_strings = ','.join(['%s'] * len(cod_art_int))

I would use .format to build the query string, and build up a list for the positional query parameters:

query_params = list(cod_art_int)
query_params.append(int(shop))
query_sql = """
 SELECT cod_art, price_EU, price_third_country 
 FROM lt_gamma_articles
 WHERE cod_art IN ({cod_art_list}) AND cod_store = %s 
 ORDER BY cod_art, timestamp
""".format(cod_art_list=format_strings)
cursor.execute(query_sql, query_params)

Explanation:

Say cod_art_int is this list of integer values:

cod_art_int = [10, 20, 30]

In order to use those values in the cod_art IN (...) part of the query, you need to add a %s for each one. That is done by:

format_strings = ','.join(['%s'] * len(cod_art_int))

Which can be broken down to:

step_one = ['%s'] * len(cod_art_int)
# ['%s', '%s', '%s']
format_strings = ','.join(step_one)
# '%s,%s,%s'

When you build the final query string, you replace {cod_art_list} with format_strings:

query_sql = """
 SELECT cod_art, price_EU, price_third_country 
 FROM lt_gamma_articles
 WHERE cod_art IN ({cod_art_list}) AND cod_store = %s 
 ORDER BY cod_art, timestamp
""".format(cod_art_list=format_strings)

And you get the query string:

SELECT cod_art, price_EU, price_third_country 
FROM lt_gamma_articles
WHERE cod_art IN (%s,%s,%s) AND cod_store = %s 
ORDER BY cod_art, timestamp

Then your query parameters will be safely substituted within the query to replace the %ss. You build up the parameter list to correspond to the %ss. Since cod_art IN (%s,%s,%s) is first, you add that to the list first, followed by the value for cod_store (int(shop) which I'm going to say is 456):

query_params = list(cod_art_int)
# [10, 20, 30] 
query_params.append(int(shop))
# [10, 20, 30, 456] 

In the end you execute the query with its parameters:

cursor.execute(query_sql, query_params)
answered Feb 12, 2018 at 23:15
Sign up to request clarification or add additional context in comments.

2 Comments

Bingo! It worked! Thank you very much! Do you have a source like a link or something for me to understand this ?
@AlbertS. I don't have a good link, but see my update to the answer.

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.