# Django 6.0.7 documentation

# Migreringar

Migreringar är Djangos sätt att sprida ändringar som du gör i dina modeller (lägga till ett fält, ta bort en modell etc.) till ditt databasschema. De är utformade för att vara mestadels automatiska, men du måste veta när du ska göra migreringar, när du ska köra dem och de vanliga problem du kan stöta på.

## Kommandon

Det finns flera kommandon som du kommer att använda för att interagera med migreringar och Djangos hantering av databasscheman:

- `migrate`, som ansvarar för att applicera och avapplicera migreringar.

- `makemigrations`, som ansvarar för att skapa nya migreringar baserat på de ändringar du har gjort i dina modeller.

- `sqlmigrate`, som visar SQL-satserna för en migrering.

- `showmigrations`, som listar ett projekts migreringar och deras status.

Du bör tänka på migreringar som ett versionskontrollsystem för ditt databasschema. `makemigrations` ansvarar för att paketera dina modelländringar i enskilda migreringsfiler - analogt med commits - och `migrate` ansvarar för att tillämpa dem på din databas.

Migreringsfilerna för varje app finns i en ”migrations”-katalog inuti appen och är utformade för att läggas till och distribueras som en del av dess kodbas. Du bör göra dem en gång på din utvecklingsmaskin och sedan köra samma migreringar på dina kollegors maskiner, dina staging-maskiner och så småningom dina produktionsmaskiner.

Observera

Det är möjligt att åsidosätta namnet på paketet som innehåller migreringarna för varje enskild app genom att ändra inställningen `MIGRATION_MODULES`.

Migreringar körs på samma sätt på samma dataset och ger konsekventa resultat, vilket innebär att det du ser i utveckling och staging under samma omständigheter är exakt vad som kommer att hända i produktion.

Django kommer att göra migreringar för alla ändringar av dina modeller eller fält - även alternativ som inte påverkar databasen - eftersom det enda sättet att rekonstruera ett fält korrekt är att ha alla ändringar i historiken, och du kan behöva dessa alternativ i vissa datamigreringar senare (till exempel om du har ställt in anpassade validerare).

## Support för backend

Migreringar stöds på alla backends som Django levereras med, liksom alla backends från tredje part om de har programmerat in stöd för schemaändring (görs via SchemaEditor-klassen).

Vissa databaser är dock mer kapabla än andra när det gäller schemamigreringar; några av förbehållen tas upp nedan.

### PostgreSQL

PostgreSQL är den mest kapabla av alla databaser här när det gäller schemastöd.

### MySQL

MySQL saknar stöd för transaktioner kring schemaändringsoperationer, vilket innebär att om en migrering misslyckas med att tillämpas måste du manuellt plocka bort ändringarna för att försöka igen (det är omöjligt att rulla tillbaka till en tidigare punkt).

MySQL 8.0 introducerade betydande prestandaförbättringar för DDL-operationer, vilket gör dem mer effektiva och minskar behovet av fullständiga tabellåteruppbyggnader. Det kan dock inte garantera en fullständig frånvaro av lås eller avbrott. I situationer där lås fortfarande är nödvändiga kommer varaktigheten för dessa operationer att stå i proportion till antalet rader som är inblandade.

Slutligen har MySQL en relativt liten gräns för den kombinerade storleken på alla kolumner som ett index täcker. Detta innebär att index som är möjliga på andra backends inte kommer att kunna skapas under MySQL.

### SQLite

SQLite har mycket lite inbyggt stöd för schemaändring, och därför försöker Django emulera det genom att:

- Skapa en ny tabell med det nya schemat

- Kopiering av data över

- Ta bort det gamla bordet

- Byt namn på den nya tabellen så att den matchar det ursprungliga namnet

Den här processen fungerar i allmänhet bra, men den kan vara långsam och ibland buggig. Det rekommenderas inte att du kör och migrerar SQLite i en produktionsmiljö om du inte är mycket medveten om riskerna och dess begränsningar; det stöd som Django levereras med är utformat för att tillåta utvecklare att använda SQLite på sina lokala maskiner för att utveckla mindre komplexa Django-projekt utan behov av en fullständig databas.

## Arbetsflöde

Django kan skapa migreringar åt dig. Gör ändringar i dina modeller - lägg till exempel till ett fält och ta bort en modell - och kör sedan `makemigrations`:

    $ python manage.py makemigrations
    Migrations for 'books':
      books/migrations/0003_auto.py:
        ~ Alter field author on book

