0

我拥有的 Python 代码如下所示

f = open('data.tsv', 'r')

for line in f:
    a = line.split("\t")
    e_id = a[1]
    name = a[2]
    start = a[3]
    end = a[4]
    loc = a[5]
    tags = a[6]
    url = a[7]
    cur = con.cursor(mdb.cursors.DictCursor)
    cur.execute("INSERT INTO data_table VALUES (" + e_id + "," + name + "," + start + "," + end + "," + loc + "," + tags + "," + url + ");")

“loc”数据块中经常有一个逗号,因为它的很多格式是“City, State”,所以 MySQL 将它解释为一个值。我不能直接注释掉逗号,因为它们被存储为变量。有没有解决的办法?

4

3 回答 3

3

以这种格式构建查询时要小心。在连接字符串之前和之后,您需要放置逗号。例如,

INSERT INTO data_table VALUES ('" + e_id + "','" + name + "','" + start + "','" + end + "','" + loc + "','" + tags + "','" + url + "');")

我希望它有助于解决您的问题。

此外,您可以使用特定的 python 语法来执行插入:

cur.execute("INSERT INTO data_table VALUES (%s,%s,%s,%s,%s,%s,%s)",(e_id,name,start,end,loc,tags,url)); 
于 2013-05-31T14:46:24.887 回答
2

为什么没有人谈论准备好的陈述?这正是用例。这是一种更简单的语法,而且完全安全。

cur.execute("INSERT INTO data_table VALUES (?,?,?,?,?,?,?)", (e_id,name,start,end,loc,tags,url))

(语法可能略有不同。请参阅Python 支持 MySQL 准备好的语句吗?

于 2013-05-31T15:10:36.817 回答
1

您真正的问题在于您的"City, State"行是一系列字符。您不能像这样在 SQL 中直接插入字符序列:

INSERT INTO test VALUES (My String);

相反,您将其视为字符串。MySQL 期望字符串用单引号括起来,因此您可以将上面的内容更改为:

INSERT INTO test VALUES ('My String');

现在您已经'My String'存储了字符串。现在,动态生成它并没有太大的不同,除了你必须确保它用单引号括起来——比如:

loc = "City, State"
sql = "INSERT INTO test VALUES ('" + loc + "');"

注意我插入位置的单引号。

剩下的就是附加信息

这是一个危险的操作,因为我允许任何值直接进入我的数据库,即使该值"'); DROP DATABASE test; -- "会造成一些损害。你会认为它是无害的,但插入后你会得到:

INSERT INTO test VALUES(''); DROP DATABASE test; -- ');

所以现在我刚刚丢失了所有数据。要解决此问题,您需要在将值放入数据库之前对其进行转义,这与MySQLdb.escape_string(str). 然后你只需:

loc = "'); DROP DATABASE test; -- "
loc = MySQLdb.escape_string(loc);
sql = "INSERT INTO test VALUES ('" + loc + "');"

结果是:

INSERT INTO test VALUES ('\'); DROP DATABASE test; -- ');

这不会对您的数据库造成任何损害。这不是您打开自己的唯一漏洞,它是一个非常简化的示例。

于 2013-05-31T14:55:03.107 回答