Search code examples
pythonpandastry-except

Evaluating multiple conditions in try block in Python


Is it possible to evaluate multiple conditions in a try block in Python. Below is the case. I have 2 conditions below.

  1. Connect to sql server to read data into two dataframes. There is a timeout in the code, if the connection takes more than 15 seconds the code should raise an exception and exit.
  2. Check if these two dataframe have data.If either one of the dataframes is empty, exit the code, if not continue the code in the else block.

I am currently thinking of doing like this. Is there more elegant way.

try:
    #Condition 1
except:
    #Condition 1
try:
    #Condition 2
except:
     #Condition 2

else:
    #Condition 3



def connect_to_server(table):
    # Connection Code
    server = '' 
    username = '' 
    password = '' 
    database = ''
    cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';ENCRYPT=yes;UID='+username+';PWD='+ password)
    cnxn.timeout = 5   
    cursor = cnxn.cursor()
    try:
        cnxn.execute('SELECT * FROM ' +table)        
    except Exception as my_timeout_exception:
        raise my_timeout_exception
        
        
def read_database(table):
    server = '' 
    username = '' 
    password = '' 
    database = ''
    cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';ENCRYPT=yes;UID='+username+';PWD='+ password)
    cursor = cnxn.cursor()
    df = pd.read_sql('SELECT * FROM '  +table, cnxn)
    if df.empty:
        print("dataframe is empty")
    else:
        return df
        
        
try:
    using_con = connect_to_server('table')
    df = read_database('table')
except my_timeout_exception:
    handle_error_1
    #break
except empty_df_exception: 
    handle_error_2
    #break
else:
    print("z")

Solution

  • Fortunately pyodbc offers its own error classes so no need to create a custom one however we do create a custom error for an empty dataframe:

    import pyodbc
    import pandas as pd
    
    
    class MyEmptyDfError(Exception):
        def __init__(self):
            message = "Dataframe is empty"
            super().__init__(message)
    
    
    def connect_to_server():
        # Connection Code
        server = ''
        username = ''
        password = ''
        database = ''
        cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';ENCRYPT=yes;UID='+username+';PWD='+ password)
        return cnxn
    
    
    def read_database(table, cnxn):
        cnxn.timeout = 5
        df = pd.read_sql('SELECT * FROM ' + table, cnxn)
        if df.empty:
            raise MyEmptyDfError
        return df
    
    
    try:
        conn = connect_to_server()
        df = read_database("test_table", conn)
    except pyodbc.OperationalError as e:
        print(e)
    except MyEmptyDfError as e:
        print(e)
    finally:
        print("Final code reached")
    

    Here if server connection triggers an error it propagates up to your code and is captured as OperatioalError (which I think is the error triggered if it times out) I think this should work (haven't been able to test it yet)