Django-de

Django Dokumentation

Hinweise zu den unterstützten Datenbanken

Diese Dokumentation gilt für Djangos Entwicklerversion, die zum Teil erhebliche Unterschiede zur letzten veröffentlichen Version aufweist.

Django versucht, so viele Funktionen wie möglich auf allen Datenbank-Backends zu unterstützen. Da jedoch nicht alle Datenbank-Backends gleich sind, mussten wir Design-Entscheidungen treffen, welche Funktionen unterstützt werden sollen und von welchen Annahmen wir sicher ausgehen können.

Diese Datei beschreibt einige der Funktionen, die relevant für die Benutzung mit Django sein könnten. Natürlich soll dies kein Ersatz für serverspezifische Dokumente oder Referenzhandbücher sein.

MySQL Hinweise

Django erwartet von der Datenbank, dass sie Transaktionen, referentielle Integrität und Unicode (UTF-8-Kodierung) unterstützt. Glücklicherweise unterstützt MySQL alle diese Funktionen seit Version 3.23. Auch wenn es möglich sein könnte, Version 3.23 oder 4.0 zu benutzen, hast du wahrscheinlich weniger Probleme, wenn du Version 4.1 oder 5.0 benutzt.

MySQL 4.1

MySQL 4.1 hat die Unterstützung für Zeichensätze außerordentlich verbessert. Es ist möglich, verschiedene Standardzeichensätze in Datenbanken, Tabellen und Spalten zu verwenden. In früheren Versionen gab es nur serverweite Zeicheneinstellungen. Außerdem ist das auch die erste Version, in der der Zeichensatz spontan geändert werden kann. 4.1 hat auch Unterstützung für Views, aber Django benutzt derzeit keine Views.

MySQL 5.0

MySQL 5.0 fügt der Datenbank information_schema hinzu, das detailierte Daten über alle Datenbank-Schemata enthält. Djangos inspectdb benutzt dieses information_schema, wenn es verfügbar ist. 5.0 hat auch Unterstützung für gespeicherte Prozeduren, aber Django benutzt diese derzeit nicht.

Storage engines

MySQL hat verschiedene Storage-Engines (zuvor Tabellentypen genannt). Du kannst die standardmäßige Storage-Engine in der Serverkonfiguration ändern.

Die standardmäßige Engine ist MyISAM. Der Hauptnachteil von MyISAM ist, dass es derzeit keine Transaktionen oder Fremdschlüssel unterstützt. Dafür ist es derzeit die einzige Engine, die Volltext-Indizierung und Suchen unterstützt.

Die InnoDB-Engine unterstützt Transaktionen und Fremdschlüssel-Referenzen.

Die BDB-Engine unterstützt, wie InnoDB, Transaktionen und Fremdschlüssel-Referenzen. Allerdings wird sie kaum noch verwendet.

Andere Storage-Engines, einschließlich SolidDB und Falcon, erscheinen am Horizont. Doch für jetzt ist InnoDB wahrscheinlich die beste Wahl.

MySQLdb

MySQLdb ist das Python-Interface für MySQL. Für die vollständige Unterstützung von MySQL in Django ist Version 1.2.1p2 oder neuer erforderlich. Ältere Versionen arbeiten nicht mit dem Backend mysql zusammen.

Wenn du versuchst, eine ältere Version von MySQL und das mysql_old-Backend zu verwenden, dann könnte 1.2.0 für dich funktionieren.

Anmerkung

Solltest du den Fehler ImportError: cannot import name ImmutableSet bekommen, sobald du versuchst, Django zu benutzen, könnte deine MySQLdb-Installation eine veraltete sets.py Datei enthalten. Diese Datei kollidiert mit dem eingebauten, gleichnamigen Modul von Python 2.4 oder neuer. Um dies zu beheben, überprüfe, ob du MySQLdb 1.2.1p2 oder neuer installiert hast und lösche dann die Datei sets.py im Verzeichnis von MySQLdb, die von einer früheren Version übrig geblieben ist.

Erstellen deiner Datenbank

Du kannst deine Datenbank erstellen, indem du die Kommandozeilen-Tools und folgendes SQL benutzt:

CREATE DATABASE <dbname> CHARACTER SET utf8;

