2012-05-15 38 views
5

Tôi có tệp .sql chứa một loạt các truy vấn SQL, với mỗi truy vấn trải rộng trên nhiều dòng. Tôi muốn thực hiện các truy vấn này trong MySQL thông qua Python bằng cách sử dụng MySQLdb.Thực thi tệp .sql bằng Python với MySQLdb

sqlite3 has "a nonstandard shortcut" for this purpose called executescript(), nhưng dường như không có bất kỳ chức năng tương đương nào trong MySQLdb.

Tôi nhận thấy this old question from 2 years ago yêu cầu cùng một điều, nhưng tôi thấy câu trả lời không thỏa mãn. Câu trả lời về cơ bản là:

Sử dụng subprocess để chạy lệnh mysql và gửi tệp .sql của bạn.

này hoạt động, nhưng nó là khá thanh nha, và nó giới thiệu sự phức tạp không cần thiết với xử lý lỗi và như vậy.

Nếu mỗi truy vấn nằm trên một dòng, chỉ cần thực hiện từng dòng riêng biệt.

Nhưng trong trường hợp của tôi, chúng trải rộng trên nhiều dòng, vì vậy điều này sẽ không hoạt động.

Nếu mỗi truy vấn không nằm trên một dòng, bằng cách nào đó hãy kết nối chúng.

Nhưng, bằng cách nào? Ý tôi là, tôi có thể hack một thứ dễ dàng, vì vậy bạn không cần phải trả lời với câu trả lời nửa nướng ở đây, và có lẽ đó là những gì tôi sẽ làm, nhưng đã có một thư viện được thiết lập để thực hiện điều này chưa? Tôi cảm thấy thoải mái hơn với giải pháp toàn diện và chính xác hơn là hack.

+0

tôi đã đệ trình một câu trả lời rằng invovled phân tích cú pháp tập tin và xây dựng các truy vấn nhưng tôi nghĩ đó là những gì bạn có nghĩa là "hack" vì vậy tôi đã xóa nó. – acattle

Trả lời

3

MySQLdb dường như cho phép điều này ra khỏi hộp, bạn chỉ cần gọi cursor.nextset() để chuyển qua các tập kết quả trả về.

db = conn.cursor() 
db.execute('SELECT 1; SELECT 2;') 

more = True 
while more: 
    print db.fetchall() 
    more = db.nextset() 

Nếu bạn muốn hoàn toàn chắc chắn sự ủng hộ cho việc này được kích hoạt, và/hoặc vô hiệu hóa sự hỗ trợ, bạn có thể sử dụng một cái gì đó như thế này:

MYSQL_OPTION_MULTI_STATEMENTS_ON = 0 
MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1 

conn.set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON) 
# Multiple statement execution here... 
conn.set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_OFF) 
+0

Các tập lệnh MySQL .sql chứa một số [lệnh nội trang] (http://dev.mysql.com/doc/refman/5.6/en/mysql-commands.html) được xử lý bởi máy khách 'mysql', nhưng không được nhận dạng bởi trình phân tích cú pháp SQL trong máy chủ. Vì vậy, mặc dù MySQLdb có thể hỗ trợ đa truy vấn, bạn không thể nạp nó bất kỳ tập lệnh .sql tùy ý nào làm đầu vào. –

+0

@aleksi bạn giả định các giả định nguy hiểm: tôi không nghĩ rằng tôi sẽ làm việc trên một tệp lớn (x100MB +), thậm chí không nhỏ hơn. Không có máy phát điện trên các lệnh. Ngay cả việc thiết lập trình tạo lệnh cũng khó vì bạn cần một trình phân tích cú pháp tệp SQL; từng dòng một sẽ không nhất thiết phải hoạt động. spliiting bởi dấu chấm phẩy là xấu. v.v. –

+0

@BerryTsakala: Tôi đang có một thời gian thực sự khó hiểu về nhận xét của bạn. Mà nói; Có, tôi đưa ra giả định, phương pháp này sẽ không hoạt động đối với mọi trường hợp sử dụng (như đã được Bill chú ý một cách độc đáo ở trên), nhưng ít nhiều chính xác điều mà câu hỏi này yêu cầu. Và bạn có ý nghĩa gì về "nguy hiểm"? Điều này là khá nhiều như an toàn như nó được, không giống như cố gắng phân tích cú pháp các truy vấn SQL mình. Có, điều này sẽ không hoạt động đối với các tệp lớn, bạn sẽ gặp phải kích thước gói tối đa của MySQL. Tại sao bạn đang nói về phân tích cú pháp SQL từ phương pháp này một cách rõ ràng ** tránh ** điều đó? –

Các vấn đề liên quan