2011-05-17 82 views
0

我的目标是在Python动态生成类似于SQL查询,的Python - 生成多行更新查询

UPDATE SURV_SCF_ID_STATUS 
    SET AGE_STATUS = CASE NAME 
     WHEN 'entityXp1' THEN '1' 
     WHEN 'entityXp3' THEN '0' 
     WHEN 'entityXpto1' THEN '1' 
     WHEN 'entityXpto3' THEN '1' 
    END 
WHERE NAME IN ('entityXp1', 'entityXp3', 'entityXpto1', 'entityXpto3') 

这是我到目前为止, 但仍感觉像一个丑陋的黑客攻击,

logs_age_list = [['entityXp1', '1'], ['entityXp3', '0'], ['entityXp1', '1'], ['entityXpto3', '1']] 
conditions_list = [] 
where_list = [] 
for entity, status in logs_age_list: 
conditions_list.append("\t\tWHEN %(entity)s THEN %(value)s" % locals()) 
where_list.append(entity) 

conditions_string = '\n'.join(conditions_list) 
where_string = ', '.join(where_list) 

sql = ''' 
UPDATE SURV_SCF_ID_STATUS 
    SET AGE_STATUS = CASE NAME 
%(conditions_string)s 
END 
WHERE NAME IN (%(where_string)s) 
''' % locals() 

print sql 

有没有更明显的方法来做到这一点? 我没有找到任何允许这个的Python模块。

感谢

+1

第二线的例子说:“显式优于隐式”。我会不惜任何代价避免%本地人()。 – atomocopter 2011-05-17 11:43:48

+0

它不是也说, “美丽比丑陋/简单胜过复杂”? 在阅读wiki.python.org/moin/PythonSpeed/PerformanceTips和Zen状态“可读性计数”后,我开始将它用于可读性目的 – 2011-05-17 15:31:13

回答

1

您可以通过建立

conditions_string = ' '.join(["\t\tWHEN %s THEN %s\n" % (x, y) for x, y in logs_age_list]) 

的condition_string和where_string作为

where_string = ', '.join([duo[0] for duo inlogs_age_list]) 

然后像做

sql = ''' 
UPDATE SURV_SCF_ID_STATUS 
SET AGE_STATUS = CASE NAME 
%s 
END 
WHERE NAME IN (%s) 
''' % (conditions_string, where_string) 

但generall你应该尝试使用DB模块的执行方法来避免SQL注入。

这里是用Python的禅http://docs.python.org/library/sqlite3.html

# Never do this -- insecure! 
symbol = 'IBM' 
c.execute("... where symbol = '%s'" % symbol) 

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

我的模块生成数据,因此它应该被消毒 但我怎么能有一个这些SLQ注射预防措施多次更新? 感谢您的优化。 – 2011-05-17 14:55:05