Damit wird sichergestellt, dass alle Tabellen und Spalten standardmäßig UTF-8 benutzen.

Mit der Datenbank verbinden

Schau dir bitte die Dokumentation der Einstellungen an.

Verbindungseinstellungen werden in dieser Reihenfolge benutzt:

  1. DATABASE_OPTIONS
  2. DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD, DATABASE_HOST, DATABASE_PORT
  3. MySQL-Optionsdateien.

Mit anderen Worten, wenn du den Namen der Datenbank in DATABASE_OPTIONS setzt, hat dies Vorrang über DATABASE_NAME, das alles in der MySQL-Optionsdatei überschreiben würde.

Hier ist eine Beispielkonfiguration, die eine MySQL-Optionsdatei benutzt:

# settings.py
DATABASE_ENGINE = "mysql"
DATABASE_OPTIONS = {
    'read_default_file': '/path/to/my.cnf',
    }

# my.cnf
[client]
database = DATABASE_NAME
user = DATABASE_USER
password = DATABASE_PASSWORD
default-character-set = utf8

Verschiedene andere MySQLdb-Verbindungsoptionen könnten nützlich sein, z. B. ssl, use_unicode, init_command und sql_mode. Schau in die MySQLdb-Dokumentation für nähere Details.

Erstellen deiner Tabellen

Wenn Django das Schema generiert, legt es keine Storage-Engine fest — also werden die Tabellen in der Storage-Engine erzeugt, die für deinen Datenbankserver standardmäßig konfiguriert ist. Die einfachste Lösung ist, die Standard-Storage-Engine deiner Datenbank auf die gewünschte Engine einzustellen.

Wenn du einen Hosting-Dienst benutzt, bei dem du nicht die standardmäßige Storage-Engine ändern kannst, hast du mehrere Möglichkeiten.

  • Nachdem die Tabellen erstellt wurden, führe einen ALTER TABLE-Befehl aus, um die Tabellen in eine neue Storage-Engine zu konvertieren (wie z. B. InnoDB):

    ALTER TABLE <tablename> ENGINE=INNODB;
    

    Dies kann langwierig sein, wenn du eine Menge Tabellen hast.

  • Eine weitere Möglichkeit ist die init_command-Option von MySQLdb, bevor du deine Tabellen erstellst:

    DATABASE_OPTIONS = {
        # ...
       "init_command": "SET storage_engine=INNODB",
        # ...
    }
    

    Dieses stellt die standardmäßige Storage-Engine während des Verbindungsaufbaus zur Datenbank ein. Nachdem deine Tabellen erstellt wurden, solltest du diese Option wieder entfernen.

  • Eine andere Methode zum Ändern der Storage-Engine wird in AlterModelOnSyncDB beschrieben.

Oracle Hinweise

Django unterstützt Oracle-Datenbank-Server der Versionen 9i und höher. Oracle Version 10g oder neuer ist erforderlich, um Djangos Abfragenmethoden regex und iregex benutzen zu können. Du benötigst außerdem den cx_Oracle-Treiber, Version 4.3.1 oder neuer.

Damit der Befehl python manage.py syncdb funktioniert, muss dein Oracle-Datenbank-Benutzer die Rechte haben, folgende Befehle auszuführen:

  • CREATE TABLE
  • CREATE SEQUENCE
  • CREATE PROCEDURE
  • CREATE TRIGGER

Um Djangos Test-Suite laufen lassen zu können, benötigt der Benutzer diese zusätzlichen Rechte:

  • CREATE DATABASE
  • DROP DATABASE
  • CREATE TABLESPACE
  • DROP TABLESPACE

Mit der Datenbank verbinden

Deine settings.py-Datei sollte für Oracle ungefähr so aussehen:

DATABASE_ENGINE = 'oracle'
DATABASE_NAME = 'xe'
DATABASE_USER = 'ein_benutzer'
DATABASE_PASSWORD = 'ein_passwort'
DATABASE_HOST = ''
DATABASE_PORT = ''

Wenn du nicht eine tnsnames.ora-Datei oder eine ähnliche Methode zur Benennung benutzt, die die SID (“xe” in diesem Beispiel) benutzt, dann fülle sowohl den DATABASE_HOST, als auch den DATABASE_HOST so aus:

