2008-11-24 33 views
6

Có ai biết nếu có cách tự động mở rộng danh sách bằng Python, phân cách bằng dấu phẩy không? Tôi đang viết một số mã Python sử dụng thư viện MySQLdb, và tôi đang cố gắng tự động cập nhật danh sách các hàng trong cơ sở dữ liệu MySQL với một số giá trị khóa nhất định.Tự động mở rộng danh sách Python với đầu ra được định dạng

Ví dụ: trong mã bên dưới, tôi muốn có các giá trị số trong danh sách record_ids mở rộng thành một mệnh đề SQL "IN".

import MySQLdb 
record_ids = [ 23, 43, 71, 102, 121, 241 ] 

mysql = MySQLdb.connect(user="username", passwd="secret", db="apps") 
mysql_cursor = mysql.cursor() 

sqlStmt="UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 

mysql_cursor.execute(sqlStmt, record_ids) 
mysql.commit() 

Mọi trợ giúp sẽ được đánh giá cao!

Trả lời

18

thử:

",".join(map(str, record_ids)) 

",".join(list_of_strings) gia nhập một danh sách các chuỗi bằng cách tách chúng bằng dấu phẩy

nếu bạn có một danh sách các số, map(str, list) sẽ chuyển đổi nó vào một danh sách các chuỗi

+0

Thanks, điều này đã làm các trick! – m0j0

2

Tiếp tục với các câu trả lời đã cho, lưu ý rằng bạn có thể muốn trường hợp đặc biệt trường hợp danh sách trống là "where rec_id in()" không phải là SQL hợp lệ, do đó bạn sẽ gặp lỗi.

Cũng rất cẩn thận khi xây dựng SQL theo cách thủ công như thế này, thay vì chỉ sử dụng các tham số tự động thoát. Đối với một danh sách các số nguyên, nó sẽ hoạt động, nhưng nếu bạn đang xử lý các chuỗi nhận được từ đầu vào của người dùng, bạn sẽ mở ra một lỗ hổng SQL injection rất lớn bằng cách làm điều này.

+0

+1 Vui lòng sử dụng các biến Bind. http://stackoverflow.com/questions/1973/what-is-the-best-way-to-avoid-sql-injection-attacks –

+0

Điều này sẽ chỉ đọc dữ liệu từ cơ sở dữ liệu và cập nhật dữ liệu. Nó sẽ không bao giờ sử dụng dữ liệu được nhập từ Internet. – m0j0

+0

Cẩn thận: nhiều dữ liệu trong cơ sở dữ liệu được người dùng nhập cuối cùng. Ngay cả khi trường hợp của bạn là hoàn toàn an toàn, một số trường hợp sau này có vấn đề tương tự có thể quyết định sao chép mã hiện có. Đó là một ý tưởng tốt để quan tâm đến những điều này ngay cả khi nó an toàn. Tốt hơn để củng cố và thể hiện thói quen tốt hơn là xấu. – Brian

1

tôi làm những thứ như thế này (để đảm bảo tôi đang sử dụng các ràng buộc):

sqlStmt=("UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 
    % ', '.join(['?' for n in record_ids])) 

mysql_cursor.execute(sqlStmt, record_ids) 
mysql.commit() 

này làm việc cho tất cả các danh sách động bạn muốn để ràng buộc mà không để lại cho bạn dễ bị tấn công SQL injection.

+0

Tôi không nghĩ rằng dấu hỏi làm việc cho các ràng buộc MySQL. – m0j0

+0

Đó là nhược điểm của API DB của python. Tôi đã thực hiện ở trên cho sqlite và postgres, nhưng nó là vào trình điều khiển để quyết định cách bindings làm việc. Tuy nhiên, nguyên tắc tương tự cũng được áp dụng. Tạo các ràng buộc và nạp dữ liệu vào. – Dustin

0

thay thế Hơi khác nhau để trả lời Dustin của:

sqlStmt=("UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 
    % ', '.join(['?' * len(record_ids]))) 
+0

Điều đó không mở rộng đúng cách, nhưng điều này không: ',' .join ('?' * Len (record_ids)) - Tôi giống như vậy, mặc dù nó cảm thấy hơi sai. – Dustin

0

Alternitavely, sử dụng thay:

sqlStmt="UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in " + 
    record_ids.__str__().replace('[','(').replace(']',')') 
Các vấn đề liên quan