2

I'm coming from PHP background. When composing SQL queries I tend to do something like this:

$query = '
SELECT
    *
FROM `table` AS t
WHERE 
    t.`categoryID` = '.$categoryID.'
';

if(!empty($recordID))
{
$query .= '
    AND t.`recordID` = '.$recordID.'
';
}

$data = $db->fetchAll($query);

What would be the best/most efficient way of doing this in Python?

2
  • 3
    What DB library are you using? Probably you should avoid string concatenation altogether as it risks introducing SQL injection vulnerabilities. Commented Feb 11, 2012 at 0:58
  • To expand on @MarkByers comment: This is what the Psycopg people call a a naïve approach to the composition of query strings, e.g. using string concatenation - initd.org/psycopg/docs/… . Instead use query parameters to avoid SQL injection attacks and to automatically convert Python objects to and from SQL literals. stackoverflow.com/questions/3134691/… Commented Jun 10, 2013 at 13:25

2 Answers 2

10

There are many way you can achieve it using Python. The simplest would be to either use the format string syntax or the Template object.

The advantage of the format string syntax is that you don't need to use another object. Example:

query = "SELECT * FROM `table` AS t WHERE t.`categoryID`={}".format(category_id)
if record_id:
    query += " AND t.`recordID`={}".format(record_id)

Although most of the time the database Python wrapper will let you make it more secure (preventing SQL injection):

cursor.execute("UPDATE Writers SET Name = %s WHERE Id = %s", ("Leo Tolstoy", "1"))    

You maybe interested in these links:

Here is how it can work for Postgresql:

ps = db.prepare("SELECT * FROM information_schema.tables WHERE table_name = $1 LIMIT $2")
ps("tables", 1)
Sign up to request clarification or add additional context in comments.

5 Comments

I like this solution much better. Thanks.
Thanks! Make sure you properly escape though, otherwise you may have SQL injection.
Thanks, I take it escaping method in your second example should be sufficient?
Yes! What database are you using? You maybe interested in this discussion too: stackoverflow.com/questions/897020/…
I suppose f'' instead of format will also prevent sql injections ? Aren't both the same?
5

Use the python DB-API parameter substitution:

symbol = 'IBM'

# Do this 
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)

# Larger example
for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
          ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
         ]:
    c.execute('insert into stocks values (?,?,?,?,?)', t)

From: http://docs.python.org/library/sqlite3.html

1 Comment

That's a nice solution but it's not really what I was looking for. What I like about the way I do it in this PHP example is that it is very easy to follow the logic for complex queries that change based on some data.

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.