I have some small python apps that use cx_Oracle to connect to an Oracle database. I deploy these apps by compiling them with py2exe, which works fine in many cases.
If you want to build multiple cx_Oracle versions (eg: cx_Oracle10g, cx_Oracle11g, etc.) then you'll need to modify the cx_Oracle setup.py script. The last step in the script is a call to setup(); the first parameter is the name of the module to build. All you need to do is to change "cx_Oracle" to "cx_Oracle" + ver, where ver is 10g, 11g, etc. Either create several scripts and hard-code it, or add another parameter to setup.py to select it dynamically.
Of course, once you've got that, you need a mechanism to load the correct module at runtime. To do that you'll want to create your own cx_Oracle module that has a __init__.py file that looks something like this:
try:
from cx_Oracle9g import *
except ImportError:
try:
from cx_Oracle10g import *
except ImportError:
try:
from cx_Oracle11g import *
All you need to do is ship your custom cx_Oracle module plus the correct cx_OracleXg module with your application.
Alternately, you could have your custom cx_Oracle module dynamically check for each available Oracle client library (9g, 10g, 11g, etc) and then only import the correct matching cx_OracleXg module. In this case, you only have to ship a single binary, containing your custom cx_Oracle module plus all of the cx_OracleXg modules.