.. .. META INFORMATION OF TRANSLATION .. .. $TranslationStatus: In Progress $ .. $OriginalRevision: 14780 $ .. $TranslationAuthors: Robson Mendonça $ .. .. INFO OF THIS FILE (DO NOT EDIT! UPDATED BY SUBVERSION) .. .. $HeadURL$ .. $LastChangedRevision$ .. $LastChangedBy$ .. $LastChangedDate$ .. ========= Databases ========= O Django tenta suportar tantas funcionalidades quanto possível sobre todos os banco de dados. Entretanto, nem todos os banco de dados são parecidos, e nós temos que tomar decisões de projeto sobre quais funcionalidades suportar e quais suposições que podemos fazer com segurança. Este arquivo descreve algumas das funcionalidades que podem ser relevantes no uso do Django. Obviamente, não tem o objetivo de ser um substituto para a documentação ou referência específica do servidor. .. _postgresql-notes: Notas do PostgreSQL =================== .. versionchanged:: 1.3 Django supports PostgreSQL 8.0 and higher. If you want to use :ref:`database-level autocommit `, a minimum version of PostgreSQL 8.2 is required. .. admonition:: Improvements in recent PostgreSQL versions PostgreSQL 8.0 and 8.1 `will soon reach end-of-life`_; there have also been a number of significant performance improvements added in recent PostgreSQL versions. Although PostgreSQL 8.0 is the minimum supported version, you would be well advised to use a more recent version if at all possible. .. _will soon reach end-of-life: http://wiki.postgresql.org/wiki/PostgreSQL_Release_Support_Policy PostgreSQL 8.2 to 8.2.4 ----------------------- The implementation of the population statistics aggregates ``STDDEV_POP`` and ``VAR_POP`` that shipped with PostgreSQL 8.2 to 8.2.4 are `known to be faulty`_. Users of these releases of PostgreSQL are advised to upgrade to `Release 8.2.5`_ or later. Django will raise a ``NotImplementedError`` if you attempt to use the ``StdDev(sample=False)`` or ``Variance(sample=False)`` aggregate with a database backend that falls within the affected release range. .. _known to be faulty: http://archives.postgresql.org/pgsql-bugs/2007-07/msg00046.php .. _Release 8.2.5: http://developer.postgresql.org/pgdocs/postgres/release-8-2-5.html Transaction handling --------------------- :doc:`By default `, Django starts a transaction when a database connection is first used and commits the result at the end of the request/response handling. The PostgreSQL backends normally operate the same as any other Django backend in this respect. .. _postgresql-autocommit-mode: Autocommit mode ~~~~~~~~~~~~~~~ If your application is particularly read-heavy and doesn't make many database writes, the overhead of a constantly open transaction can sometimes be noticeable. For those situations, if you're using the ``postgresql_psycopg2`` backend, you can configure Django to use *"autocommit"* behavior for the connection, meaning that each database operation will normally be in its own transaction, rather than having the transaction extend over multiple operations. In this case, you can still manually start a transaction if you're doing something that requires consistency across multiple database operations. The autocommit behavior is enabled by setting the ``autocommit`` key in the :setting:`OPTIONS` part of your database configuration in :setting:`DATABASES`:: 'OPTIONS': { 'autocommit': True, } In this configuration, Django still ensures that :ref:`delete() ` and :ref:`update() ` queries run inside a single transaction, so that either all the affected objects are changed or none of them are. .. admonition:: This is database-level autocommit This functionality is not the same as the :ref:`autocommit ` decorator. That decorator is a Django-level implementation that commits automatically after data changing operations. The feature enabled using the :setting:`OPTIONS` option provides autocommit behavior at the database adapter level. It commits after *every* operation. If you are using this feature and performing an operation akin to delete or updating that requires multiple operations, you are strongly recommended to wrap you operations in manual transaction handling to ensure data consistency. You should also audit your existing code for any instances of this behavior before enabling this feature. It's faster, but it provides less automatic protection for multi-call operations. Indexes for ``varchar`` and ``text`` columns ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When specifying ``db_index=True`` on your model fields, Django typically outputs a single ``CREATE INDEX`` statement. However, if the database type for the field is either ``varchar`` or ``text`` (e.g., used by ``CharField``, ``FileField``, and ``TextField``), then Django will create an additional index that uses an appropriate `PostgreSQL operator class`_ for the column. The extra index is necessary to correctly perfrom lookups that use the ``LIKE`` operator in their SQL, as is done with the ``contains`` and ``startswith`` lookup types. .. _PostgreSQL operator class: http://www.postgresql.org/docs/8.4/static/indexes-opclass.html .. _mysql-notes: Notas do MySQL ============== O Django espera que o banco de dados tenha suporta a transações, integridade referencial, e Unicode (codificação UTF-8). Felizmente, o MySQL_ possui todas essas funcionalidades disponíveis desde a versão 3.23. Embora seja possível utilizar as versões 3.23 ou 4.0, você provavelmente terá menos trabalho se usar as versões 4.1 ou 5.0. MySQL 4.1 --------- O `MySQL 4.1`_ possui grandes melhorias no suporte a conjuntos de caracters. É possível configurar diferentes tipos de charsets para banco de dados, tabela e coluna. Nas versões anteriores temos somente uma configuração de charset para todo servidor. Essa também é a primeira versão onde o charset pode ser modificado durante a execução. O 4.1 também tem suporte a views, mas o Django atualmente não usa views. MySQL 5.0 --------- O `MySQL 5.0`_ adicionou o banco de dados ``information_schema``, que contém dados detalhados sobre todo o esquema do banco de dados. A funcionalidade ``inspectdb`` do Django usa este ``information_schema`` se estiver disponível. A versão 5.0 também suporta armazenamento de procedures, mas o Django atualmente não usa stored procedures. .. _MySQL: http://www.mysql.com/ .. _MySQL 4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html .. _MySQL 5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html Motores de armazenameto ----------------------- O MySQL tem vários `motores de armazenamento`_ (anteriormente chamado de tipos de tabela). Você pode mudar a configuração de motor de armazenamento padrão. O motor padrão é o MyISAM_ [#]_. O principal inconveniente do MyISAM é que ele atualmente não suporta transações ou chaves estrangeiras. O lado bom, é que atualmente ele é o único motor que suporta indexação full-text e busca. O motor InnoDB_ é completamente transacional e suporta referências de chave estrangeira e é provavelmente sua melhor escolha agora. .. _motores de armazenamento: http://dev.mysql.com/doc/refman/5.5/en/storage-engines.html .. _MyISAM: http://dev.mysql.com/doc/refman/5.5/en/myisam-storage-engine.html .. _InnoDB: http://dev.mysql.com/doc/refman/5.5/en/innodb.html .. [#] A menos que isso seja mudado pelo empacotador do seu pacote do MySQL. Tivemos relatos de que o instalador do Windows Community Server configura o InnoDB como motor de armazenamento padrão, por exemplo. MySQLdb ------- `MySQLdb`_ é uma interface Python para o MySQL. A versão 1.2.1p2 ou superior é necessária para um suporte completo no Django. .. note:: Se você ver um erro ``ImportError: cannot import name ImmutableSet`` quando tentar usar o Django, sua instalação do MySQLdb pode estar ultrapassada, pois arquivo ``sets.py`` conlita com o módulo nativo, de mesmo nome, oriundo do Python 2.4 e superior. Para arrumar isso, verifique se versão do MySQLdb que você tem instalado é a 1.2.1p2 ou mais nova, e então delete o arquivo ``sets.py`` no diretório do MySQLdb que foi deixado pela versão anterior. .. _MySQLdb: http://sourceforge.net/projects/mysql-python Criando seu banco de dados -------------------------- Você pode `criar seu banco de dados`_ usando as ferramentas de linha de comando e este SQL:: CREATE DATABASE CHARACTER SET utf8; Isto assegura que todas as tabelas e colunas usarão UTF-8 por padrão. .. _criar seu banco de dados: http://dev.mysql.com/doc/refman/5.0/en/create-database.html .. _mysql-collation: Configurações de collation ~~~~~~~~~~~~~~~~~~~~~~~~~~ A configuração de collation para uma coluna controla a ordem na qual os dados são ordenados, bem como quais strings são consideradas iguais. Ela pode ser configurada para todo banco de dados, por tabela e por coluna. Isso está `completamente documentado`_ na documentação do MySQL. Em todos os casos, você configura o collation diretamente ao manipular as tabelas do banco de dados; O Django não fornece uma forma de configurar isso na definição do model. .. _completamente documentado: http://dev.mysql.com/doc/refman/5.0/en/charset.html By default, with a UTF-8 database, MySQL will use the ``utf8_general_ci_swedish`` collation. This results in all string equality comparisons being done in a *case-insensitive* manner. That is, ``"Fred"`` and ``"freD"`` are considered equal at the database level. If you have a unique constraint on a field, it would be illegal to try to insert both ``"aa"`` and ``"AA"`` into the same column, since they compare as equal (and, hence, non-unique) with the default collation. In many cases, this default will not be a problem. However, if you really want case-sensitive comparisons on a particular column or table, you would change the column or table to use the ``utf8_bin`` collation. The main thing to be aware of in this case is that if you are using MySQLdb 1.2.2, the database backend in Django will then return bytestrings (instead of unicode strings) for any character fields it receive from the database. This is a strong variation from Django's normal practice of *always* returning unicode strings. It is up to you, the developer, to handle the fact that you will receive bytestrings if you configure your table(s) to use ``utf8_bin`` collation. Django itself should mostly work smoothly with such columns (except for the ``contrib.sessions`` ``Session`` and ``contrib.admin`` ``LogEntry`` tables described below), but your code must be prepared to call ``django.utils.encoding.smart_unicode()`` at times if it really wants to work with consistent data -- Django will not do this for you (the database backend layer and the model population layer are separated internally so the database layer doesn't know it needs to make this conversion in this one particular case). If you're using MySQLdb 1.2.1p2, Django's standard :class:`~django.db.models.CharField` class will return unicode strings even with ``utf8_bin`` collation. However, :class:`~django.db.models.TextField` fields will be returned as an ``array.array`` instance (from Python's standard ``array`` module). There isn't a lot Django can do about that, since, again, the information needed to make the necessary conversions isn't available when the data is read in from the database. This problem was `fixed in MySQLdb 1.2.2`_, so if you want to use :class:`~django.db.models.TextField` with ``utf8_bin`` collation, upgrading to version 1.2.2 and then dealing with the bytestrings (which shouldn't be too difficult) as described above is the recommended solution. Should you decide to use ``utf8_bin`` collation for some of your tables with MySQLdb 1.2.1p2 or 1.2.2, you should still use ``utf8_collation_ci_swedish`` (the default) collation for the :class:`django.contrib.sessions.models.Session` table (usually called ``django_session``) and the :class:`django.contrib.admin.models.LogEntry` table (usually called ``django_admin_log``). Those are the two standard tables that use :class:`~django.db.model.TextField` internally. .. _fixed in MySQLdb 1.2.2: http://sourceforge.net/tracker/index.php?func=detail&aid=1495765&group_id=22307&atid=374932 Conectando ao banco de dados ---------------------------- Consulte a :doc:`documentação de configurações `. Configurações de conexões são usadas nesta ordem: 1. :setting:`OPTIONS`. 2. :setting:`NAME`, :setting:`USER`, :setting:`PASSWORD`, :setting:`HOST`, :setting:`PORT` 3. MySQL option files. Em outras palavras, se você configurar o nome do banco de dados em ``OPTIONS``, este terá precedência sobre ``NAME``, que poderia ser sobrescrito por qualquer um num `arquivo de opções do MySQL`_. Aqui temos uma amostra de configurações que usam um arquivo de opções do MySQL:: # settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'OPTIONS': { 'read_default_file': '/path/to/my.cnf', }, } } # my.cnf [client] database = NAME user = USER password = PASSWORD default-character-set = utf8 Várias outras configurações de conexões do MySQLdb poem ser úteis, como ``ssl``, ``use_unicode``, ``init_command``, e ``sql_mode``. Consulte a `documentação do MySQLdb`_ para mais detalhes. .. _arquivo de opções do MySQL: http://dev.mysql.com/doc/refman/5.0/en/option-files.html .. _documentação do MySQLdb: http://mysql-python.sourceforge.net/ Criando suas tabelas -------------------- Quando o Django gera um esquema, ele não especifica um motor de armazenamento, então as tabelas podem ser criadas com qualquer motor de armazenamento padrão para o qual o seu servidor de banco de dados esteja configurado. A solução mais fácil é configurar o motor de armazenamento padrão de seu banco de dados para o motor desejado. Se você estiver usando um serviço de hospedagem e não pode modificar o motor de armazenamento padrão de seu servidor, você tem algumas opções. * Depois de criar as tabelas, execute uma consulta ``ALTER TABLE`` para converter uma tabela para o novo motor de armazenamento (tal como InnoDB):: ALTER TABLE ENGINE=INNODB; Isso pode ser um tédio se você possui muitas tabelas. * Outra opção seria usar a opção ``init_command`` para o MySQLdb antes de criar suas tabelas:: 'OPTIONS': { 'init_command': 'SET storage_engine=INNODB', } Isso configurar o motor de armazenamento padrão ao conectar ao banco de dados. Depois que suas tabelas foram criadas, você deve remover esta opção. * Outro método para mudar o motor de armazenamento é descrito no AlterModelOnSyncDB_. .. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB Notas sobre campos específicos ------------------------------ Campos boolean ~~~~~~~~~~~~~~ .. versionchanged:: 1.2 In previous versions of Django when running under MySQL ``BooleanFields`` would return their data as ``ints``, instead of true ``bools``. See the release notes for a complete description of the change. Campos de caracter ~~~~~~~~~~~~~~~~~~ Quaisquer campos que são armazenados com colunas do tipo ``VARCHAR`` e que tenha o seu ``max_lenght`` limitado em 255 caracteres se você estiver usando ``unique=True`` para o campo. Isto afeta :class:`~django.db.models.CharField`, :class:`~django.db.models.SlugField` e :class:`~django.db.models.CommaSeparatedIntegerField`. Além disso, se você estiver usando uma versnao do MySQL anterior ao 5.0.3, todos esses tipos de colunas possuem um comprimento máximo limitado em 255 caracteres, independentemente de ``unique=True`` está especificado ou não. DateTime fields ~~~~~~~~~~~~~~~ MySQL does not have a timezone-aware column type. If an attempt is made to store a timezone-aware ``time`` or ``datetime`` to a :class:`~django.db.models.TimeField` or :class:`~django.db.models.DateTimeField` respectively, a ``ValueError`` is raised rather than truncating data. .. _sqlite-notes: Notas do SQLite =============== O SQLite_ fornece uma alternativa excelente para desenvolvimento para aplicações que são predominantemente somente leitura ou requer uma instalação pequena. Como todos os servidores de banco de dados, ainda que, há algumas diferenças que são específicas do SQLite que você deve tomar cuidado. .. _SQLite: http://www.sqlite.org/ .. _sqlite-string-matching: String matching for non-ASCII strings ------------------------------------- O SQLite não suporta case-insensitive (diferenciação de maiúsculas e minúsculas) para strings non-ASCII. Algumas soluções para esse problema estão `documentadas em sqlite.org`_, mas elas não são utilizadas pelo backend padrão do SQLite no Django. Portanto, se você estiver usando a pesquisa do tipo ``iexact`` nos seus filtros de queryset, esteja ciente de que não funcionará como esperado para strings non-ASCII. .. _documentadas em sqlite.org: http://www.sqlite.org/faq.html#q18 SQLite 3.3.6 ou mais recente é fortemente recomendado ----------------------------------------------------- Versões do SQLite 3.3.5 e anteriores contêm os seguintes bugs: * um bug ao `manipular`_ parametros ``ORDER BY``. Isso pode causar problemas quando você usa o parâmetro ``select`` para o método ``extra()`` do QuerySet. O bug pode ser identificado pela mensagem de erro ``OperationalError: ORDER BY terms must not be non-integer constants`` (termos do ORDER BY não devem ser constantes não inteiras). * A bug when handling `aggregation`_ together with DateFields and DecimalFields. .. _manipular: http://www.sqlite.org/cvstrac/tktview?tn=1768 .. _aggregation: http://code.djangoproject.com/ticket/10031 O SQLite 3.3.6 foi lançado em Abril de 2006, assim a maior parte das distribuições binárias para diferentes plataformas incluem a versão mais nova do SQLite usável pelo Python tanto através do módulo ``pysqlite2`` quanto do ``sqlite3``. Entretanto, algumas versões de plaformas/Python incluem versões mais antigas do SQLite (e.g. a distribuição binária oficial do Python 2.5 para o Windows, 2.5.4 na época da escrita desse documento, incluiu o SQLite 3.3.4). There are (as of Django 1.1) even some tests in the Django test suite that will fail when run under this setup. As described :ref:`below`, this can be solved by downloading and installing a newer version of ``pysqlite2`` (``pysqlite-2.x.x.win32-py2.5.exe`` in the described case) that includes and uses a newer version of SQLite. Python 2.6 for Windows ships with a version of SQLite that is not affected by these issues. Versão 3.5.9 ------------ O pacote SQLite 3.5.9-3 do Ubuntu "Intrepid Ibex" (8.10) contém um bug que causa problemas com a avaliação de expressões de consulta. Se você estiver usando o Ubuntu "Intrepid Ibex", você precisará atualizar o pacote para versão 3.5.9-3ubuntu1 ou mais recente (recomendado) ou encontrar uma fonte alternativa para os pacotes do SQLite, ou instalar o SQLite a partir do código fonte. O Debian Lenny vem acompanhado do mesmo mal funcionamento no pacote do SQLite 3.5.9-3. Entretanto, o projeto Debian tem subsequentemente entregue versões do pacote SQLite que corrigem esses bugs. Se você encontrar algum, você está obtendo resultados inesperados pelo Debian, assegure-se que de ter atualizado seu pacote do SQLite para 3.5.9-5 ou maior. O problema aparentemente não existe com outras versões do pacote SQLite de outros sistemas operacionais. Versão 3.6.2 ------------ SQLite versão 3.6.2 (liberado em 30 de Agosto de 2008) introduz um bug na manipulação do ``SELECT DISTINCT`` que é disparado pelo, entre outras coisas, ``DateQuerySet`` do Django (retornado por um método ``dates()`` num queryset). Você deve evitar usar esta versão do SQLite com o Django. Também atualize para 3.6.3 (liberado em 22 de Setembro de 2008) ou maior, ou use uma versão mais antiga do SQLite. .. _using-newer-versions-of-pysqlite: Using newer versions of the SQLite DB-API 2.0 driver ---------------------------------------------------- For versions of Python 2.5 or newer that include ``sqlite3`` in the standard library Django will now use a ``pysqlite2`` interface in preference to ``sqlite3`` if it finds one is available. This provides the ability to upgrade both the DB-API 2.0 interface or SQLite 3 itself to versions newer than the ones included with your particular Python binary distribution, if needed. Erros "Database is locked" -------------------------- SQLite is meant to be a lightweight database, and thus can't support a high level of concurrency. ``OperationalError: database is locked`` errors indicate that your application is experiencing more concurrency than ``sqlite`` can handle in default configuration. This error means that one thread or process has an exclusive lock on the database connection and another thread timed out waiting for the lock the be released. Python's SQLite wrapper has a default timeout value that determines how long the second thread is allowed to wait on the lock before it times out and raises the ``OperationalError: database is locked`` error. If you're getting this error, you can solve it by: * Switching to another database backend. At a certain point SQLite becomes too "lite" for real-world applications, and these sorts of concurrency errors indicate you've reached that point. * Rewriting your code to reduce concurrency and ensure that database transactions are short-lived. * Increase the default timeout value by setting the ``timeout`` database option option:: 'OPTIONS': { # ... 'timeout': 20, # ... } This will simply make SQLite wait a bit longer before throwing "database is locked" errors; it won't really do anything to solve them. .. _oracle-notes: Oracle notes ============ Django supports `Oracle Database Server`_ versions 9i and higher. Oracle version 10g or later is required to use Django's ``regex`` and ``iregex`` query operators. You will also need at least version 4.3.1 of the `cx_Oracle`_ Python driver. Note that due to a Unicode-corruption bug in ``cx_Oracle`` 5.0, that version of the driver should **not** be used with Django; ``cx_Oracle`` 5.0.1 resolved this issue, so if you'd like to use a more recent ``cx_Oracle``, use version 5.0.1. ``cx_Oracle`` 5.0.1 or greater can optionally be compiled with the ``WITH_UNICODE`` environment variable. This is recommended but not required. .. _`Oracle Database Server`: http://www.oracle.com/ .. _`cx_Oracle`: http://cx-oracle.sourceforge.net/ In order for the ``python manage.py syncdb`` command to work, your Oracle database user must have privileges to run the following commands: * CREATE TABLE * CREATE SEQUENCE * CREATE PROCEDURE * CREATE TRIGGER To run Django's test suite, the user needs these *additional* privileges: * CREATE USER * DROP USER * CREATE TABLESPACE * DROP TABLESPACE * CONNECT WITH ADMIN OPTION * RESOURCE WITH ADMIN OPTION Connecting to the database -------------------------- Your Django settings.py file should look something like this for Oracle:: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'xe', 'USER': 'a_user', 'PASSWORD': 'a_password', 'HOST': '', 'PORT': '', } } If you don't use a ``tnsnames.ora`` file or a similar naming method that recognizes the SID ("xe" in this example), then fill in both ``HOST`` and ``PORT`` like so:: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'xe', 'USER': 'a_user', 'PASSWORD': 'a_password', 'HOST': 'dbprod01ned.mycompany.com', 'PORT': '1540', } } You should supply both ``HOST`` and ``PORT``, or leave both as empty strings. Threaded option ---------------- If you plan to run Django in a multithreaded environment (e.g. Apache in Windows using the default MPM module), then you **must** set the ``threaded`` option of your Oracle database configuration to True:: 'OPTIONS': { 'threaded': True, }, Failure to do this may result in crashes and other odd behavior. Tablespace options ------------------ A common paradigm for optimizing performance in Oracle-based systems is the use of `tablespaces`_ to organize disk layout. The Oracle backend supports this use case by adding ``db_tablespace`` options to the ``Meta`` and ``Field`` classes. (When you use a backend that lacks support for tablespaces, Django ignores these options.) .. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace A tablespace can be specified for the table(s) generated by a model by supplying the ``db_tablespace`` option inside the model's ``class Meta``. Additionally, you can pass the ``db_tablespace`` option to a ``Field`` constructor to specify an alternate tablespace for the ``Field``'s column index. If no index would be created for the column, the ``db_tablespace`` option is ignored:: class TablespaceExample(models.Model): name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes") data = models.CharField(max_length=255, db_index=True) edges = models.ManyToManyField(to="self", db_tablespace="indexes") class Meta: db_tablespace = "tables" In this example, the tables generated by the ``TablespaceExample`` model (i.e., the model table and the many-to-many table) would be stored in the ``tables`` tablespace. The index for the name field and the indexes on the many-to-many table would be stored in the ``indexes`` tablespace. The ``data`` field would also generate an index, but no tablespace for it is specified, so it would be stored in the model tablespace ``tables`` by default. .. versionadded:: 1.0 Use the :setting:`DEFAULT_TABLESPACE` and :setting:`DEFAULT_INDEX_TABLESPACE` settings to specify default values for the db_tablespace options. These are useful for setting a tablespace for the built-in Django apps and other applications whose code you cannot control. Django does not create the tablespaces for you. Please refer to `Oracle's documentation`_ for details on creating and managing tablespaces. .. _`Oracle's documentation`: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#SQLRF01403 Naming issues ------------- Oracle imposes a name length limit of 30 characters. To accommodate this, the backend truncates database identifiers to fit, replacing the final four characters of the truncated name with a repeatable MD5 hash value. When running syncdb, an ``ORA-06552`` error may be encountered if certain Oracle keywords are used as the name of a model field or the value of a ``db_column`` option. Django quotes all identifiers used in queries to prevent most such problems, but this error can still occur when an Oracle datatype is used as a column name. In particular, take care to avoid using the names ``date``, ``timestamp``, ``number`` or ``float`` as a field name. NULL and empty strings ---------------------- Django generally prefers to use the empty string ('') rather than NULL, but Oracle treats both identically. To get around this, the Oracle backend coerces the ``null=True`` option on fields that have the empty string as a possible value. When fetching from the database, it is assumed that a NULL value in one of these fields really means the empty string, and the data is silently converted to reflect this assumption. ``TextField`` limitations ------------------------- The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes some limitations on the usage of such LOB columns in general: * LOB columns may not be used as primary keys. * LOB columns may not be used in indexes. * LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that attempting to use the ``QuerySet.distinct`` method on a model that includes ``TextField`` columns will result in an error when run against Oracle. As a workaround, use the ``QuerySet.defer`` method in conjunction with ``distinct()`` to prevent ``TextField`` columns from being included in the ``SELECT DISTINCT`` list. .. _third-party-notes: Using a 3rd-party database backend ================================== In addition to the officially supported databases, there are backends provided by 3rd parties that allow you to use other databases with Django: * `Sybase SQL Anywhere`_ * `IBM DB2`_ * `Microsoft SQL Server 2005`_ * Firebird_ * ODBC_ The Django versions and ORM features supported by these unofficial backends vary considerably. Queries regarding the specific capabilities of these unofficial backends, along with any support queries, should be directed to the support channels provided by each 3rd party project. .. _Sybase SQL Anywhere: http://code.google.com/p/sqlany-django/ .. _IBM DB2: http://code.google.com/p/ibm-db/ .. _Microsoft SQL Server 2005: http://code.google.com/p/django-mssql/ .. _Firebird: http://code.google.com/p/django-firebird/ .. _ODBC: http://code.google.com/p/django-pyodbc/