简体   繁体   中英

Pyodbc if connection fails retry

Hi there I have the following python code to connect to my SQL-Server DB

class CDBTools:
    details = {
        'server' : 'localhost',
        'database' : 'MyDB',
        'username' : 'me',
        'password' : 'myPass'
    }

    conn = None
    def __init__(self, server, database, username, password): 
        
        self.details["server"] = server
        self.details["database"] = database
        self.details["username"] = username
        self.details["password"] = password
           

    def connect_to_db(self):
        connect_string = 'DRIVER={{FreeTDS}};SERVER={server}; DATABASE={database};UID={username};PWD={password}'.format(**self.details)
        try:
            self.conn = pyodbc.connect(connect_string, autocommit=True)
            #print(connect_string)
            #Logger.Log(self.conn, "info")
        except pyodbc.Error as e:
            print(e, "error")
            
    def execute_select_query(self, query):
        try:
            curr = self.conn.cursor()
            out = curr.execute(query).fetchall()
        except pyodbc.IntegrityError as e:
            out = []
            print('ms-sql error: {0}'.format(e)) 
        except pyodbc.OperationalError as err: #Something happend with db, so try again
            out = []
            print('ms-sql Operation Error: {0}'.format(err))

        except AttributeError as err:
            out = []
            print('Connection to DB failed')
            pass
        try:
            curr.close()
        except:
            print('Connection to DB failed')
        return out

    def execute_inset_query(self, query):
        try:
            database_cursor = self.conn.cursor()
            database_cursor.execute(query)
        except pyodbc.DataError as e:
            print('ms-sql error: {0}'.format(e))
        except pyodbc.IntegrityError as e:
            print('ms-sql error: {0}'.format(e))
        except pyodbc.OperationalError as err: #Something happend with db, so try again
            print('ms-sql error: {0}'.format(e))

then in my main program I am trying this and it works just fine, until I disconnect the network

DBT = CDBTools("192.168.1.2\instance4", "my_db", "my_username", "my_passowrd")
DBT.connect_to_db()
while(True):
    print("[{0}]: {1}".format(time.strftime("%H:%M:%S"), DBT.execute_select_query("SELECT Name FROM Persons WHERE ID='1'")))

When I disconnect the network I get no error, just time doesn't count anymore (of course because query is failing) but when I reconnect the network query never sucseeds anymore

so does anyone maybe know how I can modify execute_select_query and execute_inset_query so when connection to the db is restored it will start to work again :)

Thanks for Anwsering and Best Regards

Try this, it'll connect each time you use the with clause, and automatically disconnect when you leave it.

class CDBTools:
    details = {
        'server' : 'localhost',
        'database' : 'MyDB',
        'username' : 'me',
        'password' : 'myPass'
    }

    conn = None
    def __init__(self, server, database, username, password): 
        
        self.details["server"] = server
        self.details["database"] = database
        self.details["username"] = username
        self.details["password"] = password
           

    def connect_to_db(self):
        connect_string = 'DRIVER={{FreeTDS}};SERVER={server}; DATABASE={database};UID={username};PWD={password}'.format(**self.details)
        try:
            conn = pyodbc.connect(connect_string, autocommit=True)
            #print(connect_string)
            #Logger.Log(self.conn, "info")
        except pyodbc.Error as e:
            print(e, "error")

        return conn
            
    def execute_select_query(self, conn, query):
        try:
            curr = conn.cursor()
            out = curr.execute(query).fetchall()
        except pyodbc.IntegrityError as e:
            out = []
            print('ms-sql error: {0}'.format(e)) 
        except pyodbc.OperationalError as err: #Something happend with db, so try again
            out = []
            print('ms-sql Operation Error: {0}'.format(err))

        except AttributeError as err:
            out = []
            print('Connection to DB failed')
            pass

    def execute_inset_query(self, conn, query):
        try:
            database_cursor = conn.cursor()
            database_cursor.execute(query)
        except pyodbc.DataError as e:
            print('ms-sql error: {0}'.format(e))
        except pyodbc.IntegrityError as e:
            print('ms-sql error: {0}'.format(e))
        except pyodbc.OperationalError as err: #Something happend with db, so try again
            print('ms-sql error: {0}'.format(e))

then:

DBT = CDBTools("192.168.1.2\instance4", "my_db", "my_username", "my_passowrd")

while True:
    with DBT.connect_to_db() as conn:
        print("[{0}]: {1}".format(time.strftime("%H:%M:%S"), DBT.execute_select_query(conn, "SELECT Name FROM Persons WHERE ID='1'")))

I'd probably make a method to return the cursor rather than the connection. For example:

class CDBTools:
    details = {
        'server' : 'localhost',
        'database' : 'MyDB',
        'username' : 'me',
        'password' : 'myPass'
    }

    conn = None
    def __init__(self, server, database, username, password): 

        self.details["server"] = server
        self.details["database"] = database
        self.details["username"] = username
        self.details["password"] = password


    def get_cursor(self):
        connect_string = 'DRIVER={{FreeTDS}};SERVER={server}; DATABASE={database};UID={username};PWD={password}'.format(**self.details)
        try:
            conn = pyodbc.connect(connect_string, autocommit=True)
            #print(connect_string)
            #Logger.Log(self.conn, "info")
        except pyodbc.Error as e:
            print(e, "error")

        return conn.cursor()

DBT = CDBTools("192.168.1.2\instance4", "my_db", "my_username", "my_passowrd")

with DBT.get_cursor() as cursor:
    cursor.execute("SELECT Name FROM Persons WHERE ID='1'")
    for row in cursor.fetchall():
        print(row)

Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM