Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ODBC Library(libodbc.so) loading issue in AIX 7.1 #95

Open
FrankWangAU opened this issue Jan 15, 2018 · 5 comments
Open

ODBC Library(libodbc.so) loading issue in AIX 7.1 #95

FrankWangAU opened this issue Jan 15, 2018 · 5 comments

Comments

@FrankWangAU
Copy link

FrankWangAU commented Jan 15, 2018

Env: OS AIX 7.1.0.0
tdodbc version: 14.10.0.7
xxxxxxxxxx:/opt/teradata/client/ODBC_64/lib: lslpp -l | grep odbc
tdodbc1410.tdodbc1410 14.10.0.7 COMMITTED Teradata ODBC Driver for AIX

Tried to use PyTD to connect Teradata in AIX 7.1 but got following error:
Traceback (most recent call last):
File "/opt/freeware/lib64/python3.5/runpy.py", line 184, in _run_module_as_main
"main", mod_spec)
File "/opt/freeware/lib64/python3.5/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/xxxxxx/python/proj/cba/aipl/proj_teradata.py", line 71, in
with ConnTest() as myConnTest:
File "/home/xxxxxx/python/proj/cba/aipl/teradata/proj/init.py", line 1747, in init
self.session = get_db_conn(config_files, query_band)
File "/home/xxxxxx/python/proj/cba/aipl/teradata/utils/tdconn.py", line 166, in get_db_conn
session = uda_exec.connect(queryBands=query_band, dataTypeConverter=TeradataDataTypeConverter(), **conn_param)
File "/home/xxxxxx/python/proj/lib64/python3.5/site-packages/teradata/udaexec.py", line 183, in connect
**args))
File "/home/xxxxxx/python/proj/lib64/python3.5/site-packages/teradata/tdodbc.py", line 399, in init
init(odbcLibPath)
File "/home/xxxxxx/python/proj/lib64/python3.5/site-packages/teradata/tdodbc.py", line 344, in init
initOdbcLibrary(odbcLibPath)
File "/home/xxxxxx/python/proj/lib64/python3.5/site-packages/teradata/tdodbc.py", line 297, in initOdbcLibrary
odbc = ctypes.cdll.LoadLibrary(odbcLibPath)
File "/opt/freeware/lib64/python3.5/ctypes/init.py", line 435, in LoadLibrary
return self._dlltype(name)
File "/opt/freeware/lib64/python3.5/ctypes/init.py", line 357, in init
self._handle = _dlopen(self._name, mode)
OSError: 0509-022 Cannot load module .
0509-026 System error: A file or directory in the path name does not exist.
Did a little bit further investigation, then found there was an issue to load libodbc.so

Python 3.5.2 (default, Dec  1 2016, 02:07:23)
[GCC 4.8.5] on aix6
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import cdll
>>> print(cdll.LoadLibrary("libodbc.so"))
Loading Library: libodbc.so
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/freeware/lib64/python3.5/ctypes/__init__.py", line 437, in LoadLibrary
    return self._dlltype(name)
  File "/opt/freeware/lib64/python3.5/ctypes/__init__.py", line 357, in __init__
    self._handle = _dlopen(self._name, mode)
OSError:        0509-022 Cannot load module .
        0509-026 System error: A file or directory in the path name does not exist.
>>>

It turned out there is no file named libodbc.so, but there is one file named "odbc.so" exist in /opt/teradata/client/ODBC_64/lib

xxxxxxxxxx:/opt/teradata/client/ODBC_64/lib: ls -lrt
total 71192
-r--r--r--    1 bin      bin           67068 21 Mar 2015  vscnctdlg.so
-r--r--r--    1 bin      bin          229441 21 Mar 2015  tdconndlg.so
-r--r--r--    1 bin      bin         6020823 21 Mar 2015  tdata.so
-r--r--r--    1 bin      bin         2171709 21 Mar 2015  odbc.so
-r--r--r--    1 bin      bin         1830772 21 Mar 2015  odbcinst.so
-r--r--r--    1 bin      bin         2032897 21 Mar 2015  odbccurs.so
-r--r--r--    1 grandhsa 30000       1769226 21 Mar 2015  libtdsso.so
-r--r--r--    1 bin      bin          610880 21 Mar 2015  libtdparse.so
-r--r--r--    1 bin      bin          610880 21 Mar 2015  libtdparse.a
-r--r--r--    1 bin      bin         1831194 21 Mar 2015  libodbcinst.a
-r--r--r--    1 bin      bin         2172128 21 Mar 2015  libodbc.a
-r--r--r--    1 bin      bin        15005158 21 Mar 2015  libddicu26.a
-r--r--r--    1 bin      bin         2064704 21 Mar 2015  ddtrc26.so
lrwxrwxrwx    1 root     system           31 01 Aug 21:03 libicudatatd.so -> /usr/lib/lib_64/libicudatatd.so
lrwxrwxrwx    1 root     system           33 01 Aug 21:03 libicudatatd46.so -> /usr/lib/lib_64/libicudatatd46.so
lrwxrwxrwx    1 root     system           31 01 Aug 21:03 libicuiotd46.so -> /usr/lib/lib_64/libicuiotd46.so
lrwxrwxrwx    1 root     system           31 01 Aug 21:03 libicui18ntd.so -> /usr/lib/lib_64/libicui18ntd.so
lrwxrwxrwx    1 root     system           33 01 Aug 21:03 libicui18ntd46.so -> /usr/lib/lib_64/libicui18ntd46.so
lrwxrwxrwx    1 root     system           31 01 Aug 21:03 libiculetd46.so -> /usr/lib/lib_64/libiculetd46.so
lrwxrwxrwx    1 root     system           29 01 Aug 21:03 libicuiotd.so -> /usr/lib/lib_64/libicuiotd.so
lrwxrwxrwx    1 root     system           29 01 Aug 21:03 libiculetd.so -> /usr/lib/lib_64/libiculetd.so
lrwxrwxrwx    1 root     system           31 01 Aug 21:03 libicuuctd46.so -> /usr/lib/lib_64/libicuuctd46.so
lrwxrwxrwx    1 root     system           29 01 Aug 21:03 libiculxtd.so -> /usr/lib/lib_64/libiculxtd.so
lrwxrwxrwx    1 root     system           31 01 Aug 21:03 libiculxtd46.so -> /usr/lib/lib_64/libiculxtd46.so
lrwxrwxrwx    1 root     system           29 01 Aug 21:03 libicuuctd.so -> /usr/lib/lib_64/libicuuctd.so
lrwxrwxrwx    1 root     system           49 01 Aug 21:03 odbctrac.so -> /opt/teradata/client/14.10/odbc_64/lib/ddtrc26.so
lrwxrwxrwx    1 root     system           29 01 Aug 21:03 tdwalletdir -> /opt/teradata/client/tdwallet

