Is it possible to evaluate multiple conditions in a try block in Python. Below is the case. I have 2 conditions below.
- 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.
- 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)