Python MySQL Statement, возвращающий ошибку - PullRequest
2 голосов
/ 03 ноября 2008

эй, я очень новичок во всем этом, поэтому, пожалуйста, извините за глупость

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

Эта ошибка происходит, потому что я должен экранировать эти значения, прежде чем пытаться вставить их в базу данных? Или я полностью упускаю суть ??

Любая помощь будет принята с благодарностью! заранее спасибо.

Ответы [ 3 ]

9 голосов
/ 03 ноября 2008

Как указывалось, вы не можете скопировать значения переменных 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]))
4 голосов
/ 03 ноября 2008
 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)

Это выражение для печати сделало бы совершенно очевидным, в чем проблема.

Если вы собираетесь использовать переменные списка очень похожими, это может привести к путанице, рассмотрите возможность использования списка только один раз и помещения переменных в словарь. Это немного дольше печатать, но намного, намного легче отслеживать, что происходит.

1 голос
/ 18 ноября 2008

никогда не используйте «прямую конкатенацию строк» ​​с SQL, потому что это небезопасный, более правильный вариант:

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

автоматически экранирует запрещенные символы в значениях (например, ", 'и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...