When I try to read a table from an SQL database with pandas using pandas.read_sql
, the package pyodbc throws an DataError
(pyodbc.DataError) that I would like to catch. The DataError
is caused by an unexpected nvarchar value, causing an conversion failure when pyodbc attempts to convert it to data type int.
This is my code:
import pandas as pd
import pyodbc
from sqlalchemy import create_engine
from sqlalchemy.engine import URL
driver = "SQL Server"
server = "my_server"
database = "my_db"
connection_string = (f"Driver={driver};"
f"Server={server};"
f"Database={database};"
f"Trusted_Connection=yes;"
f"TrustServerCertificate=yes")
connection_url = URL.create("mssql+pyodbc",
query={"odbc_connect": connection_string})
engine = create_engine(connection_url)
# select only the first 10 rows in a table
query = (f"SELECT top 10 * "
f"FROM abc.table_name")
df = pd.read_sql(sql=query,
con=engine)
The output is
DataError: (pyodbc.DataError) ('22018', "[22018] [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value '00:35' to data type int. (245) (SQLExecDirectW)")
[SQL: SELECT top 10 * FROM abc.table_name]
(Background on this error at: https://sqlalche.me/e/14/9h9h)
I know how to catch and handle built-in exceptions using try
and except
statements in Python. The DataError
(pyodbc.DataError) however is not a built-in exception. I would like to catch this package-specific error while not just catching any error (I understand this to be bad practice).
I have attempted the following:
try:
df = pd.read_sql(sql=query,
con=engine)
except DataError as err:
print(err)
pass
This results in an NameError: name 'DataError' is not defined
(as far as I understand, because DataError
is not a built-in exception).
I have also attempted the following:
try:
df = pd.read_sql(sql=query,
con=engine)
except pyodbc.DataError as err:
print(err)
pass
This results in DataError: (pyodbc.DataError)
, because the error is not caught.
DataError
seems to be an exception from SQLalchemy, see documentation: https://docs.sqlalchemy.org/en/20/core/exceptions.html#sqlalchemy.exc.DataError
Try:
from sqlalchemy.exc import DataError
then
try:
df = pd.read_sql(sql=query,
con=engine)
except DataError as err:
print(err)
pass