So, I manually changed the code of function: initOdbcLibrary in tdodbc.py and added hack for AIX, now it is working fine.

def initOdbcLibrary(odbcLibPath=None):
    """Initialize the ODBC Library."""
    global odbc
    if odbc is None:
        if osType == "Windows":
            odbc = ctypes.windll.odbc32
        else:
            if not odbcLibPath:
                # If MAC OSx
                if osType == "Darwin":
                    odbcLibPath = "libiodbc.dylib"
                elif osType.startswith("CYGWIN"):
                    odbcLibPath = "odbc32.dll"
                # 2018-01-12 Bug fix for AIX teradata TTU 14.10
                if osType == "AIX":
                    odbcLibPath = "odbc.so"
                else:
                    odbcLibPath = 'libodbc.so'
            logger.info("Loading ODBC Library: %s", odbcLibPath)
            odbc = ctypes.cdll.LoadLibrary(odbcLibPath)

workaround codes:

                # 2018-01-12 Bug fix for AIX teradata TTU 14.10
                if osType == "AIX":
                    odbcLibPath = "odbc.so"

Should this workaround to be added in?
Do we have testing in AIX flatform?

Thanks,
Frank

@escheie
Copy link
Contributor

escheie commented Jan 18, 2018

Hi Frank,

I have not tested PyTd on AIX. You can set odbcLibPath without a code change by passing it as an argument to UdaExec or by specifying it in an external config file. I think we would only add the default value for AIX if it was officially tested on that platform. I will keep this issue open to track interest in officially certifying on AIX.

Thanks,
-Eric

@FrankWangAU
Copy link
Author

Hi Eric,

Did not know that we can specify "odbcLibPath" in external config file.
I think I will go with this solution for now.

Thanks for your help.

Regards,
Frank

@djb18
Copy link

djb18 commented Feb 5, 2018

Hi Frank and Eric,

Glad to find this discussion, as I've also struggled to connect to Python to Teradata from AIX 7.1. Defining the odbcLibPath was critical, but I found it only works when placed in the udaexec.ini and NOT when passed as a UdaExec parameter.

I also found (in another post) that I had to define Authentication=LDAP. Strangely, this only works as a UdaExec parameter but NOT in the udaexec.ini (converse to the odbcLibPath)! Beyond the finicky location, this confuses me for other reasons... first, because the Teradata Python Module documentation doesn't include Authentication among UdaExec's valid parms, but also because I had already declared "Authentication=LDAP" in the odbc.ini config, within my DSN section. Why doesn't it work there?

Here is my sample Python program (which works):
import teradata udaExec = teradata.UdaExec(appName="Test1", version="1.0") with udaExec.connect(method="odbc", authentication="LDAP", system="tdt", username="xxx", password="$$tdwallet(xxx)") as myses: ...

My udaexec.ini file:
`[CONFIG]
logConsole=True

[DEFAULT]
odbcLibPath=/opt/teradata/client/ODBC_64/lib/odbc.so
`

And finally, my /opt/teradata/client/ODBC_64/odbc.ini file:
`[ODBC]
InstallDir=/opt/teradata/client/ODBC_64
Trace=0
TraceDll=/opt/teradata/client/ODBC_64/lib/odbctrac.so
TraceFile=/usr/joe/odbcusr/trace.log
TraceAutoStop=0

[ODBC Data Sources]
tdt=tdata.so

[tdt]
Driver=/opt/teradata/client/ODBC_64/lib/tdata.so
Description=Teradata Test database
DBCName=tdt
Authentication=LDAP
Charset=UTF16`

Optimally, I want to place as much config as possible in external files to keep our programs cleaner, so I'd like to move the "method" and "authentication" to external configs, but attempting to do so breaks the db connection. Any insight you can offer is appreciated.

Thanks,
Dan

@FrankWangAU
Copy link
Author

Hi @djb18

I never use ODBC DSN as 'system', I always put all parameters into a external config file.
you need ensure ODBC driver info in file: /opt/teradata/client/ODBC_64/odbcinst.ini is correct.

Frank

@Soberoo
Copy link

Soberoo commented Oct 11, 2018

Hi Guys,

I am stuck on the same issue here - I tried to pass an alternative value of odbcLibPath, but in both cases (in config, and passing as a param), I get the same error:

using:
odbcLibPath=/opt/teradata/client/ODBC_64/lib/odbc.

File "/opt/freeware/lib64/python3.5/teradata/udaexec.py", line 183, in connect **args))
TypeError: type object got multiple values for keyword argument 'odbcLibPath'

Any assistance gratefully received.
Soberoo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants