I recently decided to write a few tools to automate some boring database management tasks. Since I am not attached to any particular technology, I decided to do take the opportunity to get to know the Django web framework. Getting a simple server up and running is as easy as doing the same with the Rails framework. In order to do something useful, one needs to integrate a database system, which in my case is Oracle 10g.
In Django’s settings.py, one can setup the database engine, which, luckily includes oracle. Unless you already have a working Python-Oracle setup, you will have to install the cx_Oracle Python database adapter first. Prebuilt binaries for Windows and Linux can be downloaded from the Sourceforge archive directly, since I mainly work on a MacBook Pro, I had to build the module by myself.
There are a few little changes I had to make in order to build and install it successfully, which I will describe here. I used the advice on Pedro’s Blog as a starting point and adapted it so that it worked for me.
I. Downloading the required software:
System Requirements:
- Mac OS X Leopard Intel (comes with Python 2.5)
- Xcode (to get the gcc that it contains) from the Apple Developer Connection
To build the module, you need at least the Oracle Instant Client software for MacOS X, which can be downloaded here. The minimum packages that need to be downloaded are the “Basic” and the “SDK” packages.
From the cx_Oracle Sourceforge site, download cx_Oracle-4.3.3.tar.gz (that's the version I used)
II. Unpacking files
I assume that I uncompress my files in /Users/foo/oracle. That’s just my personal setup of course, because I tend to install stuff that I just want to try out under my home folder. Many people would probably put their ORACLE_HOME under /usr/local/oracle.
cd ~/oracle unzip instantclient-basic-macosx-10.2.0.4.0.zip unzip instantclient-sdk-macosx-10.2.0.4.0.zip tar xvfz cx_Oracle-4.3.3.tar.gz
III. Setup of the environment
To my ~/.profile, I added the following lines:
# Setting Oracle development environment export ORACLE_HOME=/Users/foo/oracle/instantclient_10_2 export DYLD_LIBRARY_PATH=$ORACLE_HOME
and in the /Users/foo/oracle/instantclient_10_2 directory, I entered
ln -s libclntsh.dylib.10.1 libclntsh.dylib
(otherwise the build script does not find the dynamic library).
IV. Edit setup.py
In my case, I could not run the build script out of the box, because it was complaining that the Oracle version could not be determined. That’s because setup.py is looking for a $ORACLE_HOME/lib directory (or $ORACLE_HOME/bin on a Windows system) and trying to determine the Oracle version by looking for the client libraries it contains. In my case, I don’t have a lib directory, so I patched the setup.py and set the Oracle version by hand.
In your favorite text editor, open /Users/foo/oracle/cx_Oracle-4.3.3/setup.py and replace:
if self.oracleVersion is None:
raise DistutilsSetupError, "Oracle home does not refer to an " \
"8i, 9i, 10g or 11g installation"
with
if self.oracleVersion is None:
self.oracleVersion = "10g"
or whatever your Oracle version is.
V. Build and install
This is just as the README.txt describes:
sudo python setup.py build sudo python setup.py install
(I got a warning "ld: warning in /Users/foo/Development/oracle/instantclient_10_2/libclntsh.dylib, file is not of required architecture", but I simply ignored it)
I also created a $ORACLE_HOME/network/admin directory and copied the service file our DBA defined (tnsnames.ora) into it in order to make the services known to the Oracle client installation on my Mac. I did a few test queries to verify that it worked as expected.
I have written down my personal setup process for cx_Oracle, because it was somewhat different from Pablo’s approach and I have different OS and software versions. Hopefully, this can be of some help for someone else (or myself, should I ever have to do it again in the future).
I followed your steps and got past the setup.py complaining that it couldn’t find the right version of Oracle. However I got slews of error messages basically resulting from the fact that the root account did not have the right path variables set. As a workaround, I did the following for step V:
1. “Become Root”:
sudo su -
2. Inherit the environment from “me”:
. /Users/rmichaud/.bash_profile
3. Change directory to the location of cx_oracle and build it:
cd (where your cx_oracle is)
python setup.py build
4. Install
python setup.py install.
This seemed to work well so far, but there doesn’t seem to be a test harness (sorry — sorry about the throwback to my Perl days….)
Comment by Rick Michaud — May 8, 2008 @ 1:55 pm |
Ooops and forgot to mention – thanks for the suggestion to tweak the setup.py, that saved me hours of hair pulling!!
Comment by Rick Michaud — May 8, 2008 @ 1:56 pm |
I followed your instructions on MacOS X Server Leopard 10.5.3 with Oracle instantclient-basic-macosx-10.2.0.4.0 and new cx_Oracle-4.4. I compile cx_Oracle-44 with a python 2.4 version installed by macports and all works well.
Many thanks.
Comment by chrisb06 — July 6, 2008 @ 11:40 am |
worked! thx!
Comment by Mario — July 14, 2008 @ 3:24 pm |
I followed the instructions by have trouble with DYLD library. It seems like the path to the library is hardwired to point to some location on /scratch. If I do symbolic link at that location, I get “Reason: no suitable image found”
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/cx_Oracle.so, 2): Library not loaded: /scratch/plebld/208/rdbms/lib/libclntsh.dylib.10.1
Referenced from: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/cx_Oracle.so
Reason: image not found
—
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/cx_Oracle.so, 2): Library not loaded: /scratch/plebld/208/rdbms/lib/libclntsh.dylib.10.1
Referenced from: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/cx_Oracle.so
Reason: no suitable image found. Did find:
/scratch/plebld/208/rdbms/lib/libclntsh.dylib.10.1: stat() failed with errno=62
Comment by Yaroslav Bulatov — July 23, 2008 @ 7:11 pm |
Follow-up note, previous errors were because I didn’t source my .profile file, when I did, it found dyld, but got a different error (note, the error comes up when I start python and do “import cx_Oracle”)
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/cx_Oracle.so, 2): Symbol not found: ___divdi3
Referenced from: /Applications/instantclient_10_2/libclntsh.dylib.10.1
Expected in: flat namespace
Comment by Yaroslav Bulatov — July 23, 2008 @ 7:34 pm |
Final comment, the MacOS error was because of an incorrect flag in the linker command. The way to fix it is to do python setup.py build, then execute the fixed linker command manually, ie
gcc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -bundle -undefined dynamic_lookup build/temp.macosx-10.3-i386-2.5-10g/cx_Oracle.o -L/Applications/instantclient_10_2/lib -L/Applications/instantclient_10_2 -lclntsh -o build/lib.macosx-10.3-i386-2.5-10g/cx_Oracle.so
then do python setup.py install
Comment by Yaroslav Bulatov — July 25, 2008 @ 12:16 am |
i am getting the same error what Yaroslav was getting but i am getting this while connecting to oracle from lisp using a package called clsql. How do i fix it in this case??
Comment by Rima — October 26, 2008 @ 1:42 pm |
THANK YOU for this post it has saved me TONS of time with this darn library. I had similar issues in Linux and had to do the same things to get this working. Apparently whomever is in charge of of cx_Oracle needs a bit more cross training and/or testing.
Comment by anonymous — November 29, 2008 @ 7:13 am |
Hi,
I have created an updated HowTo for version 5.0 of the cx_Oracle module.
http://wiki.unixcraft.com/display/MainPage/Install+Oracle+(cx_Oracle)+module+for+Python
Regards
Kashif
Comment by Kashif Ali — February 5, 2009 @ 7:57 pm |
I’m trying to get cx_Oracle-5.0.1 built against the instant client 10.2.0.4 (instantclient-basic-10.2.0.4.0-macosx-x86.zip and instantclient-sdk-10.2.0.4.0-macosx-x86.zip) on OS X 10.5.8 with Python 2.5.1, and I’m running across the same problem as Yaroslav Bulatov.
Luckily, his suggestion works for me. After running “python setup.py build” look for the call to gcc, remove the “-arch ppc” option, and run that command again. For me this was:
gcc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -g -bundle -undefined dynamic_lookup build/temp.macosx-10.3-fat-2.5-10g/cx_Oracle.o -L$ORACLE_HOME/lib -L$ORACLE_HOME -lclntsh -o build/lib.macosx-10.3-fat-2.5-10g/cx_Oracle.so
Then running “python setup.py install” works as expected.
Thanks for the article and the comments!
Comment by bradmontgomery — October 7, 2009 @ 9:39 am |
For what it’s worth, I didn’t run into the Symbol not found: ___divdi3 problem until I tried installing python 2.6, and Yaroslav’s fix did not work for me.
When I reverted back to 2.5 (that is, the OSX default install), the problem went away.
Comment by jaythomas — October 19, 2009 @ 12:29 pm |
jaythomas is it possible you did not change the 2.5 in the command? Did you use the command as brad had it or did you get it from the results of the build?
Using Stackless 2.6.2 on a MacbookPro OSX Leopard. I was using virtualenv and simply ran easy_install cx_Oracle.
When this was done I had the __divdi3 problem per above.
I then went to another directory and downloaded the cx_oracle tar file per above. Created a subdirectory bob. Added bob to my PYTHONPATH (export PYTHONPATH=${PYTHONPATH}:./bob/) then ran:
python setup.py install –install-lib ./bob/
looking back in the output I see.
creating build/lib.macosx-10.3-fat-2.6-10g
gcc -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -g -bundle -undefined dynamic_lookup build/temp.macosx-10.3-fat-2.6-10g/cx_Oracle.o -L/Applications/instantclient/ohome/lib -L/Applications/instantclient/ohome -lclntsh -o build/lib.macosx-10.3-fat-2.6-10g/cx_Oracle.so
Looking in the bob directory there is an egg that is 102871 bytes long.
running this gcc command with “-arch ppc” taken out…
then rerunning my install to ./bob/… I get an egg now that is 51521 bytes long.
I then moved that egg to where easy_install put the bad egg
It a bit longer than it needs to be. But I wanted to make sure I was not introducing additional path problems etc.
Comment by catfishlar — October 24, 2009 @ 12:22 pm |
I had the ‘Symbol not found: ___divdi3′ problem as well, using Python 2.6.2 from python.org. The problem is that python itself is not built correctly? (not linked against libgcc dynamically – I’m not exactly sure) The solution is to link cx_Oracle.so against gcc with the flag
-lgcc
Place that right after ‘-lclntsh’ and the build should work and run without issues. The full gcc line I used was:
gcc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -g -bundle -undefined dynamic_lookup build/temp.macosx-10.3-i386-2.6-10g/cx_Oracle.o -L/usr/lib -L/oracle_home/lib -lclntsh -lgcc -o build/lib.macosx-10.3-i386-2.6-10g/cx_Oracle.so
Comment by Robert Myers — November 17, 2009 @ 10:00 am |
I’m now on a clean install of Snow Leopard (with python 2.6), and I’m having similar problems. cx_Oracle seems to compile and install using the process outlined above, but it now generates an ImportError similar to the following:
ImportError: dlopen(/Users/brad/.python-eggs/cx_Oracle-5.0.1-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so, 2): no suitable image found. Did find:
/Users/brad/.python-eggs/cx_Oracle-5.0.1-py2.6-macosx-10.6-universal.egg-tmp/cx_Oracle.so: mach-o, but wrong architecture
I’ve also found that recompiling the library generates “-arch i386 -arch ppc -arch x86_64″ flags, and results in a linker error (even when removing the ppc and x86_64 flags):
ld: warning: in /Users/brad/Oracle10g_MacOSX/instantclient/instantclient_10_2/libclntsh.dylib, file is not of required architecture
I grabbed the x64 version of Oracle’s libraries (instantclient-basic-10.2.0.4.0-macosx-x64.zip, etc), rebuilt cx_Oracle with just the “-arch x86_64″ flag, and cx_Oracle is now working on Snow Leopard.
So the process is:
1) Run: python setup.py build
2) Alter and run your generated gcc commanr. Mine looks like: gcc-4.2 -Wl,-F. -bundle -undefined dynamic_lookup -arch x86_64 build/temp.macosx-10.6-universal-2.6-10g/cx_Oracle.o -L/Users/oldbrad/Oracle10g_MacOSX/instantclient/instantclient_10_2/lib -L/Users/oldbrad/Oracle10g_MacOSX/instantclient/instantclient_10_2 -lclntsh -o build/lib.macosx-10.6-universal-2.6-10g/cx_Oracle.so
3) Run: python setup.py install
Comment by Brad Montgomery — December 21, 2009 @ 10:23 am |