【问题标题】:Python MySQL Statement returning ErrorPython MySQL 语句返回错误
【发布时间】:2008-11-02 23:26:35
【问题描述】:

嘿,我对这一切都很陌生,所以请原谅愚蠢:)

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

发生此错误是因为我应该在尝试将这些值插入数据库之前转义这些值吗? 还是我完全没有抓住重点??

任何帮助将不胜感激! 提前致谢。

【问题讨论】:

    标签: python sql


    【解决方案1】:

    正如所指出的,您没有将 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]))
    

    【讨论】:

      【解决方案2】:
       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)
      

      那个打印语句会让问题很明显。

      如果您要像这样大量使用列表变量,可能会非常混乱,请考虑只使用一次列表并将变量放入字典中。输入的时间有点长,但要跟踪正在发生的事情要容易得多。

      【讨论】:

      • 您可能还需要在 [y4] 和 [y7] 中的字符串周围加上引号
      【解决方案3】:

      永远不要在 SQL 中使用“直接字符串连接”,因为它不安全,更正确的变体:

      cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))
      

      它会自动转义值中的禁止符号(例如“,”等)

      【讨论】:

        猜你喜欢
        • 2016-11-12
        • 1970-01-01
        • 2019-12-21
        • 1970-01-01
        • 2015-04-13
        • 2013-10-06
        • 1970-01-01
        • 2017-05-10
        • 2013-11-26
        相关资源
        最近更新 更多