从Python插入MySQL - 错误

时间:2013-06-12 17:37:03

标签: python mysql

我正在尝试将记录写入MySQL数据库,我将表jobs定义为:

CREATE TABLE jobs(
   job_id INT NOT NULL AUTO_INCREMENT,
   job_title VARCHAR(300) NOT NULL,
   job_url VARCHAR(400) NOT NULL,
   job_location VARCHAR(150),
   job_salary_low DECIMAL(25) DEFAULT(0),
   job_salary_high DECIMAL(25), DEFAULT(0),
   company VARCHAR(150),
   job_posted DATE,
   PRIMARY KEY ( job_id )
);

我正在测试的代码是:

cur.execute("INSERT INTO jobs VALUES(DEFAULT, '"+jobTitle+"','"
    +jobHref+"',"+salaryLow+","+salaryHigh+",'"+company+"',"
    +jobPostedAdjusted+"','"+salaryCurrency+"';")
print(cur.fetchall())

我得到的错误是:

pydev debugger: starting
Traceback (most recent call last):
  File "C:\Users\Me\AppData\Local\Aptana Studio 3\plugins\org.python.pydev_2.7.0.2013032300\pysrc\pydevd.py", line 1397, in <module>
    debugger.run(setup['file'], None, None)
  File "C:\Users\Me\AppData\Local\Aptana Studio 3\plugins\org.python.pydev_2.7.0.2013032300\pysrc\pydevd.py", line 1090, in run
    pydev_imports.execfile(file, globals, locals) #execute the script
  File "C:\Users\Me\Documents\Aptana Studio 3 Workspace\PythonScripts\PythonScripts\testFind.py", line 25, in <module>
    +jobPostedAdjusted+"','"+salaryCurrency+"';")
TypeError: cannot concatenate 'str' and 'float' objects

插入此记录的最佳方法是什么?感谢。

3 个答案:

答案 0 :(得分:2)

  

插入此记录的最佳方式是什么?

使用%s占位符,并将参数作为单独的列表传递,然后MySQLdb为您执行所有参数插值。

例如......

params = [jobTitle,
          jobHref,
          salaryLow,
          salaryHigh,
          company,
          jobPostedAdjusted,
          salaryCurrency]
cur.execute("INSERT INTO jobs VALUES(DEFAULT, %s, %s, %s, %s, %s, %s, %s)", params)

这也可以保护您免受SQL注入。


<强>更新

  

我在print(cur.fetchall())之后cur.execute....   代码运行时,会打印空括号,例如()

INSERT个查询不返回结果集,因此cur.fetchall()将返回一个空列表。

  

当我从终端询问数据库时,我发现没有任何改变。

如果您正在使用像InnoDB这样的事务存储引擎,那么您已明确提交了事务,例如......

conn = MySQLdb.connect(...)
cur = conn.cursor()
cur.execute("INSERT ...")
conn.commit()

如果你想要INSERT多行,那么在单个交易中执行它会快得多......

conn = MySQLdb.connect(...)
cur = conn.cursor()
for i in range(100):
    cur.execute("INSERT ...")
conn.commit()

...因为InnoDB(默认情况下)会在每次调用conn.commit()后将数据同步到磁盘。

  

此外,commit;声明是否必须在某个地方?

commit语句由MySQL客户端而不是服务器解释,因此您无法将其与MySQLdb一起使用,但它最终与{{1}完全相同上一个例子中的行。

答案 1 :(得分:0)

错误消息全部说明:

  

TypeError:无法连接'str'和'float'对象

Python不会将automagicaly浮动转换为字符串。你最好的朋友可以 format

>>> "INSERT INTO jobs VALUES(DEFAULT, '{}', '{}')".format("Programmer", 35000.5)
"INSERT INTO jobs VALUES(DEFAULT, 'Programmer', '35000.5')"

但是,请注意,在没有任何预防措施的情况下在SQL字符串中插入用户提供的数据可能会导致SQL Injection!要小心......这就是为什么execute提供自己的行为方式,保护你免受这种风险。这样的事情:

>>> cursor.execute("INSERT INTO jobs VALUES(DEFAULT, '%s', '%f', "Programmer", 35000.5)

有关此内容的完整讨论,请搜索网页。例如http://love-python.blogspot.fr/2010/08/prevent-sql-injection-in-python-using.html


而且,顺便说一句,浮动类型主要用于科学计算。但由于舍入误差,这通常不适合货币价值(这就是为什么你的表使用DECIMAL列,而不是FLOAT列,我假设)。对于完全值,Python提供decimal类型。你应该看看它。

答案 2 :(得分:0)

如果需要A1,则无法像'A' + 1那样进行连接。正如Sylvain刚刚说的那样,format起作用:

'A{}'.format(1)

但在这种情况下,execute方法提供了自己的方法来处理这个常见问题。

execute('A%s', (1))

有关更完整的示例,请参阅documentation