2012-02-11 2 views
2

Я исхожу из фона PHP. При составлении запросов SQL Я стараюсь сделать что-то вроде этого:Лучший способ склеивания строк в Python для составления SQL-запроса

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

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

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

Что бы быть лучшим/наиболее эффективный способ сделать это в Python?

+3

Что DB библиотеки вы используете? Вероятно, вам следует избегать конкатенации строк, поскольку это может привести к возникновению уязвимостей SQL-инъекций. –

+0

Чтобы расширить комментарий @MarkByers: Это то, что люди Psycopg называют наивным подходом к составу строк запроса, например. используя конкатенацию строк - http://initd.org/psycopg/docs/usage.html#the-problem-with- the-query-parameters. Вместо этого используйте параметры запроса, чтобы избежать атак SQL-инъекций и автоматически конвертировать объекты Python в и из SQL-литералов. http://stackoverflow.com/questions/3134691/python-string-formats-with-sql-wildcards-and-like?rq=1#comment24606225_3134691 –

ответ

6

Существует много способов добиться этого с помощью Python. Самый простой способ - либо использовать объект format string syntax, либо объект Template.

Преимущество синтаксиса строки формата заключается в том, что вам не нужно использовать другой объект. Пример:

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

Хотя большую часть времени Питон базы данных обертка позволит вам сделать его более безопасным (предотвращение инъекции SQL):

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

Вам, возможно, заинтересованы в этих ссылок:

Вот как это может работать на Postgresql:

ps = db.prepare("SELECT * FROM information_schema.tables WHERE table_name = $1 LIMIT $2") 
ps("tables", 1) 
+0

Мне нравится это решение намного лучше. Благодарю. –

+0

Спасибо! Удостоверьтесь, что вы правильно убегаете, хотя в противном случае у вас может быть SQL-инъекция. – charlax

+0

Спасибо, я беру его метод экранирования во втором примере, должно быть достаточно? –

4

Используйте питона DB-API подстановку параметров:

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) 

От: http://docs.python.org/library/sqlite3.html

+0

Это приятное решение, но это не то, что я искал. Что мне нравится в том, как я это делаю в этом примере PHP, так это то, что очень легко следовать логике сложных запросов, которые изменяются на основе некоторых данных. –

Смежные вопросы