| 1 |
=============================== |
|---|
| 2 |
Notes about supported databases |
|---|
| 3 |
=============================== |
|---|
| 4 |
|
|---|
| 5 |
Django attempts to support as many features as possible on all database |
|---|
| 6 |
backends. However, not all database backends are alike, and we've had to make |
|---|
| 7 |
design decisions on which features to support and which assumptions we can make |
|---|
| 8 |
safely. |
|---|
| 9 |
|
|---|
| 10 |
This file describes some of the features that might be relevant to Django |
|---|
| 11 |
usage. Of course, it is not intended as a replacement for server-specific |
|---|
| 12 |
documentation or reference manuals. |
|---|
| 13 |
|
|---|
| 14 |
MySQL notes |
|---|
| 15 |
=========== |
|---|
| 16 |
|
|---|
| 17 |
Django expects the database to support transactions, referential integrity, |
|---|
| 18 |
and Unicode support (UTF-8 encoding). Fortunately, MySQL_ has all these |
|---|
| 19 |
features as available as far back as 3.23. While it may be possible to use |
|---|
| 20 |
3.23 or 4.0, you'll probably have less trouble if you use 4.1 or 5.0. |
|---|
| 21 |
|
|---|
| 22 |
MySQL 4.1 |
|---|
| 23 |
--------- |
|---|
| 24 |
|
|---|
| 25 |
`MySQL 4.1`_ has greatly improved support for character sets. It is possible to |
|---|
| 26 |
set different default character sets on the database, table, and column. |
|---|
| 27 |
Previous versions have only a server-wide character set setting. It's also the |
|---|
| 28 |
first version where the character set can be changed on the fly. 4.1 also has |
|---|
| 29 |
support for views, but Django currently doesn't use views. |
|---|
| 30 |
|
|---|
| 31 |
MySQL 5.0 |
|---|
| 32 |
--------- |
|---|
| 33 |
|
|---|
| 34 |
`MySQL 5.0`_ adds the ``information_schema`` database, which contains detailed |
|---|
| 35 |
data on all database schema. Django's ``inspectdb`` feature uses this |
|---|
| 36 |
``information_schema`` if it's available. 5.0 also has support for stored |
|---|
| 37 |
procedures, but Django currently doesn't use stored procedures. |
|---|
| 38 |
|
|---|
| 39 |
.. _MySQL: http://www.mysql.com/ |
|---|
| 40 |
.. _MySQL 4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html |
|---|
| 41 |
.. _MySQL 5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html |
|---|
| 42 |
|
|---|
| 43 |
Storage engines |
|---|
| 44 |
--------------- |
|---|
| 45 |
|
|---|
| 46 |
MySQL has several `storage engines`_ (previously called table types). You can |
|---|
| 47 |
change the default storage engine in the server configuration. |
|---|
| 48 |
|
|---|
| 49 |
The default engine is MyISAM_. The main drawback of MyISAM is that it doesn't |
|---|
| 50 |
currently support transactions or foreign keys. On the plus side, it's |
|---|
| 51 |
currently the only engine that supports full-text indexing and searching. |
|---|
| 52 |
|
|---|
| 53 |
The InnoDB_ engine is fully transactional and supports foreign key references. |
|---|
| 54 |
|
|---|
| 55 |
The BDB_ engine, like InnoDB, is also fully transactional and supports foreign |
|---|
| 56 |
key references. However, its use seems to be deprecated. |
|---|
| 57 |
|
|---|
| 58 |
`Other storage engines`_, including SolidDB_ and Falcon_, are on the horizon. |
|---|
| 59 |
For now, InnoDB is probably your best choice. |
|---|
| 60 |
|
|---|
| 61 |
.. _storage engines: http://dev.mysql.com/doc/refman/5.0/en/storage-engines.html |
|---|
| 62 |
.. _MyISAM: http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html |
|---|
| 63 |
.. _BDB: http://dev.mysql.com/doc/refman/5.0/en/bdb-storage-engine.html |
|---|
| 64 |
.. _InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb.html |
|---|
| 65 |
.. _Other storage engines: http://dev.mysql.com/doc/refman/5.1/en/storage-engines-other.html |
|---|
| 66 |
.. _SolidDB: http://forge.mysql.com/projects/view.php?id=139 |
|---|
| 67 |
.. _Falcon: http://dev.mysql.com/doc/falcon/en/index.html |
|---|
| 68 |
|
|---|
| 69 |
MySQLdb |
|---|
| 70 |
------- |
|---|
| 71 |
|
|---|
| 72 |
`MySQLdb`_ is the Python interface to MySQL. Version 1.2.1p2 or later is |
|---|
| 73 |
required for full MySQL support in Django. Earlier versions will not work with |
|---|
| 74 |
the ``mysql`` backend. |
|---|
| 75 |
|
|---|
| 76 |
If you are trying to use an older version of MySQL and the ``mysql_old`` |
|---|
| 77 |
backend, then 1.2.0 *might* work for you. |
|---|
| 78 |
|
|---|
| 79 |
.. note:: |
|---|
| 80 |
If you see ``ImportError: cannot import name ImmutableSet`` when trying to |
|---|
| 81 |
use Django, your MySQLdb installation may contain an outdated ``sets.py`` |
|---|
| 82 |
file that conflicts with the built-in module of the same name from Python |
|---|
| 83 |
2.4 and later. To fix this, verify that you have installed MySQLdb version |
|---|
| 84 |
1.2.1p2 or newer, then delete the ``sets.py`` file in the MySQLdb |
|---|
| 85 |
directory that was left by an earlier version. |
|---|
| 86 |
|
|---|
| 87 |
.. _MySQLdb: http://sourceforge.net/projects/mysql-python |
|---|
| 88 |
|
|---|
| 89 |
Creating your database |
|---|
| 90 |
---------------------- |
|---|
| 91 |
|
|---|
| 92 |
You can `create your database`_ using the command-line tools and this SQL:: |
|---|
| 93 |
|
|---|
| 94 |
CREATE DATABASE <dbname> CHARACTER SET utf8; |
|---|
| 95 |
|
|---|
| 96 |
This ensures all tables and columns will use UTF-8 by default. |
|---|
| 97 |
|
|---|
| 98 |
.. _create your database: http://dev.mysql.com/doc/refman/5.0/en/create-database.html |
|---|
| 99 |
|
|---|
| 100 |
Connecting to the database |
|---|
| 101 |
-------------------------- |
|---|
| 102 |
|
|---|
| 103 |
Refer to the `settings documentation`_. |
|---|
| 104 |
|
|---|
| 105 |
Connection settings are used in this order: |
|---|
| 106 |
|
|---|
| 107 |
1. ``DATABASE_OPTIONS`` |
|---|
| 108 |
2. ``DATABASE_NAME``, ``DATABASE_USER``, ``DATABASE_PASSWORD``, ``DATABASE_HOST``, |
|---|
| 109 |
``DATABASE_PORT`` |
|---|
| 110 |
3. MySQL option files. |
|---|
| 111 |
|
|---|
| 112 |
In other words, if you set the name of the database in ``DATABASE_OPTIONS``, |
|---|
| 113 |
this will take precedence over ``DATABASE_NAME``, which would override |
|---|
| 114 |
anything in a `MySQL option file`_. |
|---|
| 115 |
|
|---|
| 116 |
Here's a sample configuration which uses a MySQL option file:: |
|---|
| 117 |
|
|---|
| 118 |
# settings.py |
|---|
| 119 |
DATABASE_ENGINE = "mysql" |
|---|
| 120 |
DATABASE_OPTIONS = { |
|---|
| 121 |
'read_default_file': '/path/to/my.cnf', |
|---|
| 122 |
} |
|---|
| 123 |
|
|---|
| 124 |
# my.cnf |
|---|
| 125 |
[client] |
|---|
| 126 |
database = DATABASE_NAME |
|---|
| 127 |
user = DATABASE_USER |
|---|
| 128 |
password = DATABASE_PASSWORD |
|---|
| 129 |
default-character-set = utf8 |
|---|
| 130 |
|
|---|
| 131 |
Several other MySQLdb connection options may be useful, such as ``ssl``, |
|---|
| 132 |
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the |
|---|
| 133 |
`MySQLdb documentation`_ for more details. |
|---|
| 134 |
|
|---|
| 135 |
.. _settings documentation: ../settings/#database-engine |
|---|
| 136 |
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html |
|---|
| 137 |
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/ |
|---|
| 138 |
|
|---|
| 139 |
Creating your tables |
|---|
| 140 |
-------------------- |
|---|
| 141 |
|
|---|
| 142 |
When Django generates the schema, it doesn't specify a storage engine, so |
|---|
| 143 |
tables will be created with whatever default storage engine your database |
|---|
| 144 |
server is configured for. The easiest solution is to set your database server's |
|---|
| 145 |
default storage engine to the desired engine. |
|---|
| 146 |
|
|---|
| 147 |
If you're using a hosting service and can't change your server's default |
|---|
| 148 |
storage engine, you have a couple of options. |
|---|
| 149 |
|
|---|
| 150 |
* After the tables are created, execute an ``ALTER TABLE`` statement to |
|---|
| 151 |
convert a table to a new storage engine (such as InnoDB):: |
|---|
| 152 |
|
|---|
| 153 |
ALTER TABLE <tablename> ENGINE=INNODB; |
|---|
| 154 |
|
|---|
| 155 |
This can be tedious if you have a lot of tables. |
|---|
| 156 |
|
|---|
| 157 |
* Another option is to use the ``init_command`` option for MySQLdb prior to |
|---|
| 158 |
creating your tables:: |
|---|
| 159 |
|
|---|
| 160 |
DATABASE_OPTIONS = { |
|---|
| 161 |
# ... |
|---|
| 162 |
"init_command": "SET storage_engine=INNODB", |
|---|
| 163 |
# ... |
|---|
| 164 |
} |
|---|
| 165 |
|
|---|
| 166 |
This sets the default storage engine upon connecting to the database. |
|---|
| 167 |
After your tables have been created, you should remove this option. |
|---|
| 168 |
|
|---|
| 169 |
* Another method for changing the storage engine is described in |
|---|
| 170 |
AlterModelOnSyncDB_. |
|---|
| 171 |
|
|---|
| 172 |
.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB |
|---|
| 173 |
|
|---|
| 174 |
|
|---|
| 175 |
Oracle notes |
|---|
| 176 |
============ |
|---|
| 177 |
|
|---|
| 178 |
Django supports `Oracle Database Server`_ versions 9i and higher. Oracle |
|---|
| 179 |
version 10g or later is required to use Django's ``regex`` and ``iregex`` query |
|---|
| 180 |
operators. You will also need the `cx_Oracle`_ driver, version 4.3.1 or newer. |
|---|
| 181 |
|
|---|
| 182 |
.. _`Oracle Database Server`: http://www.oracle.com/ |
|---|
| 183 |
.. _`cx_Oracle`: http://cx-oracle.sourceforge.net/ |
|---|
| 184 |
|
|---|
| 185 |
In order for the ``python manage.py syncdb`` command to work, your Oracle |
|---|
| 186 |
database user must have privileges to run the following commands: |
|---|
| 187 |
|
|---|
| 188 |
* CREATE TABLE |
|---|
| 189 |
* CREATE SEQUENCE |
|---|
| 190 |
* CREATE PROCEDURE |
|---|
| 191 |
* CREATE TRIGGER |
|---|
| 192 |
|
|---|
| 193 |
To run Django's test suite, the user needs these *additional* privileges: |
|---|
| 194 |
|
|---|
| 195 |
* CREATE DATABASE |
|---|
| 196 |
* DROP DATABASE |
|---|
| 197 |
* CREATE TABLESPACE |
|---|
| 198 |
* DROP TABLESPACE |
|---|
| 199 |
|
|---|
| 200 |
Connecting to the database |
|---|
| 201 |
-------------------------- |
|---|
| 202 |
|
|---|
| 203 |
Your Django settings.py file should look something like this for Oracle:: |
|---|
| 204 |
|
|---|
| 205 |
DATABASE_ENGINE = 'oracle' |
|---|
| 206 |
DATABASE_NAME = 'xe' |
|---|
| 207 |
DATABASE_USER = 'a_user' |
|---|
| 208 |
DATABASE_PASSWORD = 'a_password' |
|---|
| 209 |
DATABASE_HOST = '' |
|---|
| 210 |
DATABASE_PORT = '' |
|---|
| 211 |
|
|---|
| 212 |
If you don't use a ``tnsnames.ora`` file or a similar naming method that |
|---|
| 213 |
recognizes the SID ("xe" in this example), then fill in both ``DATABASE_HOST`` |
|---|
| 214 |
and ``DATABASE_PORT`` like so:: |
|---|
| 215 |
|
|---|
| 216 |
DATABASE_ENGINE = 'oracle' |
|---|
| 217 |
DATABASE_NAME = 'xe' |
|---|
| 218 |
DATABASE_USER = 'a_user' |
|---|
| 219 |
DATABASE_PASSWORD = 'a_password' |
|---|
| 220 |
DATABASE_HOST = 'dbprod01ned.mycompany.com' |
|---|
| 221 |
DATABASE_PORT = '1540' |
|---|
| 222 |
|
|---|
| 223 |
You should supply both ``DATABASE_HOST`` and ``DATABASE_PORT``, or leave both |
|---|
| 224 |
as empty strings. |
|---|
| 225 |
|
|---|
| 226 |
Tablespace options |
|---|
| 227 |
------------------ |
|---|
| 228 |
|
|---|
| 229 |
A common paradigm for optimizing performance in Oracle-based systems is the |
|---|
| 230 |
use of `tablespaces`_ to organize disk layout. The Oracle backend supports |
|---|
| 231 |
this use case by adding ``db_tablespace`` options to the ``Meta`` and |
|---|
| 232 |
``Field`` classes. (When you use a backend that lacks support for tablespaces, |
|---|
| 233 |
Django ignores these options.) |
|---|
| 234 |
|
|---|
| 235 |
.. _`tablespaces`: http://en.wikipedia.org/wiki/Tablespace |
|---|
| 236 |
|
|---|
| 237 |
A tablespace can be specified for the table(s) generated by a model by |
|---|
| 238 |
supplying the ``db_tablespace`` option inside the model's ``class Meta``. |
|---|
| 239 |
Additionally, you can pass the ``db_tablespace`` option to a ``Field`` |
|---|
| 240 |
constructor to specify an alternate tablespace for the ``Field``'s column |
|---|
| 241 |
index. If no index would be created for the column, the ``db_tablespace`` |
|---|
| 242 |
option is ignored. |
|---|
| 243 |
|
|---|
| 244 |
:: |
|---|
| 245 |
|
|---|
| 246 |
class TablespaceExample(models.Model): |
|---|
| 247 |
name = models.CharField(max_length=30, db_index=True, db_tablespace="indexes") |
|---|
| 248 |
data = models.CharField(max_length=255, db_index=True) |
|---|
| 249 |
edges = models.ManyToManyField(to="self", db_tablespace="indexes") |
|---|
| 250 |
|
|---|
| 251 |
class Meta: |
|---|
| 252 |
db_tablespace = "tables" |
|---|
| 253 |
|
|---|
| 254 |
In this example, the tables generated by the ``TablespaceExample`` model |
|---|
| 255 |
(i.e., the model table and the many-to-many table) would be stored in the |
|---|
| 256 |
``tables`` tablespace. The index for the name field and the indexes on the |
|---|
| 257 |
many-to-many table would be stored in the ``indexes`` tablespace. The ``data`` |
|---|
| 258 |
field would also generate an index, but no tablespace for it is specified, so |
|---|
| 259 |
it would be stored in the model tablespace ``tables`` by default. |
|---|
| 260 |
|
|---|
| 261 |
**New in the Django development version:** Use the ``DEFAULT_TABLESPACE`` and |
|---|
| 262 |
``DEFAULT_INDEX_TABLESPACE`` settings to specify default values for the |
|---|
| 263 |
db_tablespace options. These are useful for setting a tablespace for the |
|---|
| 264 |
built-in Django apps and other applications whose code you cannot control. |
|---|
| 265 |
|
|---|
| 266 |
Django does not create the tablespaces for you. Please refer to `Oracle's |
|---|
| 267 |
documentation`_ for details on creating and managing tablespaces. |
|---|
| 268 |
|
|---|
| 269 |
.. _`Oracle's documentation`: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#SQLRF01403 |
|---|
| 270 |
|
|---|
| 271 |
Naming issues |
|---|
| 272 |
------------- |
|---|
| 273 |
|
|---|
| 274 |
Oracle imposes a name length limit of 30 characters. To accommodate this, the |
|---|
| 275 |
backend truncates database identifiers to fit, replacing the final four |
|---|
| 276 |
characters of the truncated name with a repeatable MD5 hash value. |
|---|
| 277 |
|
|---|
| 278 |
NULL and empty strings |
|---|
| 279 |
---------------------- |
|---|
| 280 |
|
|---|
| 281 |
Django generally prefers to use the empty string ('') rather than NULL, but |
|---|
| 282 |
Oracle treats both identically. To get around this, the Oracle backend |
|---|
| 283 |
coerces the ``null=True`` option on fields that permit the empty string as a |
|---|
| 284 |
value. When fetching from the database, it is assumed that a NULL value in |
|---|
| 285 |
one of these fields really means the empty string, and the data is silently |
|---|
| 286 |
converted to reflect this assumption. |
|---|
| 287 |
|
|---|
| 288 |
``TextField`` limitations |
|---|
| 289 |
------------------------- |
|---|
| 290 |
|
|---|
| 291 |
The Oracle backend stores ``TextFields`` as ``NCLOB`` columns. Oracle imposes |
|---|
| 292 |
some limitations on the usage of such LOB columns in general: |
|---|
| 293 |
|
|---|
| 294 |
* LOB columns may not be used as primary keys. |
|---|
| 295 |
|
|---|
| 296 |
* LOB columns may not be used in indexes. |
|---|
| 297 |
|
|---|
| 298 |
* LOB columns may not be used in a ``SELECT DISTINCT`` list. This means that |
|---|
| 299 |
attempting to use the ``QuerySet.distinct`` method on a model that |
|---|
| 300 |
includes ``TextField`` columns will result in an error when run against |
|---|
| 301 |
Oracle. A workaround to this is to keep ``TextField`` columns out of any |
|---|
| 302 |
models that you foresee performing ``distinct()`` queries on, and to |
|---|
| 303 |
include the ``TextField`` in a related model instead. |
|---|