diff --git a/README.rst b/README.rst index d502908..b5a4b9a 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ This simple Django utility allows you to utilize the Supported databases ------------------- -Support currently exists for PostgreSQL, PostGIS, MySQL, MySQL (GIS) and SQLite. +Support currently exists for PostgreSQL, PostGIS, MySQL, MySQL (GIS), Oracle, Oracle (GIS) and SQLite. Installation ------------ @@ -54,6 +54,10 @@ URL schema +-------------+--------------------------------------------+--------------------------------------------------+ | SQLite | ``django.db.backends.sqlite3`` | ``sqlite:///PATH`` [2]_ | +-------------+--------------------------------------------+--------------------------------------------------+ +| Oracle | ``django.db.backends.oracle`` | ``oracle://USER:PASSWORD@HOST:PORT/NAME`` [3]_ | ++-------------+--------------------------------------------+--------------------------------------------------+ +| Oracle (GIS)| ``django.contrib.gis.db.backends.oracle`` | ``oraclegis://USER:PASSWORD@HOST:PORT/NAME`` | ++-------------+--------------------------------------------+--------------------------------------------------+ .. [1] With PostgreSQL, you can also use unix domain socket paths with `percent encoding `_: @@ -62,3 +66,8 @@ URL schema the hostname, and using the "file" portion as the filename of the database. This has the effect of four slashes being present for an absolute file path: ``sqlite:////full/path/to/your/database/file.sqlite``. +.. [3] Note that when connecting to Oracle the URL isn't in the form you may know + from using other Oracle tools (like SQLPlus) i.e. user and password are separated + by ``:`` not by ``/``. Also you can omit ``HOST`` and ``PORT`` + and provide a full DSN string or TNS name in ``NAME`` part. + diff --git a/dj_database_url.py b/dj_database_url.py index 57f4400..6669976 100644 --- a/dj_database_url.py +++ b/dj_database_url.py @@ -8,7 +8,6 @@ except ImportError: import urllib.parse as urlparse - # Register database schemes in URLs. urlparse.uses_netloc.append('postgres') urlparse.uses_netloc.append('postgresql') @@ -19,6 +18,8 @@ urlparse.uses_netloc.append('mysql2') urlparse.uses_netloc.append('mysqlgis') urlparse.uses_netloc.append('spatialite') urlparse.uses_netloc.append('sqlite') +urlparse.uses_netloc.append('oracle') +urlparse.uses_netloc.append('oraclegis') DEFAULT_ENV = 'DATABASE_URL' @@ -32,6 +33,8 @@ SCHEMES = { 'mysqlgis': 'django.contrib.gis.db.backends.mysql', 'spatialite': 'django.contrib.gis.db.backends.spatialite', 'sqlite': 'django.db.backends.sqlite3', + 'oracle': 'django.db.backends.oracle', + 'oraclegis': 'django.contrib.gis.db.backends.oracle', } diff --git a/test_dj_database_url.py b/test_dj_database_url.py index 9a48af2..c72a3e5 100644 --- a/test_dj_database_url.py +++ b/test_dj_database_url.py @@ -158,5 +158,62 @@ class DatabaseTestSuite(unittest.TestCase): assert 'OPTIONS' not in url + def test_oracle_parsing(self): + url = 'oracle://scott:tiger@oraclehost:1521/hr' + url = dj_database_url.parse(url) + + assert url['ENGINE'] == 'django.db.backends.oracle' + assert url['NAME'] == 'hr' + assert url['HOST'] == 'oraclehost' + assert url['USER'] == 'scott' + assert url['PASSWORD'] == 'tiger' + assert url['PORT'] == 1521 + + def test_oracle_gis_parsing(self): + url = 'oraclegis://scott:tiger@oraclehost:1521/hr' + url = dj_database_url.parse(url) + + assert url['ENGINE'] == 'django.contrib.gis.db.backends.oracle' + assert url['NAME'] == 'hr' + assert url['HOST'] == 'oraclehost' + assert url['USER'] == 'scott' + assert url['PASSWORD'] == 'tiger' + assert url['PORT'] == 1521 + + def test_oracle_dsn_parsing(self): + url = ( + 'oracle://scott:tiger@/' + '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' + '(HOST=oraclehost)(PORT=1521)))' + '(CONNECT_DATA=(SID=hr)))' + ) + url = dj_database_url.parse(url) + + assert url['ENGINE'] == 'django.db.backends.oracle' + assert url['USER'] == 'scott' + assert url['PASSWORD'] == 'tiger' + assert url['HOST'] == '' + assert url['PORT'] == '' + + dsn = ( + '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' + '(HOST=oraclehost)(PORT=1521)))' + '(CONNECT_DATA=(SID=hr)))' + ) + + assert url['NAME'] == dsn + + def test_oracle_tns_parsing(self): + url = 'oracle://scott:tiger@/tnsname' + url = dj_database_url.parse(url) + + assert url['ENGINE'] == 'django.db.backends.oracle' + assert url['USER'] == 'scott' + assert url['PASSWORD'] == 'tiger' + assert url['NAME'] == 'tnsname' + assert url['HOST'] == '' + assert url['PORT'] == '' + + if __name__ == '__main__': unittest.main()