2009-03-15 26 views
14

Tôi muốn bắt và ghi nhật ký MySQL bằng Python. Ví dụ, MySQL đưa ra cảnh báo lỗi chuẩn nếu bạn gửi 'DROP DATABASE IF EXISTS database_of_armaments' khi không có cơ sở dữ liệu nào tồn tại. Tôi muốn nắm bắt điều này và đăng nhập nó, nhưng ngay cả trong cú pháp try/else thông điệp cảnh báo vẫn xuất hiện.Bẫy cảnh báo MySQL bằng Python

Cú pháp thử/ngoại lệ không phát hiện lỗi MySQL (ví dụ: gửi lỗi đánh máy như 'DRP DATABASE database_of_armaments').

Tôi đã thử nghiệm với <<except.MySQLdb.Warning>> - không có may mắn. Tôi đã xem xét các mô-đun cảnh báo, nhưng không hiểu cách kết hợp nó vào cú pháp try/else.

Để cụ thể, làm thế nào để tôi có được những thứ sau (hoặc thứ gì đó tương tự) hoạt động.

GIVEN: cơ sở dữ liệu 'database_of_armaments' không tồn tại.

try: 
    cursor.execute('DROP DATABASE IF EXISTS database_of_armaments') 
except: <<WHAT DO I PUT HERE?>> 
    print 'There was a MySQL warning.' 
    <<AND what goes here if I want to get and manipulate information about the warning?>> 

UPDATE:

Cám ơn ý kiến. Tôi đã thử những điều này và chúng không hoạt động - nhưng tôi đã sử dụng một lớp DatabaseConnection mà tôi đã viết cho một kết nối và phương thức runQuery() của nó để thực thi. Khi tôi tạo một kết nối và con trỏ bên ngoài lớp, ngoại lệ try/except đã bắt gặp lỗi "Lập trình lỗi" và ngoại trừ MySQLdb.ProgrammingError làm việc như được quảng cáo.

Vì vậy, bây giờ tôi phải tìm ra điều gì sai với mã hóa lớp học của mình.

Cảm ơn sự giúp đỡ của bạn.

+1

tôi không tìm thấy bất kỳ câu trả lời ở đây hữu ích, nhưng http://stackoverflow.com/a/2102315/91238 là. – arantius

Trả lời

15

Làm theo các bước sau.

  1. Chạy với except Exception, e: print repr(e).

  2. Xem ngoại lệ bạn nhận được.

  3. Thay đổi Exception thành ngoại lệ bạn thực sự có.

Ngoài ra, hãy nhớ rằng ngoại lệ, e, là một đối tượng. Bạn có thể in dir(e), e.__class__.__name__, v.v để xem thuộc tính của nó.

Ngoài ra, bạn có thể thực hiện tương tác này tại dấu nhắc >>> bằng Python. Sau đó bạn có thể thao tác trực tiếp đối tượng - không đoán.

+0

Điều này đã giúp tôi, như django helpfully sử dụng tên ngoại lệ giống như kết nối MySQL cơ bản; 'OperationalError'. Tôi đã chuyển 'từ MySQLdb import OperationalError' sang' từ django.db.utils nhập OperationalError' ở đầu tệp của tôi, và tôi đột nhiên có thể bắt được ngoại lệ. –

7

Bạn đã thử một cái gì đó như thế này?

try: 
    cursor.execute(some_statement) 
except MySQLdb.IntegrityError, e: 
    # handle a specific error condition 
except MySQLdb.Error, e: 
    # handle a generic error condition 
except MySQLdb.Warning, e: 
    # handle warnings, if the cursor you're using raises them 
+0

Mặc dù câu trả lời này có thể kỹ lưỡng hơn, nhưng nó vẫn là một khởi đầu tốt hơn so với những câu trả lời khác, tôi không hiểu tại sao nó lại bị giảm giá. –

+1

@ Flav vì cảnh báo không 'nâng cao ' – g33kz0r

2

Tôi nghĩ rằng ngoại trừ bạn muốn bắt là một MySQLdb.ProgrammingError, và để có được thông tin về nó, chỉ cần thêm một biến để lưu trữ các dữ liệu lỗi (một tuple) ở sau tức rằng:

try: 
    cursor.execute('DROP DATABASE IF EXISTS database_of_armaments') 
except MySQLdb.ProgrammingError, e: 
    print 'There was a MySQL warning. This is the info we have about it: %s' %(e) 
+0

Bạn không có nghĩa là MySQLdb.OperationalError (thay vì Lập trình)? – elo80ka

+0

Đây là ngoại lệ đã bị ném cho tôi trong một dự án tương tự mà tôi đang làm việc. Và vâng tôi đã nghĩ rằng đó là kỳ quặc. – dangerouslyfacetious

+0

Cảm ơn, điều này rất hữu ích. – chernevik

1

trước tiên bạn nên bật cảnh báo để coi là ngoại lệ và chỉ khi đó bạn mới có thể bắt chúng. xem mô-đun "cảnh báo" chuẩn để biết chi tiết.

0

Plain và đơn giản

def log_warnings(curs): 
    for msg in curs.messages: 
     if msg[0] == MySQLdb.Warning: 
      logging.warn(msg[1]) 

cursor.execute('DROP DATABASE IF EXISTS database_of_armaments') 
log_warnings(cursor) 

msg [1] Ví dụ: - (u'Warning', 1366L, u"Incorrect integer value: '\xa3' for column 'in_userid' at row 1")

1

tôi quản lý để bẫy cảnh báo mysql như thế này:

import _mysql_exceptions 

try: 
    foo.bar() 
except _mysql_exceptions.Warning, e: 
    pass