Teradata / PyTd

A Python Module to make it easy to script powerful interactions with Teradata Database in a DevOps friendly way.
MIT License
108 stars 43 forks source link

Provide cleaner error messages when ODBC drivers are not installed #35

Closed nchammas closed 8 years ago

nchammas commented 8 years ago

I was just getting started with PyTd, working through the Hello World example, when I hit my first problem:

Traceback (most recent call last):
  File "hello-world.py", line 12, in <module>
    password='xxx')
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/udaexec.py", line 172, in connect
    **args))
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 367, in __init__
    checkStatus(rc, hDbc=self.hDbc, method="SQLDriverConnectW")
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 187, in checkStatus
    info = getDiagnosticInfo(hDbc, SQL_HANDLE_DBC)
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 170, in getDiagnosticInfo
    "SQL_ERROR", "SQL_ERROR returned from SQLGetDiagRecW.")
teradata.api.InterfaceError: ('SQL_ERROR', 'SQL_ERROR returned from SQLGetDiagRecW.')
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 136, in cleanupConnections
    conn.close()
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 408, in close
    SQL_STATE_INVALID_TRANSACTION_STATE])
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 187, in checkStatus
    info = getDiagnosticInfo(hDbc, SQL_HANDLE_DBC)
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 170, in getDiagnosticInfo
    "SQL_ERROR", "SQL_ERROR returned from SQLGetDiagRecW.")
teradata.api.InterfaceError: ('SQL_ERROR', 'SQL_ERROR returned from SQLGetDiagRecW.')
Exception ignored in: <bound method OdbcConnection.__del__ of OdbcConnection(sessionno=0)>
Traceback (most recent call last):
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 446, in __del__
  File "./hello-world/.env/lib/python3.5/site-packages/teradata/tdodbc.py", line 404, in close
AttributeError: 'NoneType' object has no attribute 'SQLDisconnect'

This is a pretty intimidating way to say what the problem actually is: "Could not find ODBC driver." Once I installed it, things worked fine.

A clear, direct message about this problem would be helpful for newcomers.

escheie commented 8 years ago

Could you please provide the OS you were using and the version of the Teradata Python Module?

Thanks, -Eric

nchammas commented 8 years ago

OS X 10.11.3, teradata 15.10.0.14, and Python 3.5.1.

escheie commented 8 years ago

I was able to make several improvements on Mac and Linux when drivers are not installed or paths not setup correctly.

On Mac, the iODBC driver Manager wasn't returning the SQL_ERROR until the third time the SQLGetDiagRecW call was made, so I modified code to return the error data from the first to calls instead of reporting the SQL_ERROR from SQLGetDiagRecW.

On Linux, all the DataDirect driver manager returns when the driver is installed but the ODBCINI environment variable is not set is "[632] 523 630". I've added a check for all numbered error messages to check that the driver is installed and the ODBCINI environment variable is set correctly.