Home > database >  Evaluating multiple conditions in try block in Python
Evaluating multiple conditions in try block in Python

Time:01-11

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")

CodePudding user response:

rIf you just want to capture different error conditions then you can include your code to connect to server and then test for data in the try statement. you then specify the error you want to catch in the except statement:

def connect_to_server(db):
    # Connection Code
    if connection_timed_out:
        raise my_timeout_exception #either a custom error you have created or propagate standard error from connection timeout
    return connection

def read_database(conn):
    #read db into dataframe code
    if dataframe_isempty:
        raise empty_df_exception #either a custom error you have created or propagate standard error from dataframe reading
    return dataframe

try:
    using_con = connect_to_server(db)
    df = read_database(using_con)
except my_timeout_exception:
    handle_error_1
    break
except empty_df_exception: 
    handle_error_2
    break
else:
    continue_code

You can actually include both exceptions in one except statement if the handling code is the same (eg just a break statement).

CodePudding user response:

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)

  • Related