如何在我的 python 代码中执行 mysql 语句?

How to execute the mysql statement in my python code?

我可以在我的 sql 客户端中 运行 以下 sql 和 return 正确的结果 :

mysql> select cj.name job_name , cb.build_result build_result, count(*) total , GROUP_CONCAT(cb.id) id_list 
       from ci_build as cb INNER JOIN ci_job as cj 
       ON cb.job_id = cj.id 
       where cb.build_time > date_format('2016-04-16','%Y%m%d')
       and cb.build_time < date_format('2016-05-27','%Y%m%d') 
       GROUP BY cj.name , cb.build_result;

但是如果我使用下面的 python 代码,它将 return 错误:

ValueError:索引 225

处的格式字符 'Y' (0x59) 不受支持

任何人都可以帮助我的 python 代码出了什么问题?非常感谢~

start_time = '2016-04-16'
end_time   = '2016-05-27'

db = MySQLdb.connect(host='xxxx',port=3306,user='xxxx', passwd='xxxx', db='xxxx',charset='utf8')

sql_query  = "select cj.name job_name , cb.build_result build_result, count(*) total , GROUP_CONCAT(cb.id) id_list from ci_build as cb INNER JOIN ci_job as cj ON cb.job_id = cj.id where cb.build_time > date_format(%s,'%Y%m%d') and cb.build_time < date_format(%s,'%Y%m%d') GROUP BY cj.name , cb.build_result; % (start_time , end_time)

cursor = db.cursor()
cursor.execute(sql_query)
all_res=cursor.fetchall()
cursor.close()
db.close()

您必须将不想插值的百分号与 % 运算符的参数和其他一些内容加倍 ;-)

sql_query  = "select cj.name job_name , cb.build_result build_result, count(*) total , GROUP_CONCAT(cb.id) id_list from ci_build as cb INNER JOIN ci_job as cj ON cb.job_id = cj.id where cb.build_time > date_format('%s','%%Y%%m%%d') and cb.build_time < date_format('%s','%%Y%%m%%d') GROUP BY cj.name , cb.build_result;" % ('a', 'b')

会起作用。抱歉使用字符串文字 'a', 'b' 进行测试。您当然应该输入您的变量。

另请注意在分号后添加的结束双引号以结束字符串(如@MosesKoledoye 所述),当数据库接收到填充的字符串时,添加 '%%s' 来包装插入的字符串可能会很好文字开始和结束 "times"(但不是双引号,我认为是@sparkandshine)指出,因为这将是 "More" 有效 SQL.

正如@mhawke 所指出的:尽量不要通过从变量!

注入内容来构建sql 查询字符串

有一天你控制了它们的内容,一切都很好,第二天你重构了代码,并收到变量 "from the outside" 和 SQL 注入准备好滚动 - 尝试为所有准备好的语句复杂查询(为数据库提供在 PREPARE 阶段优化的可能性,并通过在 BIND 阶段提供更好的保护来自动添加分层安全性,拒绝在 EXECUTE 阶段时间的注入尝试。

您正在使用字符串插值替换两个 date_format() 中的 %s,但是,由于 % 是字符串插值的特殊字符,Python认为 %Y 也是字符串格式化操作。但它 Y 不是有效的格式说明符。

您可以通过将查询字符串中的 % 加倍来转义其他 % 个字符:

date_format('%s','%%Y%%m%%d')

您还需要引用 %s 因为您发送的是字符串。

但是,我建议您改用参数化查询,因为这有助于避免可能的 SQL 注入漏洞:

sql_query  = "select cj.name job_name , cb.build_result build_result, count(*) total , GROUP_CONCAT(cb.id) id_list from ci_build as cb INNER JOIN ci_job as cj ON cb.job_id = cj.id where cb.build_time > date_format(%s,'%%Y%%m%%d') and cb.build_time < date_format(%s,'%%Y%%m%%d') GROUP BY cj.name , cb.build_result"

cursor = db.cursor()
cursor.execute(sql_query, (start_time , end_time))

这在传递给 cursor.execute() 的单独元组中提供查询参数。数据库引擎将安全地执行替换,确保引号和其他特殊字符被正确转义。请注意,您不应在此处引用占位符 (%s) - 引擎会为您完成。