DATABASE_ENGINE = 'oracle'
DATABASE_NAME = 'xe'
DATABASE_USER = 'ein_benutzer'
DATABASE_PASSWORD = 'ein_benutzer'
DATABASE_HOST = 'dbprod01ned.mycompany.com'
DATABASE_PORT = '1540'

Du solltest beide angeben (DATABASE_HOST und DATABASE_PORT) oder beide leer lassen.

Tablespace-Optionen

Ein übliches Paradigma zur Optimierung der Leistung von Oracle-basierten Systemen ist die Benutzung von tablespaces zur Organisation der Festplatte. Das Oracle-Backend fügt in diesem Fall den Meta- und Field-Klassen db_tablespace-Optionen hinzu. (Solltest du ein Backend benutzen, das keine Unterstützung für tablespaces hat, ignoriert Django diese Optionen).

Ein Tablespace kann durch das Hinzufügen der Option db_tablespace im Bereich class Meta für Tabellen angegeben werden, die von einem Datenmodell generiert wurden. Zusätzlich kannst du die Option db_tablespace an einen Field-Konstruktor weitergeben, um einen alternativen Tablespace für den Spaltenindex von Field anzugeben. Wenn kein Index für die Spalte erstellt werden soll, wird die Option db_tablespace ignoriert.

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 diesem Beispiel würden die Tabellen, die vom Datenmodell TablespaceExample (z. B. die Datenmodell-Tabelle und die Many-to-Many-Tabelle ) erzeugt würden, im tables-Tablespace abgelegt. Der Index für das name-Feld und die Indices der Many-to-Many-Tabelle würden im Tablespace indexes abgelegt werden. Das Feld data würde ebenfalls einen Index generieren, aber da kein Tablespace angegeben wurde, würde es standardmäßig im Tablespace tables des Datenmodells gespeichert.

Neu in Djangos Entwicklerversion: Benutze die Einstellungen DEFAULT_TABLESPACE und DEFAULT_INDEX_TABLESPACE um die Standardwerte für die Optionen von db_tablespace anzugeben. Diese sind nützlich, um einen Tablespace für die eingebauten Django-Anwendungen und andere Anwendungen, deren Code du nicht kontrollieren kannst, zu definieren.

Django erzeugt deine Tablespaces nicht automatisch. Bitte schaue in die Oracle-Dokumentation für Details zum Erzeugen und Verwalten von Tablespaces.

Bennenungsprobleme

Oracle erzwingt die Begrenzung eines Namens auf maximal 30 Zeichen. Um dem entgegenzukommen, beschneidet das Backend die Datenbankbezeichnung, in dem es die letzten vier Zeichen des beschnittenen Namen mit einem reproduzierbaren MD5-Hashwert ersetzt.

NULL und leere Zeichenketten

Django zieht es generell vor, eine leere Zeichenkette (‘’) anstatt NULL zu verwenden, Oracle behandelt allerdings beide identisch. Um dieses zu umgehen, erzwingt das Oracle-Backend die Option null=True bei Feldern, die eine leere Zeichenkette als Wert zulassen. Beim Abrufen von der Datenbank wird angenommen, dass ein NULL-Wert in einem dieser Felder wirklich eine leere Zeichenketten bedeutet und die Daten werden stillschweigend konvertiert, um diese Annahme widerzuspiegeln.

TextField-Beschränkungen

Das Oracle-Backend speichert TextFields als NCLOB-Spalten. Oracle verhängt im Allgemeinen einige Beschränkungen bei solchen LOB-Spalten:

  • LOB-Spalten dürfen nicht als Primärschlüssel benutzt werden.
  • LOB-Spalten dürfen nicht in Indexes benutzt werden.
  • LOB-Spalten dürfen nicht in einer SELECT DISTINCT-Liste verwendet werden. Das bedeutet, dass der Versuch die Methode``QuerySet.distinct`` auf ein Datenmodell mit TextField-Spalten anzuwenden, in einen Fehler resultiert, wenn es mit Oracle versucht wird. Eine Lösungsmöglichkeit ist, die TextField-Spalten aus jedem Datenmodell herauszuhalten, von dem man annimmt, dass distinct()-Anfragen damit ausgeführt werden könnten. Stattdessen sollten die TextField-Felder in verknüpften Datenmodellen eingefügt werden.