RSS Feed

RSS
Comments RSS

Pyinstaller and cx_Oracle success!

I have had success with producing a single file executable from a Python script that includes cx_Oracle.  Here are the details.  Another post in the PyInstaller Google Groups forum from the past put me onto the right track.  Hopefully this will also help someone struggling to get this working.
OS was Windows 7 Pro 64 bit.
Python was 2.7.8 32 bit.
cx_Oracle-5.13 for 2.7
PyInstaller-2.1
Python script oracle_connect.py, this was my program.
Oracle 11g instant client DLL files, OCI.dll and oraociei11.dll (OCI.dll seems to stay constant from version to version of Oracle, but the other DLL file’s name will change with Oracle versions.)
A properly designed tnsnames.ora file.  This contains the necessary connection information for your Oracle database.
A Pyinstaller-2.1 .spec file to make sure Pyinstaller did everything that was needed to produce the single file .exe.  Pyinstaller-2.1 will not automatically include both DLLs into the .exe without using a .spec file.  It does pick up the OCI.dll file automatically, but not oraociei11.dll.
First, I began by writing my Python script, which imports cx_Oracle, makes the connection to the database, and does some work.  My working directory was C:\Python27, so the script, two DLL files and .ora file were all placed there.  Test the code to make sure that via the interpreter the script interacted with the database correctly.
Second, I ran Pyinstaller-2.1 against the oracle_connect.py script without the -F option (for single file .exe).  This created an oracle_connect.spec file which I used as a template which was edited to include the needed settings.
Third, I edited the oracle_connect.spec file (see below) to specify a single file executable and to include the oraociei11.dll in the compilation  The paths were specific to my installation environment and where I had placed by Python source file and other files, adjust to match your environment.  This oracle_connect.spec file I then placed in my c:\Python27\PyInstaller-2.1 direcory.  Then I executed the following to produce the single file executable.
C:\Python27\PyInstaller-2.1>..\python.exe .\pyinstaller.py .\oracle_connect.spec
The resulting oracle_connect.exe may now be distributed without including loose DLLs.  The only additional file needed is the tnsnames.ora file.  This cannot be compiled into the program and must reside in the same location as the executable program.  It is a configuration file for the communications parameters necessary to make the connection to the Oracle database.  I include a sample of a tnsnames.ora file below.
oracle_connect.spec file contents:
# -*- mode: python -*-
a = Analysis([‘..\\oracle_connect.py’],
pathex=[‘C:\\Python27\\PyInstaller-2.1\\oracle_connect’],
hiddenimports=[],
hookspath=None,
runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
a.binaries  + [(‘oraociei11.dll’,’c:\python27\oraociei11.dll’,’BINARY’)],
a.zipfiles,
a.datas,
name=’oracle_connect.exe’,
debug=False,
strip=None,
upx=False,
console=True )
Sample tnsnames.ora, values in <> are Oracle installation specific, contact your local Oracle admin for the correct values to use.
# tnsnames.ora Network Configuration File
<Oracle instance name> =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = <FQDN or IP>)(PORT = <1521>))
)
(CONNECT_DATA =
(SERVICE_NAME = <Oracle service name>)
)
)








*