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.

Notas do PostgreSQL

Alterado no Django 1.3: Please, see the release notes

Django supports PostgreSQL 8.0 and higher. If you want to use database-level autocommit, a minimum version of PostgreSQL 8.2 is required.

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.

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.

Transaction handling

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.

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 OPTIONS part of your database configuration in DATABASES:

'OPTIONS': {
    'autocommit': True,
}

In this configuration, Django still ensures that delete() and update() queries run inside a single transaction, so that either all the affected objects are changed or none of them are.

This is database-level autocommit

This functionality is not the same as the autocommit decorator. That decorator is a Django-level implementation that commits automatically after data changing operations. The feature enabled using the 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.

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.

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 [1]. 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.

[1]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.

Criando seu banco de dados

Você pode criar seu banco de dados usando as ferramentas de linha de comando e este SQL:

CREATE DATABASE <dbname> CHARACTER SET utf8;

Isto assegura que todas as tabelas e colunas usarão UTF-8 por padrão.

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.

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 CharField class will return unicode strings even with utf8_bin collation. However, 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 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 django.contrib.sessions.models.Session table (usually called django_session) and the django.contrib.admin.models.LogEntry table (usually called django_admin_log). Those are the two standard tables that use TextField internally.

Conectando ao banco de dados

Consulte a documentação de configurações.

Configurações de conexões são usadas nesta ordem:

  1. OPTIONS.
  2. NAME, USER, PASSWORD, HOST, 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.

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 <tablename> 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.

Notas sobre campos específicos

Campos boolean

Alterado no Django 1.2: Please, see the release notes

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 CharField, SlugField e 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 TimeField or DateTimeField respectively, a ValueError is raised rather than truncating data.

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.

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.

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.

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 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 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

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.

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.)

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.

Novo no Django 1.0: Please, see the release notes

Use the DEFAULT_TABLESPACE and 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.

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.

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:

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.