2010-09-01 87 views
52

我使用Python和MySQLdb來下載網頁並將它們存儲到數據庫中。我遇到的問題是我無法在數據庫中保存複雜的字符串,因爲它們沒有正確轉義。Escape字符串Python for MySQL

在Python中有一個函數可以用來爲MySQL轉義字符串嗎?我嘗試使用'''(三簡單引號)和""",但它沒有奏效。我知道PHP有mysql_escape_string(),在Python中類似嗎?

謝謝。

+0

做'db_cur.execute( '''更新TEST_TABLE SET field_1 = 「%s的」 WHERE field_2 =「% s''''%(data,condition))'注意'%s'周圍的三個單引號和雙引號' – zelusp 2016-10-29 01:33:01

回答

75
conn.escape_string() 

見MySQL的C API函數映射:http://mysql-python.sourceforge.net/MySQLdb.html

+1

+1 ...完美答案。驚訝於看到那麼多複雜的答案。顯然,參數化查詢不考慮正在存儲的長字符串(文本)。 – Mike 2010-11-18 23:59:29

+0

+1我喜歡黑色和白色的HTML頁面,發誓的單詞和代碼。 – Droogans 2011-12-29 01:07:02

+2

_mysql.escape_string(「input's」)也可以用於爲mysql轉義一個ascii字符串。顯然不適用於unicode。 _mysql.escape_string(u「input'séh」) – 2013-04-10 12:14:19

1

使用SQLAlchemy的文本函數刪除特殊字符的解釋:

注意使用以下功能text("your_insert_statement")的。它所做的是與sqlalchemy交流,傳入的字符串中的所有問號和百分號應視爲文字。

import sqlalchemy 
from sqlalchemy import text 
from sqlalchemy.orm import sessionmaker 
from datetime import datetime 
import re 

engine = sqlalchemy.create_engine("mysql+mysqlconnector://%s:%[email protected]%s/%s" 
    % ("your_username", "your_password", "your_hostname_mysql_server:3306", 
    "your_database"), 
    pool_size=3, pool_recycle=3600) 

conn = engine.connect() 

myfile = open('access2.log', 'r') 
lines = myfile.readlines() 

penguins = [] 
for line in lines: 
    elements = re.split('\s+', line) 

    print "item: " + elements[0] 
    linedate = datetime.fromtimestamp(float(elements[0])) 
    mydate = linedate.strftime("%Y-%m-%d %H:%M:%S.%f") 

    penguins.append(text(
    "insert into your_table (foobar) values('%%%????')")) 

for penguin in penguins: 
    print penguin 
    conn.execute(penguin) 

conn.close() 
+0

你的意思是函數? – User 2014-12-19 23:32:09

+0

是的,已更正。 – 2014-12-20 02:41:11

+0

做這項工作以逃避單引號? – user2654569 2016-04-21 15:29:41

44

的MySQLdb的庫實際上爲你做這個,如果你使用他們的實現建立,而不是試圖建立自己的SQL查詢字符串。

不要做:

sql = "INSERT INTO TABLE_A (COL_A,COL_B) VALUES (%s, %s)" % (val1, val2) 
cursor.execute(sql) 

務必:

sql = "INSERT INTO TABLE_A (COL_A,COL_B) VALUES (%s, %s)" 
cursor.execute(sql, (val1, val2)) 
+3

有點令人不安,它強制引號。例如,如果您要插入條件表(TABLE_A而不是'TABLE_A'),則無法使用此方法完成此操作。 – bozdoz 2015-05-11 19:52:21

+2

bozdoz,這是非常多的設計,因爲它可以防止SQL注入。如果要插入到條件表中,請首先確保用戶提交的字符串無法用於表名,然後直接將其添加到查詢中。 – techdude 2016-10-08 14:38:59

+1

這絕對是正確的答案。永遠不會知道有什麼新的方法來解決字符串轉義問題(就像我們目前在PHP世界中所做的那樣)。更安全地做準備陳述總是 – 2017-06-09 15:56:14

3
>>> import MySQLdb 
>>> example = r"""I don't like "special" chars ¯\_(ツ)_/¯""" 
>>> example 
'I don\'t like "special" chars \xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf' 
>>> MySQLdb.escape_string(example) 
'I don\\\'t like \\"special\\" chars \xc2\xaf\\\\_(\xe3\x83\x84)_/\xc2\xaf' 
+0

嗯。似乎StackOverflows突出顯示算法不知道Pythons三重引號。 – 2017-08-03 13:28:32