Dina modeller kommer att skannas och jämföras med de versioner som för närvarande finns i dina migreringsfiler, och sedan kommer en ny uppsättning migreringar att skrivas ut. Se till att läsa utdata för att se vad `makemigrations` tror att du har ändrat - den är inte perfekt, och för komplexa ändringar kanske den inte upptäcker vad du förväntar dig.

När du har dina nya migreringsfiler bör du tillämpa dem på din databas för att se till att de fungerar som förväntat:

    $ python manage.py migrate
    Operations to perform:
      Apply all migrations: books
    Running migrations:
      Applying books.0003_auto... OK

När migreringen har tillämpats ska du överföra migreringen och modelländringen till ditt versionshanteringssystem som en enda överföring - på så sätt får andra utvecklare (eller dina produktionsservrar) både ändringarna i dina modeller och den åtföljande migreringen samtidigt när de kontrollerar koden.

Om du vill ge migreringarna ett meningsfullt namn i stället för ett genererat namn kan du använda alternativet `makemigrations --name`:

    $ python manage.py makemigrations --name changed_my_model your_app_label

### Versionskontroll

Eftersom migreringar lagras i versionshanteringen kan du ibland stöta på situationer där du och en annan utvecklare har genomfört en migrering till samma app samtidigt, vilket resulterar i två migreringar med samma nummer.

Oroa dig inte - siffrorna är bara där för utvecklarnas referens, Django bryr sig bara om att varje migrering har ett annat namn. Migreringar anger vilka andra migreringar de är beroende av - inklusive tidigare migreringar i samma app - i filen, så det är möjligt att upptäcka när det finns två nya migreringar för samma app som inte är ordnade.

När detta händer kommer Django att fråga dig och ge dig några alternativ. Om det tycker att det är tillräckligt säkert kommer det att erbjuda att automatiskt linearisera de två migreringarna åt dig. Om inte, måste du gå in och modifiera migreringarna själv - oroa dig inte, det är inte svårt och förklaras mer i Migreringsfiler nedan.

## Transaktioner

På databaser som stöder DDL-transaktioner (SQLite och PostgreSQL) kommer alla migreringsoperationer att köras i en enda transaktion som standard. Om en databas däremot inte stöder DDL-transaktioner (t.ex. MySQL, Oracle) kommer alla operationer att köras utan en transaktion.

Du kan förhindra att en migrering körs i en transaktion genom att ställa in attributet `atomic` till `False`. Till exempel:

    from django.db import migrations

    class Migration(migrations.Migration):
        atomic = False

It’s also possible to execute parts of the migration inside a transaction using `atomic()` or by passing `atomic=True` to `RunPython`. See Icke-atomiska migreringar for more details.

## Beroenden

Även om migreringar sker per app är tabellerna och relationerna i dina modeller för komplexa för att skapas för en app i taget. När du gör en migrering som kräver att något annat körs - till exempel om du lägger till en `ForeignKey` i appen `books` till appen `authors` - kommer den resulterande migreringen att innehålla ett beroende av en migrering i `authors`.

Detta innebär att när du kör migreringarna körs `authors`-migreringen först och skapar tabellen som `ForeignKey` refererar till, och sedan körs migreringen som skapar `ForeignKey`-kolumnen efteråt och skapar begränsningen. Om detta inte hände skulle migreringen försöka skapa kolumnen `ForeignKey` utan att tabellen som den hänvisar till existerar och din databas skulle ge ett fel.

Detta beroendebeteende påverkar de flesta migreringar där du begränsar till en enda app. Att begränsa till en enda app (antingen i `makemigrations` eller `migrate`) är ett löfte om bästa möjliga ansträngning och inte en garanti; alla andra appar som behöver användas för att få beroenden korrekta kommer att bli det.

Appar utan migreringar får inte ha relationer (`ForeignKey`, `ManyToManyField`, etc.) till appar med migreringar. Ibland kan det fungera, men det stöds inte.

### Utbytbara beroenden

django.db.migrations.swappable_dependency(value)

Funktionen `swappable_dependency()` används i migreringar för att deklarera ”swappable” beroenden av migreringar i appen för den inbytta modellen, för närvarande vid den första migreringen av denna app. Som en följd av detta bör den inbytta modellen skapas i den första migreringen. Argumentet `value` är en sträng `"<app label>.<model>"` som beskriver en appetikett och ett modellnamn, t.ex. `"myapp.MyModel"`.

Genom att använda `swappable_dependency()` informerar du migreringsramverket om att migreringen är beroende av en annan migrering som skapar en swappable-modell, vilket ger möjlighet att ersätta modellen med en annan implementering i framtiden. Detta används vanligtvis för att referera till modeller som är föremål för anpassning eller ersättning, till exempel den anpassade användarmodellen (`settings.AUTH_USER_MODEL`, som standard är `"auth.User"`) i Djangos autentiseringssystem.

## Migreringsfiler

Migreringar lagras i ett diskformat som här kallas ”migreringsfiler”. Dessa filer är egentligen vanliga Python-filer med en överenskommen objektlayout, skrivna i en deklarativ stil.

En grundläggande migreringsfil ser ut så här:

    from django.db import migrations, models

    class Migration(migrations.Migration):
        dependencies = [("migrations", "0001_initial")]

        operations = [
            migrations.DeleteModel("Tribble"),
            migrations.AddField("Author", "rating", models.IntegerField(default=0)),
        ]

Vad Django letar efter när den laddar en migreringsfil (som en Python-modul) är en underklass av `django.db.migrations.Migration` som heter `Migration`. Det inspekterar sedan detta objekt för fyra attribut, varav endast två används för det mesta:

- `dependencies`, en lista över migreringar som den här beror på.

- `operations`, en lista över `Operation`-klasser som definierar vad denna migrering gör.

Operationerna är nyckeln; de är en uppsättning deklarativa instruktioner som talar om för Django vilka schemaändringar som behöver göras. Django skannar dem och bygger en representation i minnet av alla schemaändringar för alla appar och använder detta för att generera SQL som gör schemaändringarna.

Den minnesstrukturen används också för att ta reda på vad skillnaderna är mellan dina modeller och det aktuella läget för dina migreringar; Django kör igenom alla ändringar, i ordning, på en minnesuppsättning av modeller för att komma fram till läget för dina modeller förra gången du körde `makemigrations`. Den använder sedan dessa modeller för att jämföra med dem i dina `models.py`-filer för att räkna ut vad du har ändrat.

Du behöver sällan eller aldrig redigera migreringsfiler för hand, men det är fullt möjligt att skriva dem manuellt om du behöver. Vissa av de mer komplexa operationerna kan inte autodetekteras och är endast tillgängliga via en handskriven migrering, så var inte rädd för att redigera dem om du måste.

### Anpassade fält

Du kan inte ändra antalet positionella argument i ett redan migrerat anpassat fält utan att det uppstår ett `TypeError`. Den gamla migreringen kommer att anropa den modifierade metoden `__init__` med den gamla signaturen. Så om du behöver ett nytt argument, skapa ett nyckelordsargument och lägg till något i stil med `assert 'argument_name' in kwargs` i konstruktören.

### Modell chefer

Du kan valfritt serialisera chefer till migreringar och ha dem tillgängliga i `RunPython`-operationer. Detta görs genom att definiera ett `use_in_migrations`-attribut på managerklassen:

    class MyManager(models.Manager):
        use_in_migrations = True

    class MyModel(models.Model):
        objects = MyManager()

Om du använder funktionen `from_queryset()` för att dynamiskt generera en managerklass måste du ärva från den genererade klassen för att göra den importerbar:

    class MyManager(MyBaseManager.from_queryset(CustomQuerySet)):
        use_in_migrations = True

    class MyModel(models.Model):
        objects = MyManager()

Se anteckningarna om Historiska modeller i migreringar för att se vilka konsekvenser som följer med.

### Inledande migreringar

Migration.initial

De ”initiala migreringarna” för en app är de migreringar som skapar den första versionen av appens tabeller. Vanligtvis har en app en första migrering, men i vissa fall med komplexa modellberoenden kan den ha två eller fler.

Initiala migreringar markeras med ett klassattribut `initial = True` på migreringsklassen. Om klassattributet `initial` inte hittas betraktas en migrering som ”initial” om den är den första migreringen i appen (dvs. om den inte har några beroenden till någon annan migrering i samma app).

När alternativet `migrate --fake-initial` används, behandlas dessa initiala migreringar speciellt. För en initial migrering som skapar en eller flera tabeller (`CreateModel` operation), kontrollerar Django att alla dessa tabeller redan finns i databasen och tillämpar migreringen om så är fallet. På samma sätt, för en initial migrering som lägger till ett eller flera fält (`AddField` operation), kontrollerar Django att alla respektive kolumner redan finns i databasen och fejkapplicerar migreringen om så är fallet. Utan `--fake-initial` behandlas initiala migreringar inte annorlunda än någon annan migrering.

### Historisk konsekvens

Som tidigare nämnts kan du behöva linjärisera migreringar manuellt när två utvecklingsgrenar sammanfogas. När du redigerar migreringsberoenden kan du oavsiktligt skapa ett inkonsekvent historiktillstånd där en migrering har tillämpats men vissa av dess beroenden inte har gjort det. Detta är en stark indikation på att beroendena är felaktiga, så Django kommer att vägra att köra migreringar eller göra nya migreringar tills det är åtgärdat. När du använder flera databaser kan du använda metoden `allow_migrate()` i database routers för att kontrollera vilka databaser som `makemigrations` kontrollerar för konsekvent historik.

## Lägga till migreringar i appar

Nya appar är förkonfigurerade för att acceptera migreringar, så du kan lägga till migreringar genom att köra `makemigrations` när du har gjort några ändringar.

Om din app redan har modeller och databastabeller och inte har migreringar ännu (till exempel om du skapade den mot en tidigare Django-version) måste du konvertera den till att använda migreringar genom att köra:

    $ python manage.py makemigrations your_app_label

Detta kommer att skapa en ny initial migrering för din app. Kör nu `python manage.py migrate --fake-initial`, och Django kommer att upptäcka att du har en initial migrering och att de tabeller som den vill skapa redan finns, och kommer att markera migreringen som redan tillämpad. (Utan `migrate --fake-initial` flaggan skulle kommandot misslyckas eftersom tabellerna som den vill skapa redan existerar)

Observera att detta bara fungerar under förutsättning att två saker inträffar:

- Du har inte ändrat dina modeller sedan du skapade deras tabeller. För att migreringar ska fungera måste du göra den första migreringen först och sedan göra ändringar, eftersom Django jämför ändringar mot migreringsfiler, inte databasen.

- Du har inte redigerat din databas manuellt - Django kommer inte att kunna upptäcka att din databas inte matchar dina modeller, du kommer bara att få fel när migreringar försöker ändra dessa tabeller.

## Återvändande av migration

Migreringar kan återställas med `migrate` genom att ange numret på den föregående migreringen. Till exempel, för att vända migreringen `books.0003`:

/ 

    $ python manage.py migrate books 0002
    Operations to perform:
      Target specific migration: 0002_auto, from books
    Running migrations:
      Rendering model states... DONE
      Unapplying books.0003_auto... OK

    ...\> py manage.py migrate books 0002
    Operations to perform:
      Target specific migration: 0002_auto, from books
    Running migrations:
      Rendering model states... DONE
      Unapplying books.0003_auto... OK

Använd namnet `zero` om du vill återkalla alla migreringar som gjorts för en app:

/ 

    $ python manage.py migrate books zero
    Operations to perform:
      Unapply all migrations: books
    Running migrations:
      Rendering model states... DONE
      Unapplying books.0002_auto... OK
      Unapplying books.0001_initial... OK

    ...\> py manage.py migrate books zero
    Operations to perform:
      Unapply all migrations: books
    Running migrations:
      Rendering model states... DONE
      Unapplying books.0002_auto... OK
      Unapplying books.0001_initial... OK

En migrering är irreversibel om den innehåller några irreversibla åtgärder. Försök att vända sådana migreringar kommer att ge upphov till `IrreversibleError`:

/ 

    $ python manage.py migrate books 0002
    Operations to perform:
      Target specific migration: 0002_auto, from books
    Running migrations:
      Rendering model states... DONE
      Unapplying books.0003_auto...Traceback (most recent call last):
    django.db.migrations.exceptions.IrreversibleError: Operation <RunSQL  sql='DROP TABLE demo_books'> in books.0003_auto is not reversible

    ...\> py manage.py migrate books 0002
    Operations to perform:
      Target specific migration: 0002_auto, from books
    Running migrations:
      Rendering model states... DONE
      Unapplying books.0003_auto...Traceback (most recent call last):
    django.db.migrations.exceptions.IrreversibleError: Operation <RunSQL  sql='DROP TABLE demo_books'> in books.0003_auto is not reversible

## Historiska modeller

När du kör migreringar arbetar Django från historiska versioner av dina modeller som lagras i migreringsfilerna. Om du skriver Python-kod med hjälp av `RunPython`, eller om du har `allow_migrate`-metoder på dina databasroutrar, måste du använda dessa historiska modellversioner istället för att importera dem direkt.

Varning

Om du importerar modeller direkt i stället för att använda de historiska modellerna kan dina migreringar fungera initialt, men de kommer att misslyckas i framtiden när du försöker köra gamla migreringar igen (vanligtvis när du skapar en ny installation och kör igenom alla migreringar för att skapa databasen).

Detta innebär att problem med historiska modeller kanske inte är omedelbart uppenbara. Om du stöter på den här typen av fel är det OK att redigera migreringen så att den använder de historiska modellerna i stället för direktimport och genomföra dessa ändringar.

Eftersom det är omöjligt att serialisera godtycklig Python-kod kommer dessa historiska modeller inte att ha några anpassade metoder som du har definierat. De kommer dock att ha samma fält, relationer, chefer (begränsat till dem med `use_in_migrations = True`) och `Meta`-alternativ (även versionerade, så de kan skilja sig från dina nuvarande).

Varning

Detta innebär att du INTE kommer att ha anpassade `save()`-metoder som anropas på objekt när du kommer åt dem i migreringar, och du kommer INTE att ha några anpassade konstruktörer eller instansmetoder. Planera på lämpligt sätt!

Hänvisningar till funktioner i fältalternativ som `upload_to` och `limit_choices_to` och modellhanterardeklarationer med hanterare som har `use_in_migrations = True` serialiseras i migreringar, så funktionerna och klasserna måste sparas så länge det finns en migrering som hänvisar till dem. Eventuella custom model fields måste också sparas, eftersom dessa importeras direkt av migreringar.

Dessutom lagras modellens konkreta basklasser som pekare, så du måste alltid ha kvar basklasserna så länge det finns en migration som innehåller en referens till dem. På plussidan är att metoder och managers från dessa basklasser ärvs normalt, så om man absolut behöver tillgång till dessa kan man välja att flytta dem till en superklass.

För att ta bort gamla referenser kan du squash migrations eller, om det inte finns så många referenser, kopiera dem till migreringsfilerna.

## Överväganden vid borttagning av modellfält

På samma sätt som när det gäller ”referenser till historiska funktioner” i föregående avsnitt kan det uppstå problem om du tar bort anpassade modellfält från ditt projekt eller din tredjepartsapp om de refereras till i gamla migreringar.

För att hjälpa till med den här situationen tillhandahåller Django några modellfältsattribut för att hjälpa till med borttagning av modellfält med hjälp av systemets ramverk för kontroller.

Lägg till attributet `system_check_deprecated_details` till ditt modellfält på följande sätt:

    class IPAddressField(Field):
        system_check_deprecated_details = {
            "msg": (
                "IPAddressField has been deprecated. Support for it (except "
                "in historical migrations) will be removed in Django 1.9."
            ),
            "hint": "Use GenericIPAddressField instead.",  # optional
            "id": "fields.W900",  # pick a unique ID for your field.
        }

Efter en utfasningsperiod som du väljer (två eller tre funktionsutgåvor för fält i Django själv), ändra attributet `system_check_deprecated_details` till `system_check_removed_details` och uppdatera ordlistan på liknande sätt:

    class IPAddressField(Field):
        system_check_removed_details = {
            "msg": (
                "IPAddressField has been removed except for support in "
                "historical migrations."
            ),
            "hint": "Use GenericIPAddressField instead.",
            "id": "fields.E900",  # pick a unique ID for your field.
        }

Du bör behålla fältets metoder som krävs för att det ska fungera i databasmigreringar, t.ex. `__init__()`, `deconstruct()` och `get_internal_type()`. Behåll detta stubbfält så länge som de migreringar som refererar till fältet existerar. Till exempel, efter att ha krossat migreringar och tagit bort de gamla, bör du kunna ta bort fältet helt och hållet.

## Migrering av data

Förutom att ändra databasschemat kan du också använda migreringar för att ändra data i själva databasen, i kombination med schemat om du vill.

Migreringar som ändrar data kallas vanligtvis ”datamigreringar”; det är bäst att skriva dem som separata migreringar vid sidan av dina schemamigreringar.

Django kan inte automatiskt generera datamigreringar åt dig, som det gör med schemamigreringar, men det är inte särskilt svårt att skriva dem. Migreringsfiler i Django består av Operations, och den huvudsakliga operationen du använder för datamigreringar är `RunPython`.

Börja med att skapa en tom migreringsfil som du kan arbeta utifrån (Django placerar filen på rätt plats, föreslår ett namn och lägger till beroenden åt dig):

    python manage.py makemigrations --empty yourappname

Öppna sedan filen; den ska se ut ungefär så här:

    # Generated by Django A.B on YYYY-MM-DD HH:MM
    from django.db import migrations

    class Migration(migrations.Migration):
        dependencies = [
            ("yourappname", "0001_initial"),
        ]

        operations = []

Now, all you need to do is create a new function and have `RunPython` use it. `RunPython` expects a callable as its argument which takes two arguments - the first is an app registry that has the historical versions of all your models loaded into it to match where in your history the migration sits, and the second is a SchemaEditor, which you can use to manually effect database schema changes (but beware, doing this can confuse the migration autodetector).

Låt oss skriva en migrering som fyller vårt nya fält `name` med de kombinerade värdena för `first_name` och `last_name` (vi har tagit vårt förnuft till fånga och insett att alla inte har för- och efternamn). Allt vi behöver göra är att använda den historiska modellen och iterera över raderna:

    from django.db import migrations

    def combine_names(apps, schema_editor):
        # We can't import the Person model directly as it may be a newer
        # version than this migration expects. We use the historical version.
        Person = apps.get_model("yourappname", "Person")
        for person in Person.objects.all():
            person.name = f"{person.first_name} {person.last_name}"
            person.save()

    class Migration(migrations.Migration):
        dependencies = [
            ("yourappname", "0001_initial"),
        ]

        operations = [
            migrations.RunPython(combine_names),
        ]

När det är gjort kan vi köra `python manage.py migrate` som vanligt och datamigreringen kommer att köras på plats tillsammans med andra migreringar.

Du kan skicka en andra callable till `RunPython` för att köra den logik du vill ska köras när du migrerar bakåt. Om denna callable utelämnas kommer migreringen bakåt att ge upphov till ett undantag.

### Åtkomst till modeller från andra appar

När du skriver en `RunPython`-funktion som använder modeller från andra appar än den där migreringen finns, bör migreringens `dependencies`-attribut innehålla den senaste migreringen av varje app som är inblandad, annars kan du få ett fel som liknar: `LookupError: No installed app with label 'myappname'` när du försöker hämta modellen i `RunPython`-funktionen med hjälp av `apps.get_model()`.

I följande exempel har vi en migrering i `app1` som behöver använda modeller i `app2`. Vi bryr oss inte om detaljerna i `move_m1` annat än att den kommer att behöva komma åt modeller från båda apparna. Därför har vi lagt till ett beroende som anger den senaste migreringen av `app2`:

    class Migration(migrations.Migration):
        dependencies = [
            ("app1", "0001_initial"),
            # added dependency to enable using models from app2 in move_m1
            ("app2", "0004_foobar"),
        ]

        operations = [
            migrations.RunPython(move_m1),
        ]

### Mer avancerade migreringar

Om du är intresserad av de mer avancerade migreringsoperationerna eller vill kunna skriva dina egna, se migration operations reference och ”how-to” på writing migrations.

## Minska antalet migreringar

Du uppmuntras att göra migreringar fritt och inte oroa dig för hur många du har; migreringskoden är optimerad för att hantera hundratals åt gången utan större nedgång. Men så småningom kommer du att vilja gå tillbaka från att ha flera hundra migreringar till bara några få, och det är där squashing kommer in i bilden.

Squashing innebär att man reducerar en befintlig uppsättning med många migreringar till en (eller ibland ett fåtal) migreringar som fortfarande representerar samma ändringar.

Django gör detta genom att ta alla dina befintliga migreringar, extrahera deras `Operation` och sätta dem alla i ordning, och sedan köra en optimerare över dem för att försöka minska längden på listan - till exempel vet den att `CreateModel` och `DeleteModel` upphäver varandra, och den vet att `AddField` kan rullas in i `CreateModel`.

När operationssekvensen har reducerats så mycket som möjligt - hur mycket som är möjligt beror på hur nära sammanflätade dina modeller är och om du har några `RunSQL` eller `RunPython` operationer (som inte kan optimeras om de inte är markerade som `elidable`) - kommer Django sedan att skriva ut det igen i en ny uppsättning migreringsfiler.

These files are marked to say they replace the previously-squashed migrations, so they can coexist with the old migration files, and Django will intelligently switch between them depending on where you are in the history. If you’re still part-way through the set of migrations that you squashed, it will keep using them until it hits the end and then switch to the squashed history, while new installs will use the new squashed migration and skip all the old ones.

Detta gör att du kan göra en squash och inte förstöra system som för närvarande är i produktion och som inte är helt uppdaterade ännu. Den rekommenderade processen är att krossa, behålla de gamla filerna, commita och släppa, vänta tills alla system är uppgraderade med den nya versionen (eller om du är ett tredjepartsprojekt, se till att dina användare uppgraderar versioner i ordning utan att hoppa över någon), och sedan ta bort de gamla filerna, commita och göra en andra version.

Kommandot som ligger bakom allt detta är `squashmigrations` - skicka appens etikett och migreringsnamnet som du vill squasha upp till, så börjar det arbeta:

    $ ./manage.py squashmigrations myapp 0004
    Will squash the following migrations:
     - 0001_initial
     - 0002_some_change
     - 0003_another_change
     - 0004_undo_something
    Do you wish to proceed? [y/N] y
    Optimizing...
      Optimized from 12 operations to 7 operations.
    Created new squashed migration /home/andrew/Programs/DjangoTest/test/migrations/0001_squashed_0004_undo_something.py
      You should commit this migration but leave the old ones in place;
      the new migration will be used for new installs. Once you are sure
      all instances of the codebase have applied the migrations you squashed,
      you can delete them.

Använd alternativet `squashmigrations --squashed-name` om du vill ange namnet på den krossade migreringen i stället för att använda ett autogenererat namn.

Observera att modellberoenden i Django kan bli mycket komplexa, och squashing kan resultera i migreringar som inte körs; antingen feloptimerade (i vilket fall du kan försöka igen med `--no-optimize`, men du bör också rapportera ett problem), eller med ett `CircularDependencyError`, i vilket fall du kan lösa det manuellt.

För att manuellt lösa ett `CircularDependencyError`, bryt ut en av ForeignKeys i den cirkulära beroendeslingan till en separat migrering och flytta beroendet av den andra appen med den. Om du är osäker kan du se hur `makemigrations` hanterar problemet när den ombeds skapa helt nya migreringar från dina modeller. I en framtida version av Django kommer `squashmigrations` att uppdateras för att försöka lösa dessa fel själv.

När du har krossat din migrering bör du sedan överföra den tillsammans med de migreringar som den ersätter och distribuera denna ändring till alla körande instanser av din applikation och se till att de kör `migrate` för att lagra ändringen i sin databas.

You can then transition the squashed migration to a normal migration by:

- Raderar alla migreringsfiler som den ersätter.

- Uppdaterar alla migreringar som är beroende av de borttagna migreringarna så att de istället är beroende av den krossade migreringen.

- Ta bort attributet `replaces` i klassen `Migration` för den krossade migreringen (det är så Django berättar att det är en krossad migrering).

Observera

You can squash squashed migrations themselves without transitioning to normal migrations, which might be useful for situations where every environment has not yet run the original squashed migration set. But in general it is better to transition squashed migrations to normal migrations to be able to clean up older migration files.

Rensning av referenser till raderade migreringar

Om det är troligt att du kommer att återanvända namnet på en borttagen migrering i framtiden bör du ta bort referenser till den från Djangos migreringstabell med alternativet `migrate --prune`.

Changed in Django 6.0:

Support for squashing squashed migrations was added.

## Serialisering av värden

Migrationer är Python-filer som innehåller de gamla definitionerna av dina modeller - för att skriva dem måste Django alltså ta det aktuella tillståndet för dina modeller och serialisera dem till en fil.

Django kan serialisera det mesta, men det finns vissa saker som vi helt enkelt inte kan serialisera ut till en giltig Python-representation - det finns ingen Python-standard för hur ett värde kan omvandlas tillbaka till kod (`repr()` fungerar bara för grundläggande värden och anger inte importvägar).

Django kan serialisera följande:

- `int`, `float`, `bool`, `str`, `bytes`, `None`, `NoneType`

- `list`, `set`, `tuple`, `dict`, `range`

- instanser av `datetime.date`, `datetime.time` och `datetime.datetime` (inklusive de som är tidszonmedvetna)

- `zoneinfo.ZoneInfo` instances

- `decimal.Decimal` instanser

- instanser av `enum.Enum` och `enum.Flag`

- `uuid.UUID` instanser

- `functools.partial()` and `functools.partialmethod` instances which have serializable `func`, `args`, and `keywords` values

- Pure and concrete path objects from `pathlib`. Concrete paths are converted to their pure path equivalent, e.g. `pathlib.PosixPath` to `pathlib.PurePosixPath`

- `os.PathLike` instances, e.g. `os.DirEntry`, which are converted to `str` or `bytes` using `os.fspath()`

- `LazyObject` instances which wrap a serializable value

- Enumeration types (e.g. `TextChoices` or `IntegerChoices`) instances

- Alla Django-fält

- Alla funktions- eller metodreferenser (t.ex. `datetime.datetime.today`) (måste finnas i modulens toppnivå)

  - Funktioner kan dekoreras om de förpackas på rätt sätt, dvs. med `functools.wraps()`

  - Dekoratorerna `functools.cache()` och `functools.lru_cache()` stöds uttryckligen

- Obundna metoder som används inom klassens kropp

- Vilken klassreferens som helst (måste finnas i modulens toppnivåscope)

- Allt med en anpassad `deconstruct()`-metod (se nedan)

Changed in Django 6.0:

Serialization support for `zoneinfo.ZoneInfo` instances was added.

Django kan inte serialisera:

- Nästlade klasser

- Godtyckliga klassinstanser (t.ex. `MyClass(4.3, 5.7)`)

- Lambdas

### Anpassade serialiserare

Du kan serialisera andra typer genom att skriva en anpassad serializer. Till exempel, om Django inte serialiserade `Decimal` som standard, skulle du kunna göra så här:

    from decimal import Decimal

    from django.db.migrations.serializer import BaseSerializer
    from django.db.migrations.writer import MigrationWriter

    class DecimalSerializer(BaseSerializer):
        def serialize(self):
            return repr(self.value), {"from decimal import Decimal"}

    MigrationWriter.register_serializer(Decimal, DecimalSerializer)

Det första argumentet i `MigrationWriter.register_serializer()` är en typ eller en iterabel av typer som ska använda serializer.

Metoden `serialize()` i din serializer måste returnera en sträng som visar hur värdet ska visas i migreringar och en uppsättning av alla importer som behövs i migreringen.

### Lägga till en `deconstruct()`-metod

Du kan låta Django serialisera dina egna anpassade klassinstanser genom att ge klassen en `deconstruct()`-metod. Den tar inga argument och bör returnera en tupel av tre saker `(path, args, kwargs)`:

- `path` bör vara Python-sökvägen till klassen, med klassnamnet inkluderat som sista del (t.ex. `myapp.custom_things.MyClass`). Om din klass inte är tillgänglig på den översta nivån i en modul är den inte serialiserbar.

- `args` ska vara en lista med positionella argument som ska skickas till din klass `__init__` metod. Allt i denna lista bör i sig vara serialiserbart.

- `kwargs` bör vara en dikt av nyckelordsargument att skicka till din klass `__init__` metod. Varje värde bör i sig vara serialiserbart.

Observera

Detta returvärde skiljer sig från metoden `deconstruct()` for custom fields som returnerar en tupel med fyra objekt.

Django kommer att skriva ut värdet som en instansiering av din klass med de angivna argumenten, på samma sätt som det skriver ut referenser till Django-fält.

För att förhindra att en ny migrering skapas varje gång `makemigrations` körs, bör du också lägga till en `__eq__()`-metod till den dekorerade klassen. Denna funktion kommer att anropas av Djangos migreringsramverk för att upptäcka förändringar mellan tillstånd.

Så länge som alla argument till din klass konstruktör är själva serialiserbara, kan du använda `@deconstructible` klassdekoratorn från `django.utils.deconstruct` för att lägga till `deconstruct()` metoden:

    from django.utils.deconstruct import deconstructible

    @deconstructible
    class MyCustomClass:
        def __init__(self, foo=1):
            self.foo = foo
            ...

        def __eq__(self, other):
            return self.foo == other.foo

Dekoratorn lägger till logik för att fånga upp och bevara argumenten på väg in i din konstruktor och returnerar sedan dessa argument exakt när deconstruct() anropas.

## Stöd för flera Django-versioner

Om du är underhållare av en tredjepartsapp med modeller kan du behöva skicka migreringar som stöder flera Django-versioner. I så fall bör du alltid köra `makemigrations` med den lägsta Django-versionen som du vill stödja.

Migreringssystemet kommer att upprätthålla bakåtkompatibilitet enligt samma policy som resten av Django, så migreringsfiler som genererats på Django X.Y bör köras oförändrade på Django X.Y+1. Migreringssystemet lovar dock inte framåtkompatibilitet. Nya funktioner kan läggas till, och migreringsfiler som genereras med nyare versioner av Django kanske inte fungerar på äldre versioner.

Se även

Referensen för migreringsoperationer

  Omfattar API:et för schemaoperationer, specialoperationer och att skriva egna operationer.

”Hur man skriver migreringar”

  Förklarar hur man strukturerar och skriver databasmigreringar för olika scenarier som man kan stöta på.