import os
import MySQLdb
import time
db = MySQLdb.connect(host="localhost", user="root", passwd="********", db="workspace")
cursor = db.cursor()
tailoutputfile = os.popen('tail -f syslog.log')
while 1:
x = tailoutputfile.readline()
if len(x)==0:
break
y = x.split()
if y[2] == 'BAD':
timestring = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
if y[2] == 'GOOD':
print y[4] + '\t' + y[7]
所以我运行程序,这是我得到的错误消息
user@machine:~/$ python reader.py
Traceback (most recent call last):
File "reader.py", line 17, in ?
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
File "/usr/lib/python2.4/site-packages/MySQLdb/cursors.py", line 163, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.4/site-packages/MySQLdb/connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[4], y[7]' at line 1")
user@machine:~/$
所以我假设错误显然来自SQL语句
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
这是y [4]和y [7]的样子。
YES Mail.Sent.To.User:user@work.com.11.2.2008:23.17
是否发生了此错误,因为我在尝试将其插入数据库之前应该转义这些值? 或者我完全忽略了这一点?
任何帮助将不胜感激! 提前致谢。
答案 0 :(得分:9)
正如所指出的那样,你没有将Python变量值复制到查询中,只能将它们的名称复制到MySQL中。
但是直接字符串连接选项:
cursor.execute("INSERT INTO releases (date, cat, name) VALUES ('%s', '%s', '%s')" % (timestring, y[4], y[7]))
很危险,不应该使用。如果这些字符串具有像'或\ in这样的越界字符,那么你会得到一个SQL注入导致可能的安全性泄露。也许在您的特定应用程序中永远不会发生,但它仍然是一个非常糟糕的做法,初学者的SQL教程确实需要停止使用。
使用MySQLdb的解决方案是让DBAPI层负责为您插入和转义参数值到SQL,而不是自己尝试%:
cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))
答案 1 :(得分:4)
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
应该是
cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, '%s', '%s')" % (y[4], y[7]))
调试这样的事情最好的办法是将查询放入变量并使用:
query = "INSERT INTO releases (date, cat, name) values (timestring, '%s', '%s')" % (y[4], y[7])
print query
cursor.execute(query)
该印刷声明将使问题非常明显。
如果您要使用列表变量很多,这会让人感到非常困惑,请考虑只使用一次列表并将变量放入字典中。输入时间要长一些,但要更容易跟踪正在发生的事情。
答案 2 :(得分:1)
永远不要在SQL中使用“直接字符串连接”,因为它不安全,更正确的变体:
cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))
它会自动转义值中的禁止符号(例如“,”等)