无法使用Python将数据从CSV复制到MySQLdb

时间:2017-08-27 08:27:28

标签: python mysql csv

我是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

我很确定我错过了一些基本的东西并做了一些非常愚蠢的事情,但是你的支持对我来说非常有帮助。

1 个答案:

答案 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)没有任何机构是这个安全领域的专家。这需要经验。