Django

Code

Changeset 6432

Show
Ignore:
Timestamp:
09/28/07 14:25:50 (1 year ago)
Author:
ikelly
Message:

Fixed #5627: Added documentation and caveats about using the oracle
backend.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/docs/databases.txt

    r6261 r6432  
    164164.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB 
    165165 
     166 
     167Oracle Notes 
     168============ 
     169 
     170Django supports `Oracle Database Server`_ versions 9i and higher.  Oracle 
     171version 10g or later is required to use Django's ``regex`` and ``iregex`` query 
     172operators.  You will also need the `cx_Oracle`_ driver, version 4.3.1 or newer. 
     173 
     174.. _`Oracle Database Server`: http://www.oracle.com/ 
     175.. _`cx_Oracle`: http://cx-oracle.sourceforge.net/ 
     176 
     177To run ``python manage.py syncdb``, you'll need to create an Oracle database 
     178user with CREATE TABLE, CREATE SEQUENCE, and CREATE PROCEDURE privileges.  To 
     179run Django's test suite, the user also needs CREATE and DROP DATABASE and 
     180CREATE and DROP TABLESPACE privileges. 
     181 
     182Connecting to the Database 
     183-------------------------- 
     184 
     185Your Django settings.py file should look something like this for Oracle:: 
     186 
     187    DATABASE_ENGINE = 'oracle' 
     188    DATABASE_NAME = 'xe' 
     189    DATABASE_USER = 'a_user' 
     190    DATABASE_PASSWORD = 'a_password' 
     191    DATABASE_HOST = '' 
     192    DATABASE_PORT = '' 
     193 
     194If you don't use a ``tnsnames.ora`` file or a similar naming method that 
     195recognizes the SID ("xe" in this example), then fill in both ``DATABASE_HOST`` 
     196and ``DATABASE_PORT`` like so:: 
     197 
     198    DATABASE_ENGINE = 'oracle' 
     199    DATABASE_NAME = 'xe' 
     200    DATABASE_USER = 'a_user' 
     201    DATABASE_PASSWORD = 'a_password' 
     202    DATABASE_HOST = 'dbprod01ned.mycompany.com' 
     203    DATABASE_PORT = '1540' 
     204 
     205You should supply both ``DATABASE_HOST`` and ``DATABASE_PORT``, or leave both 
     206as empty strings. 
     207 
     208Tablespace Options 
     209------------------ 
     210 
     211A common paradigm for optimizing performance in Oracle-based systems is the 
     212use of `tablespaces`_ to organize disk layout. The Oracle backend supports 
     213this use case by adding ``db_tablespace`` options to the ``Meta`` and 
     214``Field`` classes.  (When using a backend that lacks support for tablespaces, 
     215these options are ignored.) 
     216 
     217.. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace 
     218 
     219A tablespace can be specified for the table(s) generated by a model by 
     220supplying the ``db_tablespace`` option inside the model's ``Meta`` class. 
     221Additionally, the ``db_tablespace`` option can be passed to a ``Field`` 
     222constructor to specify an alternate tablespace for the ``Field``'s column 
     223index.  If no index would be created for the column, the ``db_tablespace`` 
     224option is ignored. 
     225 
     226:: 
     227 
     228    class TablespaceExample(models.Model): 
     229        name = models.CharField(maxlength=30, db_index=True, db_tablespace="indexes") 
     230        data = models.CharField(maxlength=255, db_index=True) 
     231        edges = models.ManyToManyField(to="self", db_tablespace="indexes") 
     232 
     233        class Meta: 
     234            db_tablespace = "tables" 
     235 
     236In this example, the tables generated by the ``TablespaceExample`` model 
     237(i.e., the model table and the many-to-many table) would be stored in the 
     238``tables`` tablespace.  The index for the name field and the indexes on the 
     239many-to-many table would be stored in the ``indexes`` tablespace.  The ``data`` 
     240field would also generate an index, but no tablespace for it is specified, so 
     241it would be stored in the model tablespace ``tables`` by default. 
     242 
     243Django does not create the tablespaces for you.  Please refer to `Oracle's 
     244documentation`_ for details on creating and managing tablespaces. 
     245 
     246.. _`Oracle's documentation`: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#SQLRF01403 
     247 
     248Naming Issues 
     249------------- 
     250 
     251Oracle imposes a name length limit of 30 characters.  To accommodate this, the 
     252backend truncates database identifiers to fit, replacing the final four 
     253characters of the truncated name with a repeatable MD5 hash value. 
     254 
     255NULL and Empty Strings 
     256---------------------- 
     257 
     258Django generally prefers to use the empty string ('') rather than NULL, but 
     259Oracle treats both identically.  To get around this, the Oracle backend 
     260coerces the ``null=True`` option on fields that permit the empty string as a 
     261value.  When fetching from the database, it is assumed that a NULL value in 
     262one of these fields really means the empty string, and the data is silently 
     263converted to reflect this assumption. 
     264 
     265TextField Limitations 
     266--------------------- 
     267 
     268The Oracle backend stores ``TextFields`` as ``NCLOB`` columns.  Oracle imposes 
     269some limitations on the usage of such LOB columns in general: 
     270 
     271  * LOB columns may not be used as primary keys. 
     272 
     273  * LOB columns may not be used in indexes. 
     274 
     275  * LOB columns may not be used in a ``SELECT DISTINCT`` list.  This means that 
     276    attempting to use the ``QuerySet.distinct`` method on a model that 
     277    includes ``TextField`` columns will result in an error when run against 
     278    Oracle.  A workaround to this is to keep ``TextField`` columns out of any 
     279    models that you foresee performing ``.distinct`` queries on, and to 
     280    include the ``TextField`` in a related model instead.