Отображать ошибку MySQL в QMessageBox

Я запускаю локальный сервер MySQL для разработки своего приложения PyQt. Было бы неплохо, если бы я мог отображать QMessageBox, если сервер не работает, чтобы конечные пользователи имели представление, почему приложение не запускается.

Если я выключу сервер и запущу свою программу с терминала, я получу обычный ответ:

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' (2)")

мой код простой

import pymysql as lite

con = lite.connect(host='127.0.0.1',unix_socket='/run/mysqld/mysqld.sock', user='ivica',passwd='pass',db='baza',charset='utf8')

#define one class that inherits QMainWindow and so on...

Есть ли способ для меня фактически отобразить QMessageBox с сообщением «Сервер MySQL не работает!» или что-то подобное? Если сервер MySQL не запущен, окно моего приложения даже не будет отображаться, только ошибка терминала.

:РЕДАКТИРОВАТЬ:

После предложенных изменений мой код выглядит так:

con = None #this is how I make it global, eg. not in any method or class (?)

def dbconnect():
    global con
    #con = None
    try:
        if os.name == 'nt':
            con = lite.connect(host='127.0.0.1', user='ivica',passwd='pass',db='baza',charset='utf8')
        else:
            con = lite.connect(host='127.0.0.1',unix_socket='/run/mysqld/mysqld.sock', user='ivica',passwd='pass',db='baza',charset='utf8')
    except lite.err.OperationalError as err:
        msgBox = QtGui.QMessageBox()
        msgBox.setText(str(err))
        msgBox.show()
    return con

class Logon(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        self.ui=Ui_dlgLogovanje()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.dugmeUloguj, QtCore.SIGNAL("clicked()"), self.doLogin)

    def doLogin(self):          
        with dbconnect():
            cur = dbconnect().cursor()

и ошибка, которую я получаю:

Traceback (most recent call last):
  File "main.py", line 59, in doLogin
    with dbconnect():
AttributeError: __exit__

: РЕДАКТИРОВАТЬ 2:

После ответа unutbu и некоторых моих возни с кодом это решение, которое я искал:

con = None

def dbconnect():
    global con
    try:
        if os.name == 'nt': 
            con = lite.connect(host='127.0.0.1', user='ivica',passwd='pass',db='baza',charset='utf8')
        else:
            con = lite.connect(host='127.0.0.1',unix_socket='/run/mysqld/mysqld.sock', user='ivica',passwd='pass',db='baza',charset='utf8')
    except lite.err.OperationalError as err:
        msgBox = QtGui.QMessageBox()
        msgBox.setText(str(err))
        msgBox.show()
    return con

class Logon(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        self.ui=Ui_dlgLogovanje()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.dugmeUloguj, QtCore.SIGNAL("clicked()"), self.doLogin)

    def doLogin(self):      
        if con == None:
            reply = QtGui.QMessageBox.warning(self, 'Greška',
            "Can't establish connection to database!", QtGui.QMessageBox.Ok)
            if reply == QtGui.QMessageBox.Ok:
                self.close() #and when user clicks OK program closes

        else:
        with dbconnect():
            cur = dbconnect().cursor()
                    #do other database stuff, check credentials etc.

person ivica    schedule 14.09.2012    source источник
comment
Вы получаете это AttributeError только тогда, когда lite.connect терпит неудачу, или вы получаете его, даже если соединение установлено успешно?   -  person unutbu    schedule 15.09.2012
comment
Если сервер MySQL не работает, это ошибка, которую я получаю. Если сервер запущен, то все нормально, ошибок нет.   -  person ivica    schedule 15.09.2012
comment
При сбое соединения con равно None, у которого нет метода __exit__. Вот почему with dbconnect() терпит неудачу. Что вы хотите, чтобы произошло, если соединение не работает?   -  person unutbu    schedule 15.09.2012
comment
Показать простое окно сообщения о том, что соединения нет.   -  person ivica    schedule 15.09.2012
comment
Да, но должна ли программа закрыться после того, как пользователь подтвердит получение сообщения, или она должна продолжить работу, кроме как без подключения к MySQL?   -  person unutbu    schedule 15.09.2012
comment
Это должно показать сообщение, и после того, как пользователь нажмет кнопку OK, программа должна выйти, так как она использует сервер MySQL для своих основных операций.   -  person ivica    schedule 15.09.2012
comment
Я приму ваш ответ, но также добавлю к нему свое дополнение в исходном сообщении. Еще раз спасибо.   -  person ivica    schedule 16.09.2012
comment
Я ошибался. Данные не записываются в базу данных методом dbconnect. :/   -  person ivica    schedule 16.09.2012
comment
Избавьтесь от with. Просто вызовите dbconnect() один раз в начале скрипта. Затем вы можете использовать глобальный con в любом месте скрипта. Это упрощает написание сценария, хотя я должен упомянуть, что у него есть как минимум две потенциальные проблемы: (1) ваш сервер может разрешать ограниченное количество соединений, поэтому перехват соединения на протяжении всей программы может быть плохим. (2) Если соединение не используется в течение длительного времени, оно может истечь, и в этом случае ваша программа может неожиданно выйти из строя, если вы не добавите дополнительный код для обработки этого...   -  person unutbu    schedule 16.09.2012


Ответы (1)


Используйте блок try...except для обработки исключения OperationalError:

import sys
from PyQt4 import QtGui
import pymysql as lite


def dbconnect():
    global con
    config = {
        'host' : '127.0.0.1',
        'user' = 'ivica',
        'passwd' = 'pass',
        'db' = 'baza',
        'charset' = 'utf8'
        }
    try:
        if os.name == 'nt':
            con = lite.connect(**config)
        else:
            con = lite.connect(unix_socket = '/run/mysqld/mysqld.sock', **config))
    except lite.err.OperationalError as err:
        msgBox = QtGui.QMessageBox()
        msgBox.setText(str(err))
        msgBox.exec_()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    con = None
    dbconnect()
    if con is not None:
        sys.exit(app.exec_())

Похоже, что соединение MySQL является основной частью вашей программы, поэтому вы можете также установить соединение в самом начале или выйти, если процесс соединения не удался.

Кроме того, используя

with dbconnect():
    ...

не совместим с определением глобального con, так как соединение закрывается, когда Python выходит из блока with.

person unutbu    schedule 14.09.2012
comment
Я вижу, хороший подход. Меня беспокоит еще одна вещь; где-то в моем коде я использую with con: cur = con.cursor() и с вашим кодом получаю ошибку NameError: global name 'con' is not defined . Любой совет? Спасибо, я приму ваш ответ, как только получу эту ошибку своего терминала. - person ivica; 14.09.2012
comment
В моем определении con является локальной переменной в main, а не глобальной переменной. Вам нужно либо определить ее как глобальную переменную, либо передать con в качестве параметра функции, которая ее использует, либо использовать with dbconnect() as con: там, где вам это нужно. - person unutbu; 14.09.2012