user3066737 user3066737 - 3 months ago 12
Python Question

py2exe and cx_Oracle failed loading cx_Oracle.pyd

Given the following python program

testconnect.py

from sqlalchemy.dialects import oracle
from sqlalchemy import create_engine

url = 'oracle+cx_oracle://user:password@oracle-rds-01.....amazonaws.com:1521/orcl'

e = create_engine(url)

e.connect()
print('Connected')


setup.py

setup(
options={
'py2exe': {
'bundle_files': 1,
'compressed': True,
'dll_excludes': ['OCI.dll'],
'includes':['cx_Oracle']
}
},
console=["testconnect.py"],
zipfile=None
)


I get the following traceback

Traceback (most recent call last):
File "testconnect.py", line 7, in <module>
e = create_engine(url)
File "c:\Python34\lib\site-packages\sqlalchemy\engine\__init__.py", line 386, in create_engine
return strategy.create(*args, **kwargs)
File "c:\Python34\lib\site-packages\sqlalchemy\engine\strategies.py", line 75, in create
dbapi = dialect_cls.dbapi(**dbapi_args)
File "c:\Python34\lib\site-packages\sqlalchemy\dialects\oracle\cx_oracle.py", line 769, in dbapi
import cx_Oracle
File "c:\Python34\lib\site-packages\zipextimporter.py", line 109, in load_module
self.get_data)
ImportError: MemoryLoadLibrary failed loading cx_Oracle.pyd: The specified module could not be found. (126)


I have tried using 'includes' in the setup.py, importing cx_Oracle but to no avail.

I've tries bundle_files=3 and using 'data_files=' to copy the cx_Oracle.pyd file into the dist directory and I still get the same issue

What changes to my setup.py do I need to do to be able capture the cx_Oracle.pyd file so that it will load

Update:

The problem was I was using a cmd console that was open prior to installing cx_Oracle and instant client to build the exe with py2exe

I closed the console down re-opened it and windows was able to find the appropriate files

This now runs OK on my Windows 10 laptop (64 bit)

But when I try to deploy this EXE to my clients machine(64 bit windows 2008) I get the following still

D:\Milliman>testconnect.exe
Traceback (most recent call last):
File "testconnect.py", line 1, in <module>
File "c:\Python34\lib\site-packages\zipextimporter.py", line 109, in load_module
ImportError: MemoryLoadLibrary failed loading cx_Oracle.pyd: The specified module could not be found. (126)


Thanks for any help in advance
Andy

Answer

I finally figured out what was going on

The machine we were deploying to was windows 2008 Server 64 Bit But It had Oracle 32 bit client on it

I was trying to deploy py2exe python 3.4 app 64 bit with Cx_Oracle 64bit this was finding the 32 bit OCI.dll and failing to load

My solution was to package the 64 bit Instant Client in the data_files. Then in my app modify the path within the app

import os
if os.path.exists('./instant_client'):
  pth = os.environ.get('path')
  pth = '{0};{1}'.format('./instant_client' ,pth)
  os.environ['path'] = pth

This way I could guarantee that the cx_Oracle would find the correct OCI.dll without interfering with global paths and the already installed oracle on that machine

Comments