2010-08-23 4 views
5

Đây là truy vấn của tôi.Chiến lược ký tự thoát tốt nhất cho kết hợp Python/MySQL là gì?

cursor2.execute("update myTable set `"+ str(row[1]) +"` = \"'" + str(row[3]) +"'\" where ID = '"+str(row[0])+"'") 

Không thành công khi giá trị hàng có dấu ngoặc kép "một số giá trị". Làm cách nào để thoát khỏi tất cả các ký tự đặc biệt?

+2

Chiến lược thoát tốt nhất cho Python + MySQL được chuẩn bị . – zneak

+0

Bạn có thể vui lòng xây dựng? Cảm ơn! – ThinkCode

+0

@zneak: prapare một chèn mở rộng với 1k hàng. – Mchl

Trả lời

13

Dưới đây là một ví dụ:

import MySQLdb 
column = str(MySQLdb.escape_string(row[1])) 
query = "update myTable set %(column)s = %%s where ID = %%s" % dict(column = column) 
cursor2.execute(query, [row[3], row[0]]) 

Cập nhật

Đây là một bài bình luận ngắn gọn:

column = str(MySQLdb.escape_string(row[1])) 

Luôn luôn là một ý tưởng tốt để thoát khỏi bất cứ điều gì mà đi vào một truy vấn. Trong trường hợp này, chúng ta tự động thêm một tên cột và do đó nó phải được thoát trước khi truy vấn được thực hiện.

query = "update myTable set %(column)s = %%s where ID = %%s" % dict(column = column) 

Tôi đang tạo truy vấn tại đây. Tôi đang cố gắng để đạt được hai điều: (1) tạo một truy vấn với tên cột được điền bằng biến số column được khai báo trong dòng trước đó (2) thêm trình giữ chỗ sẽ được điền vào bởi các tham số thực tế trong khi thực hiện truy vấn.

Đoạn mã dict(column = column) thực sự là một cách khác để tạo từ điển {'column': column}. Điều này được thực hiện bằng cách sử dụng hàm tạo dict. Tôi không muốn điền vào các chủ sở hữu địa điểm khác chỉ để tôi thoát chúng bằng cách sử dụng hai dấu hiệu phần trăm (%%).

cursor2.execute(query, [row[3], row[0]]) 

Cuối cùng, thực hiện truy vấn. Nếu bạn in truy vấn trước khi thực hiện, bạn sẽ thấy chuỗi update myTable set column_name = %s where ID = %s.

+0

Bạn có thể giải thích cách tiếp cận của mình không? Nó làm việc rực rỡ! Tôi không hiểu phần dict (column = column) .. – ThinkCode

+0

Đã cập nhật câu trả lời. Xem ở trên. –

+1

Cột thoát là sai ở đây, cột là số nhận dạng và cần 'ký tự xung quanh và tăng gấp đôi' 'nếu có một số đề tài bên trong (trong tên cột), không phải là báo giá thoát. – regilero

7

Đối với các giá trị, bạn nên sử dụng các truy vấn đã chuẩn bị để nhúng chúng. Đối với các hàng, tôi không quá chắc chắn ... nó phụ thuộc vào thiết lập của bạn. Có thể bạn sẽ muốn chấp nhận bất kỳ ký tự nào bên trên giá trị ASCII 32 ngoại trừ một dấu gạch chéo không thoát. Đừng nghĩ rằng có một chức năng cụ thể cho việc này, mặc dù.

cursor2.execute("UPDATE myTable SET `" + str(row[1]) + "` = ? WHERE ID = ?", (row[3], row[1])) 

Truy vấn đã chuẩn bị có dấu hỏi và có tham số thứ hai để chỉ định những gì cần được thay thế bằng. Người lái xe sẽ chăm sóc làm cho các giá trị an toàn. Bạn chỉ có thể đặt dấu hỏi thẩm vấn, nơi mà các giá trị được mong đợi, mặc dù; vì vậy bạn không thể sử dụng chúng làm tên cột.

7

Bạn nên học cách sử dụng các tham số truy vấn:

colname = str(row[1]).replace("`", "\\`") 
sql = "update myTable set `%s` = :col1 WHERE ID = :id" % (colname) 
cursor2.execute(sql, {"col1":str(row[3]), "id":str(row[0])}) 
+0

_mysql_exceptions.ProgrammingError: (1064, "Bạn có lỗi trong cú pháp SQL của bạn; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để sử dụng đúng cú pháp ': col1 WHERE ID =: id' tại dòng 1") con trỏ? Cảm ơn bạn .. – ThinkCode

+0

Có lẽ các tham số được đặt tên chỉ dành cho Oracle. Hãy thử sử dụng '?' Các tham số vị trí thay vì như trong câu trả lời từ @zneak. –

2

Khi bạn sử dụng Oracle MySql connector bạn có thể thoát khỏi nhân vật đặc biệt theo một cách sau:

truy vấn
import mysql.connector 
from mysql.connector import conversion 

query = "SELECT id, code, name, description FROM data WHERE code='{:s}'" 

escaped_text = conversion.MySQLConverter().escape(unescaped_text) 

cursor.execute(query.format(escaped_text)) 
+0

Điều này dường như không hoạt động như mong đợi: 'conversion.MySQLConverter(). Escape ('blah; truncate other;')' => ''blah; cắt ngắn khác; ''. – b4hand