2013-06-12 55 views
1

我試圖寫一個記錄到這裏,我定義的表jobs爲MySQL數據庫:插入到MySQL從Python中 - 錯誤

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 

插入此記錄的最佳方式是什麼?謝謝。

+1

請不要將查詢建立爲字符串,請使用參數化查詢,這樣您就不會將自己打開到sql注入 – dm03514

+1

@ dm03514:感謝您指出了這一點。 –

回答

2

What is the best way insert this record?

使用%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注入。


更新

I have print(cur.fetchall()) after the cur.execute.... When the code is run, it prints empty brackets such as () .

INSERT查詢不返回結果集,所以cur.fetchall()會返回一個空列表。

When I interrogate the DB from the terminal I can see nothing has been changed.

如果你使用像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()後的數據到硬盤進行同步。

Also, does the commit; statement have to be in somewhere?

commit聲明是由MySQL客戶端,而不是服務器的解釋,所以你將無法與MySQLdb使用它,但它最終做同樣的事情與前面的例子中conn.commit()線。

+0

便士不下降。我試過這個,但無濟於事? 'cur.execute ...'後面有'print(cur.fetchall())''。當代碼運行時,它會打印空括號,例如'()'。當我從終端詢問數據庫時,我看不到任何變化。另外,'commit;'語句是否必須在某處? –

+0

@I_lost_my_last_account查看更新的答案。 – Aya

+0

您更新的答案清除了一切;還添加了'con.commit()'現在正在將記錄寫入數據庫。謝謝。 –

0

錯誤消息說明了一切:

TypeError: cannot concatenate 'str' and 'float' objects

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類型。你應該看看它。

+0

我很高興你指出了使用花車進行貨幣價值的差異。浮動的原因正在使用是因爲我以前的帖子在這裏:http://stackoverflow.com/questions/17057406/mysql-and-python-convert-string-value-to-int-to-float-or-what/ 17057737#17057737我執行@ theodox的代碼之後。如果你看一看,那裏有更多的清晰。但現在我擔心這個小數點/浮點數問題。你會建議什麼?我是一個初學者,因此作出了決定。 –

0

當你想A1,你不能像'A' + 1連接。作爲西爾只是幫腔,format作品:

'A{}'.format(1) 

但在這種情況下,執行方法提供它自己的方式來處理這個常見的問題。

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

有關更完整的示例,請參閱documentation