我是MySQL和Python的全新手,我正在尝试使用python从简单的csv文件读取一列浮点数据到本地MySQL表中,但它反复抛出一些错误。在键盘上敲了几个小时后,我纠正了一些语法错误,现在我被困在这里了。任何帮助将不胜感激。同时请原谅我这个问题的格式,因为这是我第一次。
import csv
import MySQLdb
mydb = MySQLdb.connect(host='localhost',
user='root',
passwd='',
db='test1')
cursor = mydb.cursor()
csv_data = csv.reader(file('csv1.csv'))
for row in csv_data:
cursor.execute("INSERT INTO log1(speed) values( %s )" %row)
#close the connection to the database.
mydb.commit()
cursor.close()
print "Done"
这是显示的错误:
Traceback (most recent call last):
File "test2.py", line 13, in <module>
cursor.execute("INSERT INTO log1(speed) values( %s )" %row)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 226, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise 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 '['85.26'] )' at line 1")
csv文件包含以下某些测试数据:
85.26
72.67
80.12
99.86
65.64
我的数据库似乎具有以下结构:
+-------+---------+
| speed | test_id |
+-------+---------+
| 98.86 | 1 |
| 88.86 | 2 |
| 78.86 | 3 |
+-------+---------+
速度是需要从csv文件中读取的字段,而 test_id 是自动递增的主键
修改
根据Visweswaran的建议,我更改了我的代码如下:
import csv
import MySQLdb
mydb = MySQLdb.connect(host='localhost',
user='root',
passwd='',
db='test1')
cursor = mydb.cursor()
csv_data = csv.reader(file('csv1.csv'))
for row in csv_data:
cursor.execute("INSERT INTO log1(speed) values( %s )" %row[0])
#close the connection to the database.
mydb.commit()
cursor.close()
print "Done"
现在这似乎修复了Type:List错误,但现在我收到以下错误:
File "test2.py", line 12, in <module>
cursor.execute("INSERT INTO log1(speed) values( %s )" %row[0])
IndexError: list index out of range
我很确定我错过了一些基本的东西并做了一些非常愚蠢的事情,但是你的支持对我来说非常有帮助。
答案 0 :(得分:2)
形成你的问题我已经复制了这样的表格,
如果不存在则创建表log1(speed float not null,test_id int(2)unsigned primary key auto_increment);
但是这行是列表中的字符串而不是字符串,所以我将你的查询修改了一下,
>>> if len(row) > 0:
cursor.execute("INSERT INTO log1(speed) values( %s )" %row[0])
csv将元组(在数据库中 - 也称为行)作为python列表传递。因为你只有一列我添加了row [0],它给出了每行第一列中的值。
最后,插入值
+-------+---------+
| speed | test_id |
+-------+---------+
| 85.26 | 1 |
| 72.67 | 2 |
| 80.12 | 3 |
Parfa正在说什么:为什么不应该使用字符串格式来构建查询
他说代码很容易受到关系数据库管理系统指纹识别的影响。
在表格中考虑以下代码:
value = input("Enter the value: ")
cursor.execute("select * from log1 where test_id = "+value)
data = cursor.fetchall()
for i in data:
print(i['speed'])
print(i['test_id'])
用户应输入test_id的值,并显示speed和test_id。
考虑一下,我是一个远程用户(攻击者)现在我输入1并且你的程序将输出这个
Enter the value: 1
1.0
1
Done
好的,它很好,它给了我速度和test_id,程序运行正常。
好的,现在我将此作为精心设计的查询输入,
Enter the value: 1 order by 1--
1.0
1
Done
查看相同的输出显示,但现在当我将此查询作为输入时输入值:1 by order 3-- 显示一条错误消息,以便我居住在偏远的地方,知道您的数据库中有一个表有两列。
现在,请参阅此输入
Enter the value: -1 union select 1,unhex(hex(version()))--
1.0
b'5.X.X-X'
Done
我可以获得你的数据库版本5.X.X(实际输出将显示确切的版本。我有点偏执)。
这种类型的攻击称为基于联合的SQL注入攻击。还有其他各种类别,比如盲人等,我不愿意在这里引诱这么多东西。
正如他所建议的那样,我会编写一个查询来传递这样的参数,
cursor.execute("select * from log1 where test_id = ",value)
现在我们将尝试获取版本
Enter the value: 1 union select 1,unhex(hex(verison()))--
结果:TypeError ....
即使这不是一个完整的解决方案。你必须集中很多漏洞。
请不要担心(正如你所说的noobie)没有任何机构是这个安全领域的专家。这需要经验。