---
title: "Databaser"
version: 6.0
locale: sv
source: https://docs.djangoproject.com/sv/6.0/ref/databases/
canonical: https://djangodocs.dev/sv/6.0/ref/databases/
---
# Databaser

Django har officiellt stöd för följande databaser:

- [PostgreSQL](#postgresql-notes)
- [MariaDB](#mariadb-notes)
- [MySQL](#mysql-notes)
- [Oracle](#oracle-notes)
- [SQLite](#sqlite-notes)

Det finns också ett antal [databasbackends som tillhandahålls av tredje part](#third-party-notes).

Django försöker att stödja så många funktioner som möjligt på alla databasbackends. Alla databasbackends är dock inte likadana, och vi har varit tvungna att fatta designbeslut om vilka funktioner som ska stödjas och vilka antaganden vi kan göra på ett säkert sätt.

Den här filen beskriver några av de funktioner som kan vara relevanta för Django-användning. Den är inte avsedd att ersätta serverspecifik dokumentation eller referenshandböcker.

## Allmänna anteckningar

### Beständiga anslutningar

Med beständiga anslutningar undviks omkostnaderna för att återupprätta en anslutning till databasen vid varje HTTP-begäran. De styrs av parametern [`CONN_MAX_AGE`](/sv/6.0/ref/settings/#std-setting-CONN_MAX_AGE) som definierar den maximala livslängden för en anslutning. Den kan ställas in oberoende för varje databas.

Standardvärdet är `0`, vilket bevarar det historiska beteendet att stänga databasanslutningen i slutet av varje begäran. För att aktivera långvariga anslutningar, ställ in [`CONN_MAX_AGE`](/sv/6.0/ref/settings/#std-setting-CONN_MAX_AGE) till ett positivt heltal av sekunder. För obegränsade långvariga anslutningar, ställ in den på `None`.

När ASGI används bör permanenta anslutningar inaktiveras. Använd istället databasens inbyggda anslutningspoolning om den finns tillgänglig, eller undersök ett alternativ för anslutningspoolning från tredje part om det behövs.

#### Hantering av anslutningar

Django öppnar en anslutning till databasen när den först gör en databasförfrågan. Den håller denna anslutning öppen och återanvänder den i efterföljande förfrågningar. Django stänger anslutningen när den överskrider den maximala ålder som definieras av [`CONN_MAX_AGE`](/sv/6.0/ref/settings/#std-setting-CONN_MAX_AGE) eller när den inte längre kan användas.

I detalj öppnar Django automatiskt en anslutning till databasen när den behöver en och inte redan har en - antingen för att detta är den första anslutningen eller för att den tidigare anslutningen stängdes.

I början av varje begäran stänger Django anslutningen om den har nått sin maximala ålder. Om din databas avslutar inaktiva anslutningar efter en viss tid bör du ställa in [`CONN_MAX_AGE`](/sv/6.0/ref/settings/#std-setting-CONN_MAX_AGE) till ett lägre värde, så att Django inte försöker använda en anslutning som har avslutats av databasservern. (Detta problem kan endast påverka webbplatser med mycket låg trafik)

I slutet av varje begäran stänger Django anslutningen om den har nått sin maximala ålder eller om den befinner sig i ett feltillstånd som inte kan återställas. Om några databasfel har inträffat under behandlingen av begärandena kontrollerar Django om anslutningen fortfarande fungerar och stänger den om den inte gör det. Databasfel påverkar således högst en begäran per varje applikations arbetstråd; om anslutningen blir oanvändbar får nästa begäran en ny anslutning.

Om du sätter [`CONN_HEALTH_CHECKS`](/sv/6.0/ref/settings/#std-setting-CONN_HEALTH_CHECKS) till `True` kan du förbättra robustheten för återanvändning av anslutningar och förhindra fel när en anslutning har stängts av databasservern som nu är redo att ta emot och hantera nya anslutningar, t.ex. efter omstart av databasservern. Hälsokontrollen utförs endast en gång per begäran och endast om databasen nås under hanteringen av begäran.

#### Förbehåll

Eftersom varje tråd upprätthåller sin egen anslutning måste din databas stödja minst lika många samtidiga anslutningar som du har arbetstrådar.

Ibland kommer majoriteten av dina vyer inte åt en databas, t.ex. för att det är databasen för ett externt system eller tack vare cachning. I sådana fall bör du ställa in [`CONN_MAX_AGE`](/sv/6.0/ref/settings/#std-setting-CONN_MAX_AGE) till ett lågt värde eller till och med `0`, eftersom det inte är meningsfullt att upprätthålla en anslutning som sannolikt inte kommer att återanvändas. Detta bidrar till att hålla nere antalet samtidiga anslutningar till databasen.

Utvecklingsservern skapar en ny tråd för varje begäran som den hanterar, vilket upphäver effekten av beständiga anslutningar. Aktivera dem inte under utveckling.

När Django upprättar en anslutning till databasen ställer den in lämpliga parametrar, beroende på vilken backend som används. Om du aktiverar beständiga anslutningar upprepas inte längre denna inställning vid varje begäran. Om du ändrar parametrar som anslutningens isoleringsnivå eller tidszon, bör du antingen återställa Djangos standardvärden i slutet av varje begäran, tvinga fram ett lämpligt värde i början av varje begäran eller inaktivera beständiga anslutningar.

Om en anslutning skapas i en långvarig process, utanför Djangos request-response-cykel, kommer anslutningen att förbli öppen tills den uttryckligen stängs eller timeout inträffar. Du kan använda `django.db.close_old_connections()` för att stänga alla gamla eller oanvändbara anslutningar.

### Avkodning

Django förutsätter att alla databaser använder UTF-8-kodning. Om du använder andra kodningar kan det leda till oväntat beteende, till exempel ”värdet är för långt”-fel från din databas för data som är giltiga i Django. Se de databasspecifika anmärkningarna nedan för information om hur du konfigurerar din databas korrekt.

## PostgreSQL anteckningar

Django supports PostgreSQL 14 and higher. [psycopg](https://www.psycopg.org/psycopg3/) 3.1.12+ or [psycopg2](https://www.psycopg.org/)
2.9.9+ is required, though the latest [psycopg](https://www.psycopg.org/psycopg3/) 3.1.12+ is recommended.

> **Note**
>
> Stöd för `psycopg2` kommer sannolikt att bli föråldrat och tas bort någon gång i framtiden.

### PostgreSQL-anslutningsinställningar

Se [`HOST`](/sv/6.0/ref/settings/#std-setting-HOST) för mer information.

Om du vill ansluta med ett servicenamn från [connection service file](https://www.postgresql.org/docs/current/libpq-pgservice.html) och ett lösenord från [password file](https://www.postgresql.org/docs/current/libpq-pgpass.html) måste du ange dem i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i [`DATABASES`](/sv/6.0/ref/settings/#std-setting-DATABASES):

*`settings.py`*

```python
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "OPTIONS": {
            "service": "my_service",
            "passfile": ".my_pgpass",
        },
    }
}
```

*`.pg_service.conf`*

```text
[my_service]
host=localhost
user=USER
dbname=NAME
port=5432
```

*`.my_pgpass`*

```text
localhost:5432:NAME:USER:PASSWORD
```

PostgreSQL-backend skickar innehållet i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS) som nyckelordsargument till anslutningskonstruktören, vilket möjliggör mer avancerad kontroll av drivrutinsbeteendet. Alla tillgängliga [parametrar](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS) beskrivs i detalj i PostgreSQL-dokumentationen.

> **Warning**
>
> Att använda ett servicenamn för teständamål stöds inte. Denna [kan komma att implementeras senare](https://code.djangoproject.com/ticket/33685).

### Optimera PostgreSQL: s konfiguration

Django behöver följande parametrar för sina databasanslutningar:

- `client_encoding`: `'UTF8'`,
- `default_transaction_isolation`: `'read committed'` som standard, eller det värde som anges i anslutningsalternativen (se nedan),
- **`tidszon`:**

    - när [`USE_TZ`](/sv/6.0/ref/settings/#std-setting-USE_TZ) är `True`, `'UTC'` som standard, eller det värde som [`TIME_ZONE`](/sv/6.0/ref/settings/#std-setting-DATABASE-TIME_ZONE) har ställts in för anslutningen,
    - när [`USE_TZ`](/sv/6.0/ref/settings/#std-setting-USE_TZ) är `False`, värdet av den globala [`TIME_ZONE`](/sv/6.0/ref/settings/#std-setting-TIME_ZONE)-inställningen.

Om dessa parametrar redan har rätt värden kommer Django inte att ställa in dem för varje ny anslutning, vilket förbättrar prestandan något. Du kan konfigurera dem direkt i `postgresql.conf` eller mer bekvämt per databasanvändare med [ALTER ROLE](https://www.postgresql.org/docs/current/sql-alterrole.html).

Django fungerar bra utan denna optimering, men varje ny anslutning kommer att göra några ytterligare frågor för att ställa in dessa parametrar.

### Isolationsnivå

Liksom PostgreSQL själv, är Django standard för `READ COMMITTED` ```isoleringsnivå`_. Om du behöver en högre isoleringsnivå, till exempel ``REPEATABLE READ``` eller `SERIALIZABLE`, ställer du in den i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i [`DATABASES`](/sv/6.0/ref/settings/#std-setting-DATABASES):

```
from django.db.backends.postgresql.psycopg_any import IsolationLevel

DATABASES = {
    # ...
    "OPTIONS": {
        "isolation_level": IsolationLevel.SERIALIZABLE,
    },
}
```

> **Note**
>
> Vid högre isoleringsnivåer bör ditt program vara förberett på att hantera undantag som uppstår vid serialiseringsfel. Det här alternativet är avsett för avancerad användning.

### Roll

Om du behöver använda en annan roll för databasanslutningar än den roll som används för att upprätta anslutningen, anger du den i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i [`DATABASES`](/sv/6.0/ref/settings/#std-setting-DATABASES):

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        # ...
        "OPTIONS": {
            "assume_role": "my_application_role",
        },
    },
}
```

### Anslutningspool

För att använda en anslutningspool med [psycopg](https://www.psycopg.org/psycopg3/) kan du antingen ställa in `"pool"` i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i `DATABASER` till att vara en dict som ska skickas till [`ConnectionPool`](https://www.psycopg.org/psycopg3/docs/api/pool.html#psycopg_pool.ConnectionPool), eller till `True` för att använda `ConnectionPool`-standardvärdena:

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        # ...
        "OPTIONS": {
            "pool": True,
        },
    },
}
```

Detta alternativ kräver att `psycopg[pool]` eller [psycopg-pool](https://pypi.org/project/psycopg-pool/) är installerat och ignoreras med `psycopg2`.

### Bindning av parametrar på serversidan

Med [psycopg](https://www.psycopg.org/psycopg3/) 3.1.8+ använder Django som standard [client-side binding cursors](https://www.psycopg.org/psycopg3/docs/advanced/cursors.html#client-side-binding-cursors). Om du vill använda [server-side binding](https://www.psycopg.org/psycopg3/docs/basic/from_pg2.html#server-side-binding) ställ in det i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i [`DATABASES`](/sv/6.0/ref/settings/#std-setting-DATABASES):

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        # ...
        "OPTIONS": {
            "server_side_binding": True,
        },
    },
}
```

Detta alternativ ignoreras med `psycopg2`.

### Index för kolumnerna `varchar` och `text`

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](https://www.postgresql.org/docs/current/indexes-opclass.html)
for the column. The extra index is necessary to correctly perform
lookups that use the `LIKE` operator in their SQL, as is done with the
`contains` and `startswith` lookup types.

### Migrationsoperation för att lägga till tillägg

Om du behöver lägga till en PostgreSQL-förlängning (som `hstore`, `postgis`, etc.) med hjälp av en migrering, använd [`CreateExtension`](/sv/6.0/ref/contrib/postgres/operations/#django.contrib.postgres.operations.CreateExtension) operation.

### Markörer på serversidan

När du använder [`QuerySet.iterator()`](/sv/6.0/ref/models/querysets/#django.db.models.query.QuerySet.iterator) öppnar Django en [server-side cursor](https://www.psycopg.org/psycopg3/docs/advanced/cursors.html#server-side-cursors). Som standard antar PostgreSQL att endast de första 10% of resultaten av markörfrågor kommer att hämtas. Frågeplaneraren spenderar mindre tid på att planera frågan och börjar returnera resultat snabbare, men detta kan minska prestandan om mer än 10% of resultaten hämtas. PostgreSQL: s antaganden om antalet rader som hämtas för en markörfråga styrs med alternativet [cursor\_tuple\_fraction](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-CURSOR-TUPLE-FRACTION).

#### Transaktionspoolning och cursorer på serversidan

Om du använder en anslutningspooler i transaktionspoolningsläge (t.ex. [PgBouncer](https://www.pgbouncer.org/)) måste du inaktivera markörer på serversidan för den anslutningen.

Markörer på serversidan är lokala för en anslutning och förblir öppna i slutet av en transaktion när [`AUTOCOMMIT`](/sv/6.0/ref/settings/#std-setting-DATABASE-AUTOCOMMIT) är `True`. En efterföljande transaktion kan försöka hämta fler resultat från en markör på serversidan. I transaktionspoolningsläget finns det ingen garanti för att efterföljande transaktioner kommer att använda samma anslutning. Om en annan anslutning används uppstår ett fel när transaktionen refererar till markören på serversidan, eftersom markörer på serversidan endast är tillgängliga i den anslutning där de skapades.

En lösning är att inaktivera markörer på serversidan för en anslutning i `DATABASER` genom att ställa in [`DISABLE_SERVER_SIDE_CURSORS`](/sv/6.0/ref/settings/#std-setting-DATABASE-DISABLE_SERVER_SIDE_CURSORS) till `True`.

Om du vill dra nytta av markörer på serversidan i transaktionspoolningsläge kan du konfigurera [en annan anslutning till databasen](/sv/6.0/topics/db/multi-db/) för att utföra frågor som använder markörer på serversidan. Den här anslutningen måste antingen vara direkt till databasen eller till en anslutningspooler i sessionspoolningsläge.

Ett annat alternativ är att linda in varje `QuerySet` som använder markörer på serversidan i ett [`atomic()`](/sv/6.0/topics/db/transactions/#django.db.transaction.atomic)-block, eftersom det inaktiverar `autocommit` under transaktionens varaktighet. På så sätt kommer markören på serversidan bara att leva under transaktionens varaktighet.

### Manuellt specificerade värden för primärnycklar med automatisk inkrementering

Django använder PostgreSQLs identitetskolumner för att lagra automatiskt ökande primärnycklar. En identitetskolumn fylls med värden från en [sekvens](https://www.postgresql.org/docs/current/sql-createsequence.html) som håller reda på nästa tillgängliga värde. Att manuellt tilldela ett värde till ett fält med automatisk ökning uppdaterar inte fältets sekvens, vilket senare kan orsaka en konflikt. Ett exempel:

```pycon
>>> from django.contrib.auth.models import User
>>> User.objects.create(username="alice", pk=1)
<User: alice>
>>> # The sequence hasn't been updated; its next value is 1.
>>> User.objects.create(username="bob")
IntegrityError: duplicate key value violates unique constraint
"auth_user_pkey" DETAIL:  Key (id)=(1) already exists.
```

Om du behöver ange sådana värden ska du återställa sekvensen efteråt för att undvika att återanvända ett värde som redan finns i tabellen. Hanteringskommandot [`sqlsequencereset`](/sv/6.0/ref/django-admin/#django-admin-sqlsequencereset) genererar SQL-satserna för att göra detta.

### Test av databasmallar

Du kan använda inställningen [`TEST['TEMPLATE']`](/sv/6.0/ref/settings/#std-setting-TEST_TEMPLATE) för att ange en [template](https://www.postgresql.org/docs/current/sql-createdatabase.html) (t.ex. `'template0'`) från vilken en testdatabas ska skapas.

### Snabbare testkörning med icke-durabla inställningar

Du kan påskynda testkörningstiderna genom att [konfigurera PostgreSQL för att vara icke-durable](https://www.postgresql.org/docs/current/non-durability.html).

> **Warning**
>
> Detta är farligt: det gör din databas mer mottaglig för dataförlust eller korruption i händelse av en serverkrasch eller strömavbrott. Använd detta endast på en utvecklingsmaskin där du enkelt kan återställa hela innehållet i alla databaser i klustret.

## MariaDB anteckningar

Django supports MariaDB 10.6 and higher.

För att använda MariaDB, använd MySQL-backend, som delas mellan de två. Se [MySQL notes](#mysql-notes) för mer information.

## Anteckningar om MySQL

### Stöd för version

Django stöder MySQL 8.0.11 och senare.

Djangos funktion `inspectdb` använder databasen `information_schema`, som innehåller detaljerade uppgifter om alla databasscheman.

Django förväntar sig att databasen stöder Unicode (UTF-8-kodning) och delegerar till den uppgiften att upprätthålla transaktioner och referensintegritet. Det är viktigt att vara medveten om det faktum att de två sistnämnda faktiskt inte upprätthålls av MySQL när MyISAM-lagringsmotorn används, se nästa avsnitt.

### Lagringsmotorer

MySQL har flera [lagringsmotorer](#storage-engines). Du kan ändra standardlagringsmotorn i serverkonfigurationen.

MySQL:s standardlagringsmotor är [InnoDB](https://dev.mysql.com/doc/refman/en/innodb-storage-engine.html). Denna motor är helt transaktionell och stöder utländska nyckelreferenser. Det är det rekommenderade valet. InnoDB:s autoincrement-räknare går dock förlorad vid en MySQL-omstart eftersom den inte kommer ihåg värdet `AUTO_INCREMENT`, utan istället återskapar det som ”max(id)+1”. Detta kan resultera i en oavsiktlig återanvändning av [`AutoField`](/sv/6.0/ref/models/fields/#django.db.models.AutoField)-värden.

De största nackdelarna med [MyISAM](https://dev.mysql.com/doc/refman/en/myisam-storage-engine.html) är att den inte stöder transaktioner eller upprätthåller begränsningar för utländska nycklar.

### MySQL DB API-drivrutiner

MySQL har ett par drivrutiner som implementerar Python Database API som beskrivs i [**PEP 249**](https://peps.python.org/pep-0249/):

- [mysqlclient](https://pypi.org/project/mysqlclient/) är en inbyggd drivrutin. Det är **det rekommenderade valet**.
- [MySQL Connector/Python](https://dev.mysql.com/downloads/connector/python/) är en ren Python-drivrutin från Oracle som inte kräver MySQL-klientbiblioteket eller några Python-moduler utanför standardbiblioteket.

Förutom en DB API-drivrutin behöver Django en adapter för att komma åt databasdrivrutinerna från sin ORM. Django tillhandahåller en adapter för mysqlclient medan MySQL Connector/Python innehåller [sin egen](https://dev.mysql.com/doc/connector-python/en/connector-python-django-backend.html).

#### mysqlclient

Django requires [mysqlclient](#mysqlclient) 2.2.1 or later.

#### MySQL Connector/Python

MySQL Connector/Python är tillgänglig från [nedladdningssidan](https://dev.mysql.com/downloads/connector/python/). Django-adaptern är tillgänglig i version 1.1.X och senare. Den kanske inte stöder de senaste versionerna av Django.

### Definitioner av tidszoner

Om du planerar att använda Djangos [tidszonsstöd](/sv/6.0/topics/i18n/timezones/), använd [mysql\_tzinfo\_to\_sql](https://dev.mysql.com/doc/refman/en/mysql-tzinfo-to-sql.html) för att ladda tidszonstabeller i MySQL-databasen. Detta behöver bara göras en gång för din MySQL-server, inte per databas.

### Skapa din databas

Du kan [skapa din databas](#creating-your-database) med hjälp av kommandoradsverktygen och denna SQL:

```sql
CREATE DATABASE <dbname> CHARACTER SET utf8mb4;
```

Detta säkerställer att alla tabeller och kolumner använder UTF-8 som standard.

#### Inställningar för sortering

Kollationsinställningen för en kolumn styr den ordning i vilken data sorteras samt vilka strängar som jämförs som lika. Du kan ange parametern `db_collation` för att ställa in kolumnens kollationsnamn för [`CharField`](/sv/6.0/ref/models/fields/#django.db.models.CharField.db_collation) och [`TextField`](/sv/6.0/ref/models/fields/#django.db.models.TextField.db_collation).

Kollationen kan också ställas in på en databasomfattande nivå och per tabell. Detta är [dokumenterat grundligt](https://dev.mysql.com/doc/refman/en/charset.html) i MySQL-dokumentationen. I sådana fall måste du ställa in sorteringen genom att direkt manipulera databasinställningarna eller tabellerna. Django tillhandahåller inte ett API för att ändra dem.

Som standard, med en UTF-8-databas, kommer MySQL att använda kollationen `utf8mb4_0900_ai_ci`. Detta resulterar i att alla jämförelser av stränglikhet görs på ett *case-insensitive* sätt. Det innebär att `"Fred"` och `"freD"` betraktas som lika på databasnivå. Om du har en unik begränsning på ett fält skulle det vara olagligt att försöka infoga både `"aa"` och `"AA"` i samma kolumn, eftersom de jämförs som lika (och därmed icke-unika) med standardkollationen. Om du vill ha jämförelser med skiftlägeskänslighet i en viss kolumn eller tabell, ändrar du kolumnen eller tabellen så att den använder sorteringen `utf8mb4_0900_as_cs`.

Observera att enligt [MySQL Unicode Character Sets](https://dev.mysql.com/doc/refman/en/charset-unicode-sets.html) är jämförelser för \`\` utf8mb4\_general\_ci\`\` kollation snabbare, men något mindre korrekta än jämförelser för \`\` utf8mb4\_unicode\_ci\`\`. Om detta är acceptabelt för ditt program bör du använda `utf8mb4_general_ci` eftersom det är snabbare. Om detta inte är acceptabelt (t.ex. om du behöver tysk ordboksordning), använd `utf8mb4_unicode_ci` eftersom det är mer exakt.

> **Warning**
>
> Modellformulären validerar unika fält på ett skiftlägeskänsligt sätt. Om man använder en kollationering som inte tar hänsyn till versaler kommer en formuläruppsättning med unika fältvärden som endast skiljer sig åt genom versaler att klara valideringen, men när man anropar `save()` kommer ett `IntegrityError` att uppstå.

### Anslutning till databasen

Se [inställningsdokumentation](/sv/6.0/ref/settings/).

Anslutningsinställningarna används i denna ordning:

1. [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS).
2. [`NAME`](/sv/6.0/ref/settings/#std-setting-NAME), [`USER`](/sv/6.0/ref/settings/#std-setting-USER), [`PASSWORD`](/sv/6.0/ref/settings/#std-setting-PASSWORD), [`HOST`](/sv/6.0/ref/settings/#std-setting-HOST),
   [`PORT`](/sv/6.0/ref/settings/#std-setting-PORT)
3. MySQL-alternativfiler.

Med andra ord, om du anger namnet på databasen i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS), kommer detta att ha företräde framför [`NAME`](/sv/6.0/ref/settings/#std-setting-NAME), som skulle åsidosätta allt i en [MySQL-alternativfil](https://dev.mysql.com/doc/refman/en/option-files.html).

Här är ett exempel på en konfiguration som använder en MySQL-alternativfil:

```
# settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "OPTIONS": {
            "read_default_file": "/path/to/my.cnf",
        },
    }
}
```

```ini
# my.cnf
[client]
database = NAME
user = USER
password = PASSWORD
default-character-set = utf8mb4
```

Flera andra [MySQLdb-anslutningsalternativ](https://mysqlclient.readthedocs.io/user_guide.html#functions-and-attributes) kan vara användbara, till exempel `ssl`, `init_command` och `sql_mode`.

#### Ställa in `sql_mode`

Standardvärdet för alternativet `sql_mode` innehåller `STRICT_TRANS_TABLES`. Det alternativet eskalerar varningar till fel när data trunkeras vid infogning, så Django rekommenderar starkt att du aktiverar ett strikt läge för MySQL för att förhindra dataförlust (antingen `STRICT_TRANS_TABLES` eller `STRICT_ALL_TABLES`).

Om du behöver anpassa SQL-läget kan du ställa in variabeln `sql_mode` som andra MySQL-alternativ: antingen i en konfigurationsfil eller med posten `'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"` i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i `DATABASER`.

#### Isolationsnivå

När samtidiga belastningar körs kan databastransaktioner från olika sessioner (t.ex. separata trådar som hanterar olika förfrågningar) interagera med varandra. Dessa interaktioner påverkas av varje sessions [transaktionsisoleringsnivå](https://dev.mysql.com/doc/refman/en/innodb-transaction-isolation-levels.html). Du kan ange en anslutnings isoleringsnivå med en `'isolation_level'`-post i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i `DATABASER`. Giltiga värden för den här posten är de fyra standardisoleringsnivåerna:

- `'läsa utan åtagande'`
- `'read committed'`
- ”upprepningsbar läsning
- `'serializable'`

eller `None` för att använda serverns konfigurerade isoleringsnivå. Django fungerar dock bäst med och använder som standard read committed i stället för MySQL:s standard, repeatable read. Dataförlust är möjlig med repeterbar läsning. I synnerhet kan du se fall där [`get_or_create()`](/sv/6.0/ref/models/querysets/#django.db.models.query.QuerySet.get_or_create) kommer att ge upphov till ett [`IntegrityError`](/sv/6.0/ref/exceptions/#django.db.IntegrityError) men objektet kommer inte att visas i ett efterföljande [`get()`](/sv/6.0/ref/models/querysets/#django.db.models.query.QuerySet.get)-anrop.

### Skapa dina tabeller

När Django genererar schemat anges ingen lagringsmotor, så tabeller kommer att skapas med den standardlagringsmotor som din databasserver är konfigurerad för. Den enklaste lösningen är att ställa in din databasservers standardlagringsmotor till den önskade motorn.

Om du använder en värdtjänst och inte kan ändra serverns standardlagringsmotor har du ett par alternativ.

- När tabellerna har skapats kan du köra en `ALTER TABLE`-sats för att konvertera en tabell till en ny lagringsmotor (t.ex. InnoDB):

  ```sql
  ALTER TABLE <tablename> ENGINE=INNODB;
  ```

  Detta kan vara tråkigt om du har många tabeller.
- Ett annat alternativ är att använda alternativet `init_command` för MySQLdb innan du skapar dina tabeller:

  ```
  "OPTIONS": {
      "init_command": "SET default_storage_engine=INNODB",
  }
  ```

  Detta anger standardlagringsmotorn vid anslutning till databasen. När tabellerna har skapats bör du ta bort det här alternativet eftersom det lägger till en fråga som bara behövs när tabellerna skapas i varje databasanslutning.

### Tabellnamn

Det finns [kända problem](https://bugs.mysql.com/bug.php?id=48875) även i de senaste versionerna av MySQL som kan leda till att versalerna i ett tabellnamn ändras när vissa SQL-satser körs under vissa förhållanden. Det rekommenderas att du använder små bokstäver i tabellnamn, om möjligt, för att undvika problem som kan uppstå på grund av detta beteende. Django använder små bokstäver i tabellnamn när det automatiskt genererar tabellnamn från modeller, så detta är främst ett övervägande om du åsidosätter tabellnamnet via [`db_table`](/sv/6.0/ref/models/options/#django.db.models.Options.db_table)-parametern.

### Spara poäng

Både Django ORM och MySQL (när de använder InnoDB [storage engine](#mysql-storage-engines)) stöder databas [savepoints](/sv/6.0/topics/db/transactions/#topics-db-transactions-savepoints).

Om du använder MyISAM-lagringsmotorn bör du vara medveten om att du kommer att få databasgenererade fel om du försöker använda [savepoint-relaterade metoder i transaktions-API:n](/sv/6.0/topics/db/transactions/#topics-db-transactions-savepoints). Anledningen till detta är att det är en dyr operation att upptäcka lagringsmotorn för en MySQL-databas/tabell, så det beslutades att det inte är värt att dynamiskt konvertera dessa metoder till no-op baserat på resultaten av sådan upptäckt.

### Anteckningar om specifika områden

#### Teckenfält

Alla fält som lagras med kolumntyperna `VARCHAR` kan ha sin `max_length` begränsad till 255 tecken om du använder `unique=True` för fältet. Detta påverkar [`CharField`](/sv/6.0/ref/models/fields/#django.db.models.CharField), [`SlugField`](/sv/6.0/ref/models/fields/#django.db.models.SlugField). Se [MySQL-dokumentationen](https://dev.mysql.com/doc/refman/en/create-index.html#create-index-column-prefixes) för mer information.

#### begränsningar för `TextField`

MySQL kan endast indexera de första N tecknen i en `BLOB` eller `TEXT`-kolumn. Eftersom `TextField` inte har en definierad längd kan du inte markera den som `unique=True`. MySQL kommer att rapportera: ”BLOB/TEXT-kolumn ’\<db\_column\>’ används i nyckelspecifikation utan en nyckellängd”.

#### Stöd för bråkdelar av sekunder för Time- och DateTime-fält

MySQL kan lagra bråkdelar av sekunder, förutsatt att kolumndefinitionen innehåller en bråkdelsindikation (t.ex. `DATETIME(6)`).

Django kommer inte att uppgradera befintliga kolumner för att inkludera bråkdelar av sekunder om databasservern stöder det. Om du vill aktivera dem i en befintlig databas är det upp till dig att antingen manuellt uppdatera kolumnen i måldatabasen genom att köra ett kommando som:

```sql
ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)
```

eller använda en [`RunSQL`](/sv/6.0/ref/migration-operations/#django.db.migrations.operations.RunSQL) operation i en [datamigrering](/sv/6.0/topics/migrations/#data-migrations).

#### `TIMESTAMP` kolumner

Om du använder en äldre databas som innehåller `TIMESTAMP`-kolumner måste du ställa in [`USE_TZ = False`](/sv/6.0/ref/settings/#std-setting-USE_TZ) för att undvika datakorruption. [`inspectdb`](/sv/6.0/ref/django-admin/#django-admin-inspectdb) mappar dessa kolumner till [`DateTimeField`](/sv/6.0/ref/models/fields/#django.db.models.DateTimeField) och om du aktiverar tidszonsstöd kommer både MySQL och Django att försöka konvertera värdena från UTC till lokal tid.

### Radlåsning med `QuerySet.select_for_update()`

MySQL och MariaDB stöder inte vissa alternativ till `SELECT ... FOR UPDATE`-satsen. Om `select_for_update()` används med ett alternativ som inte stöds, kommer ett [`NotSupportedError`](/sv/6.0/ref/exceptions/#django.db.NotSupportedError) att uppstå.

| Alternativ | MariaDB | MySQL |
| --- | --- | --- |
| `HOPPET LÅST` | X | X |
| `NOWAIT` | X | X |
| `OF` |  | X |
| `NO KEY` |  |  |

När du använder `select_for_update()` på MySQL, se till att du filtrerar en frågeuppsättning mot åtminstone en uppsättning fält som ingår i unika begränsningar eller endast mot fält som täcks av index. Annars kommer ett exklusivt skrivlås att förvärvas över hela tabellen under hela transaktionens varaktighet.

### Automatisk typcasting kan leda till oväntade resultat

När du utför en fråga på en strängtyp, men med ett heltalsvärde, kommer MySQL att tvinga typerna för alla värden i tabellen till ett heltal innan jämförelsen utförs. Om din tabell innehåller värdena `'abc'`, `'def'` och du frågar efter `WHERE mycolumn=0`, kommer båda raderna att matcha. På samma sätt kommer `WHERE mycolumn=1` att matcha värdet `'abc1'`. Därför kommer fält av strängtyp som ingår i Django alltid att kasta värdet till en sträng innan det används i en fråga.

Om du implementerar anpassade modellfält som ärver från [`Field`](/sv/6.0/ref/models/fields/#django.db.models.Field) direkt, åsidosätter [`get_prep_value()`](/sv/6.0/ref/models/fields/#django.db.models.Field.get_prep_value) eller använder [`RawSQL`](/sv/6.0/ref/models/expressions/#django.db.models.expressions.RawSQL), [`extra()`](/sv/6.0/ref/models/querysets/#django.db.models.query.QuerySet.extra), eller [`raw()`](/sv/6.0/topics/db/sql/#django.db.models.Manager.raw), bör du se till att du utför lämplig typecasting.

## Anteckningar om SQLite

Django stöder SQLite 3.31.0 och senare.

[SQLite](https://www.sqlite.org/) är ett utmärkt utvecklingsalternativ för applikationer som huvudsakligen är skrivskyddade eller som kräver en mindre installation. Som med alla databasservrar finns det dock vissa skillnader som är specifika för SQLite som du bör vara medveten om.

### Matchning av substrängar och skiftlägeskänslighet

For all SQLite versions, there is some slightly counterintuitive behavior when
attempting to match some types of strings. These are triggered when using the
[`iexact`](/sv/6.0/ref/models/querysets/#std-fieldlookup-iexact) or [`contains`](/sv/6.0/ref/models/querysets/#std-fieldlookup-contains) filters in querysets. The behavior
splits into two cases:

\1. For substring matching, all matches are done case-insensitively. That is a
filter such as `filter(name__contains="aa")` will match a name of `"Aabb"`.

\2. For strings containing characters outside the ASCII range, all exact string
matches are performed case-sensitively, even when the case-insensitive options
are passed into the query. So the [`iexact`](/sv/6.0/ref/models/querysets/#std-fieldlookup-iexact) filter will behave exactly
the same as the [`exact`](/sv/6.0/ref/models/querysets/#std-fieldlookup-exact) filter in these cases.

Några möjliga lösningar för detta finns [dokumenterade på sqlite.org](https://www.sqlite.org/faq.html#q18), men de används inte av standard SQLite-backend i Django, eftersom det skulle vara ganska svårt att göra dem robusta. Således exponerar Django standard SQLite-beteendet och du bör vara medveten om detta när du gör skiftlägeskänslig eller delsträngsfiltrering.

### Decimalhantering

SQLite har ingen riktig decimal intern typ. Decimalvärden konverteras internt till datatypen `REAL` (8-byte IEEE flyttalsnummer), vilket förklaras i [SQLite datatypes documentation](https://www.sqlite.org/datatype3.html#storage_classes_and_datatypes), så de stöder inte korrekt avrundad decimal flyttalsaritmetik.

### felmeddelandet ”Databasen är låst”

SQLite är tänkt att vara en lättviktig databas och kan därför inte stödja en hög nivå av samtidighet. `OperationalError: database is locked`-fel indikerar att din applikation upplever mer samtidighet än vad `sqlite` kan hantera i standardkonfigurationen. Det här felet innebär att en tråd eller process har ett exklusivt lås på databasanslutningen och att en annan tråd tidsavbröts i väntan på att låset skulle frigöras.

Pythons SQLite-wrapper har ett standardvärde för timeout som avgör hur länge den andra tråden får vänta på låset innan det tar slut och felet `OperationalError: database is locked` uppstår.

Om du får det här felet kan du lösa det genom att:

- Byta till en annan databasbackend. Vid en viss punkt blir SQLite för ”lite” för verkliga applikationer, och den här typen av samtidighetsfel indikerar att du har nått den punkten.
- Skriva om din kod för att minska samtidighet och säkerställa att databastransaktioner är kortlivade.
- Öka standardvärdet för timeout genom att ställa in databasalternativet `timeout`:

  ```
  "OPTIONS": {
      # ...
      "timeout": 20,
      # ...
  }
  ```

  Detta gör att SQLite väntar lite längre innan den ger felmeddelandet ”databasen är låst”, men det gör egentligen ingenting för att lösa dem.

#### Transaktionsbeteende

SQLite stöder tre transaktionslägen: `DEFERRED`, `IMMEDIATE` och `EXCLUSIVE`.

Standardvärdet är `DEFERRED`. Om du behöver använda ett annat läge anger du det i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i `DATABASER`, till exempel:

```
"OPTIONS": {
    # ...
    "transaction_mode": "IMMEDIATE",
    # ...
}
```

Om du vill vara säker på att dina transaktioner väntar till `timeout` innan du meddelar ”Databasen är låst”, ändrar du transaktionsläget till `IMMEDIATE`.

För bästa prestanda med `IMMEDIATE` och `EXCLUSIVE` bör transaktionerna vara så korta som möjligt. Detta kan vara svårt att garantera för alla dina vyer, så användningen av [`ATOMIC_REQUESTS`](/sv/6.0/ref/settings/#std-setting-DATABASE-ATOMIC_REQUESTS) avråds i detta fall.

För mer information se [Transaktioner i SQLite](https://www.sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions).

### `QuerySet.select_for_update()` stöds inte

SQLite har inte stöd för syntaxen `SELECT ... FOR UPDATE`. Att anropa den kommer inte att ha någon effekt.

### Isolering vid användning av `QuerySet.iterator()`

Det finns särskilda överväganden som beskrivs i [Isolation In SQLite](https://www.sqlite.org/isolation.html) när man ändrar en tabell medan man itererar över den med [`QuerySet.iterator()`](/sv/6.0/ref/models/querysets/#django.db.models.query.QuerySet.iterator). Om en rad läggs till, ändras eller tas bort inom loopen kan den raden visas eller inte visas, eller visas två gånger, i efterföljande resultat som hämtas från iteratorn. Din kod måste hantera detta.

### Aktivera JSON1-tillägget på SQLite

To use [`JSONField`](/sv/6.0/ref/models/fields/#django.db.models.JSONField) on SQLite, you need to enable the
[JSON1 extension](https://www.sqlite.org/json1.html) on Python’s [`sqlite3`](https://docs.python.org/3/library/sqlite3.html#module-sqlite3) library. If the extension is
not enabled on your installation, a system error (`fields.E180`) will be
raised.

För att aktivera JSON1-tillägget kan du följa instruktionerna på wikisidan.

> **Note**
>
> JSON1-tillägget är aktiverat som standard i SQLite 3.38+.

### Ställa in pragma-alternativ

[Pragma options](https://www.sqlite.org/pragma.html) kan ställas in vid anslutning med hjälp av `init_command` i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration i [`DATABASES`](/sv/6.0/ref/settings/#std-setting-DATABASES). I exemplet nedan visas hur man aktiverar extra hållbarhet för synkrona skrivningar och ändrar `cache_size`:

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        # ...
        "OPTIONS": {
            "init_command": "PRAGMA synchronous=3; PRAGMA cache_size=2000;",
        },
    }
}
```

## Oracle anteckningar

Django stöder [Oracle Database Server](https://www.oracle.com/) version 19c och senare. Version 2.3.0 eller högre av Python-drivrutinen [oracledb](https://oracle.github.io/python-oracledb/) krävs.

För att kommandot `python manage.py migrate` ska fungera måste din Oracle-databasanvändare ha behörighet att köra följande kommandon:

- SKAPA TABELL
- SKAPA SEKVENS
- SKAPA PROCEDUR
- SKAPA TRIGGER

För att köra ett projekts testsvit behöver användaren vanligtvis dessa *ytterligare* behörigheter:

- SKAPA ANVÄNDARE
- ÄNDRAR ANVÄNDARE
- DROP ANVÄNDARE
- SKAPA TABLESPACE
- SLÄPP TABLESPACE
- SKAPA SESSION MED ADMINISTRATÖRSALTERNATIV
- SKAPA TABELL MED ADMINISTRATÖRSALTERNATIV
- SKAPA SEKVENS MED ADMINISTRATÖRSALTERNATIV
- SKAPA PROCEDUR MED ADMINISTRATÖRSALTERNATIV
- SKAPA TRIGGER MED ADMINISTRATÖRSALTERNATIV

Även om rollen `RESOURCE` har de nödvändiga behörigheterna `CREATE TABLE`, `CREATE SEQUENCE`, `CREATE PROCEDURE` och `CREATE TRIGGER` och en användare som tilldelats `RESOURCE WITH ADMIN OPTION` kan tilldela `RESOURCE`, kan en sådan användare inte tilldela de enskilda behörigheterna (t.ex.t.ex. `CREATE TABLE`), och därför är `RESOURCE WITH ADMIN OPTION` vanligtvis inte tillräckligt för att köra tester.

Vissa testsviter skapar också vyer eller materialiserade vyer; för att köra dessa behöver användaren också behörigheterna `CREATE VIEW WITH ADMIN OPTION` och `CREATE MATERIALIZED VIEW WITH ADMIN OPTION`. I synnerhet behövs detta för Djangos egen testsvit.

Alla dessa behörigheter ingår i DBA-rollen, som är lämplig att använda i en privat utvecklares databas.

Oracle-databasens backend använder paketen `SYS.DBMS_LOB` och `SYS.DBMS_RANDOM`, så din användare kommer att behöva exekveringsbehörighet för det. Det är normalt tillgängligt för alla användare som standard, men om det inte är det måste du ge behörigheter på följande sätt:

```sql
GRANT EXECUTE ON SYS.DBMS_LOB TO user;
GRANT EXECUTE ON SYS.DBMS_RANDOM TO user;
```

### Anslutning till databasen

Om du vill ansluta med hjälp av servicenamnet för din Oracle-databas ska filen `settings.py` se ut ungefär så här:

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.oracle",
        "NAME": "xe",
        "USER": "a_user",
        "PASSWORD": "a_password",
        "HOST": "",
        "PORT": "",
    }
}
```

I det här fallet bör du lämna både [`HOST`](/sv/6.0/ref/settings/#std-setting-HOST) och [`PORT`](/sv/6.0/ref/settings/#std-setting-PORT) tomma. Om du däremot inte använder filen `tnsnames.ora` eller någon liknande namngivningsmetod och vill ansluta med hjälp av SID (”xe” i det här exemplet), fyller du i både [`HOST`](/sv/6.0/ref/settings/#std-setting-HOST) och [`PORT`](/sv/6.0/ref/settings/#std-setting-PORT) på följande sätt:

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.oracle",
        "NAME": "xe",
        "USER": "a_user",
        "PASSWORD": "a_password",
        "HOST": "dbprod01ned.mycompany.com",
        "PORT": "1540",
    }
}
```

Du bör antingen ange både [`HOST`](/sv/6.0/ref/settings/#std-setting-HOST) och [`PORT`](/sv/6.0/ref/settings/#std-setting-PORT), eller lämna båda som tomma strängar. Django kommer att använda en annan connect descriptor beroende på detta val.

#### Fullständig DSN och Easy Connect

En fullständig DSN- eller Easy Connect-sträng kan användas i [`NAME`](/sv/6.0/ref/settings/#std-setting-NAME) om både [`HOST`](/sv/6.0/ref/settings/#std-setting-HOST) och [`PORT`](/sv/6.0/ref/settings/#std-setting-PORT) är tomma. Det här formatet krävs när du använder RAC eller pluggbara databaser utan `tnsnames.ora`, till exempel.

Exempel på en Easy Connect-sträng:

```
"NAME": "localhost:1521/orclpdb1"
```

Exempel på en fullständig DSN-sträng:

```
"NAME": (
    "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))"
    "(CONNECT_DATA=(SERVICE_NAME=orclpdb1)))"
)
```

### Anslutningspool

> **New in Django 5.2**

För att använda en anslutningspool med [oracledb](https://oracle.github.io/python-oracledb/), sätt `"pool"` till `True` i [`OPTIONS`](/sv/6.0/ref/settings/#std-setting-OPTIONS)-delen av din databaskonfiguration. Detta använder drivrutinens [create\_pool()](https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-pooling) standardvärden:

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.oracle",
        # ...
        "OPTIONS": {
            "pool": True,
        },
    },
}
```

För att skicka anpassade parametrar till drivrutinens funktion [create\_pool()](https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-pooling) kan du alternativt ange att `"pool"` ska vara en dict:

```
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.oracle",
        # ...
        "OPTIONS": {
            "pool": {
                "min": 1,
                "max": 10,
                # ...
            }
        },
    },
}
```

### INFOGA … ÅTERVÄNDANDE TILL

By default, the Oracle backend uses a `RETURNING INTO` clause to efficiently
retrieve the value of an `AutoField` when inserting new rows. This behavior
may result in a `DatabaseError` in certain unusual setups, such as when
inserting into a remote table, or into a view with an `INSTEAD OF` trigger.
The `RETURNING INTO` clause can be disabled by setting the
`use_returning_into` option of the database configuration to `False`:

```
"OPTIONS": {
    "use_returning_into": False,
}
```

I det här fallet kommer Oracle-backend att använda en separat `SELECT`-fråga för att hämta `AutoField`-värden.

### Problem med namngivning

Oracle har en begränsning på 30 tecken för namnlängden. För att tillgodose detta trunkerar backend databasidentifierare så att de passar och ersätter de sista fyra tecknen i det trunkerade namnet med ett upprepningsbart MD5-hashvärde. Dessutom ändrar backend databasidentifierare till enbart versaler.

För att förhindra dessa omvandlingar (detta krävs vanligtvis endast när man arbetar med äldre databaser eller har åtkomst till tabeller som tillhör andra användare), använd ett citerat namn som värde för `db_table`:

```
class LegacyModel(models.Model):
    class Meta:
        db_table = '"name_left_in_lowercase"'

class ForeignModel(models.Model):
    class Meta:
        db_table = '"OTHER_USER"."NAME_ONLY_SEEMS_OVER_30"'
```

Citerade namn kan också användas med Djangos andra stödda databasbackends; med undantag för Oracle har citaten dock ingen effekt.

When running `migrate`, 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 och tomma strängar

Django föredrar i allmänhet att använda den tomma strängen (`''`) i stället för `NULL`, men Oracle behandlar båda identiskt. För att komma runt detta ignorerar Oracle-backend ett explicit `null`-alternativ på fält som har den tomma strängen som ett möjligt värde och genererar DDL som om `null=True`. Vid hämtning från databasen antas det att ett `NULL`-värde i ett av dessa fält verkligen betyder den tomma strängen, och data konverteras tyst för att återspegla detta antagande.

### begränsningar för `TextField`

Oracles backend lagrar varje `TextField` som en `NCLOB`-kolumn. Oracle inför vissa begränsningar för användningen av sådana LOB-kolumner i allmänhet:

- LOB-kolumner får inte användas som primärnycklar.
- LOB-kolumner får inte användas i index.
- LOB-kolumner får inte användas i en `SELECT DISTINCT`-lista. Detta innebär att försök att använda metoden `QuerySet.distinct` på en modell som innehåller `TextField`-kolumner kommer att resultera i ett `ORA-00932`-fel när den körs mot Oracle. Som en lösning kan du använda metoden `QuerySet.defer` tillsammans med `distinct()` för att förhindra att `TextField`-kolumner inkluderas i listan `SELECT DISTINCT`.

## Underklassning av de inbyggda databasbackends

Django comes with built-in database backends. You may subclass an existing
database backend to modify its behavior, features, or configuration.

Tänk dig till exempel att du behöver ändra en enda databasfunktion. Först måste du skapa en ny katalog med en `base`-modul i den. Ett exempel:

```text
mysite/
    ...
    mydbengine/
        __init__.py
        base.py
```

Modulen `base.py` måste innehålla en klass med namnet `DatabaseWrapper` som underklassar en befintlig motor från modulen `django.db.backends`. Här är ett exempel på underklassning av PostgreSQL-motorn för att ändra en funktionsklass `allows_group_by_selected_pks_on_model`:

*`mysite/mydbengine/base.py`*

```python
from django.db.backends.postgresql import base, features

class DatabaseFeatures(features.DatabaseFeatures):
    def allows_group_by_selected_pks_on_model(self, model):
        return True

class DatabaseWrapper(base.DatabaseWrapper):
    features_class = DatabaseFeatures
```

Slutligen måste du ange en [`DATABASE-ENGINE`](/sv/6.0/ref/settings/#std-setting-DATABASE-ENGINE) i din `settings.py`-fil:

```
DATABASES = {
    "default": {
        "ENGINE": "mydbengine",
        # ...
    },
}
```

Du kan se den aktuella listan över databasmotorer genom att titta i [django/db/backends](https://github.com/django/django/blob/stable/6.0.x/django/db/backends).

## Använda en databasbackend från tredje part

Förutom de databaser som stöds officiellt finns det backends som tillhandahålls av tredje part som gör att du kan använda andra databaser med Django:

- [CockroachDB](https://pypi.org/project/django-cockroachdb/)
- [Firebird](https://pypi.org/project/django-firebird/)
- [Google Cloud Spanner](https://pypi.org/project/django-google-spanner/)
- [Microsoft SQL Server](https://pypi.org/project/mssql-django/)
- [MongoDB](https://pypi.org/project/django-mongodb-backend/)
- [Snöflinga](https://pypi.org/project/django-snowflake/)
- [TiDB](https://pypi.org/project/django-tidb/)
- [YugabyteDB](https://pypi.org/project/django-yugabytedb/)

De Django-versioner och ORM-funktioner som stöds av dessa inofficiella backends varierar avsevärt. Frågor om de specifika funktionerna i dessa inofficiella backends, tillsammans med eventuella supportfrågor, bör riktas till de supportkanaler som tillhandahålls av varje tredjepartsprojekt.
