Search code examples
pythonoracle-databasepython-importcx-oracle

UNIX/Python - How to use cx_Oracle without internet and pip


My company does not (yet) allow us to install or upgrade python3 neither install modules from pip on their servers. Even if I could, the machine is not connected to internet. But we can execute the python2 binary

Goal

Use the cx_Oracle module without using pip and internet

Workaround tentative

I got the idea to install cx_Oracle package on my computer and then copy the module files installed from my computer to the server.

So server dev folder looks like this (only listing interesting directories and files, omitting __pychache__, *.pyc and other useless *.py files):

|-- test_cx_oracle_in_local.py
\-- sqlalchemy/
    |-- connectors
    |-- databases
    |-- dialects
    |   |-- firebird
    |   |-- mysql
    |   |-- mssql
    |   |-- oracle
    |   |   |-- base.py
    |   |   |-- cx_oracle.py   <--- This is the interesting file
    |   |   |-- __init__.py
    |   |   \-- zxjdbc.py
    |   |-- postgresql
    |   |-- sqlite
    |   |-- sybase
    |-- engine
    |-- event
    |-- ext
    |   \-- declarative
    |-- orm
    |-- pool
    |-- sql
    |-- testing
    |   |-- plugin
    |   \-- suite
    \-- util

TEST 1

import cx_Oracle

if __name__ == "__main__":
    cx_Oracle.connect(user="xxxxxxxx", password="xxxxxxxx", dns="xxxxxxxx")

Output:

Traceback (most recent call last):
  File "test_cx_oracle_in_local.py", line xx, in <module>
    import cx_oracle
ImportError: No module named cx_Oracle

TEST 2

from sqlalchemy.dialects.oracle.cx_oracle import cx_Oracle

if __name__ == "__main__":
    cx_Oracle.connect(user="xxxxxxxx", password="xxxxxxxx", dns="xxxxxxxx")

Output:

Traceback (most recent call last):
  File "test_cx_oracle_in_local.py", line 36, in __init__
    self.connection = cx_oracle.connect(user="xxxxxxxx", password="xxxxxxxx", dns="xxxxxxxx")
AttributeError: 'module' object has no attribute 'connect'

TEST 3

Using STACKOVERFLOW - Import a module from a relative path

import os, sys, inspect
sys.path.insert(0, xxxxxxxx) # <--- see link above to see sorin's answer
import cx_oracle

if __name__ == "__main__":
    print("SYS_PATH = " + str(sys.path))
    cx_Oracle.connect(user="xxxxxxxx", password="xxxxxxxx", dns="xxxxxxxx")

Output:

SYS_PATH = ['/xxxxxxxx/sqlalchemy/dialects/oracle', '/xxxxxxxx/sqlalchemy/dialects', '/xxxxxxxx/sqlalchemy', 'xxxxxxxx', ...]
  File "test_cx_oracle_in_local.py", line xx, in <module>
    import cx_oracle
  File "/xxxxxxxx/sqlalchemy/dialects/oracle/cx_oracle.py", line 286, in <module>
    from . import base as oracle
ValueError: Attempted relative import in non-package

Please notice

  • The server OS is UNIX family (not a Windows/MAC)
  • I do not have edition neither execution rights to /bin, /usr, /opt, etc.
  • I can't use pip, pip is not even installed on the server
  • I can download files from my pro computer to the server
  • From server side, pinging or getting internet is impossible
  • I am currently running with python 2 but I am interested for python 3 solution if you have

Question

How can I fully use the module cx_Oracle without internet and without using pip neither having +wx access to system folder?


Solution

  • The cx_oracle.py file in the sqlalchemy folder is not actually the cx_Oracle library - it's just a sqlalchemy wrapper for the actual cx_Oracle library, which is a compiled binary (including the compiled ODPI-C library, written in C).

    Easiest way I can think of:

    1. Download cx_Oracle-7.3.0-cp27-cp27mu-manylinux1_x86_64.whl - this is the Wheel for the Python 2.7 version of cx_Oracle 7.3, the most recent cx_Oracle to support Python 2.
    2. Extract it (it's just a zip file) and put cx_Oracle.so somewhere on your server. This is the binary cx_Oracle library file.
    3. Load it as a relative library - if it's in the same directory as your code, import cx_Oracle should work.