Ricerca…


Parametri

comando di django-admin Dettagli
makemigrations <my_app> Genera migrazioni per my_app
makemigrations Genera migrazioni per tutte le app
makemigrations --merge Risolvi i conflitti di migrazione per tutte le app
makemigrations --merge <my_app> Risolvi i conflitti di migrazione per my_app
makemigrations --name <migration_name> <my_app> Genera una migrazione per my_app con il nome migration_name
migrate <my_app> Applica le migrazioni in sospeso di my_app al database
migrate Applica tutte le migrazioni in sospeso al database
migrate <my_app> <migration_name> Applica o disattiva fino a migration_name
migrate <my_app> zero Annulla l'applicazione di tutte le migrazioni in my_app
sqlmigrate <my_app> <migration_name> Stampa l'SQL per la migrazione denominata
showmigrations Mostra tutte le migrazioni per tutte le app
showmigrations <my_app> Mostra tutte le migrazioni in my_app

Lavorare con le migrazioni

Django usa le migrazioni per propagare le modifiche apportate ai tuoi modelli al tuo database. Il più delle volte django può generarli per te.

Per creare una migrazione, esegui:

$ django-admin makemigrations <app_name>

Questo creerà un file di migrazione nel sottomodulo di migration di app_name . La prima migrazione sarà denominata 0001_initial.py , l'altra inizierà con 0002_ , quindi 0003 , ...

Se ometti <app_name> questo creerà le migrazioni per tutti i tuoi INSTALLED_APPS .

Per propagare le migrazioni al tuo database, esegui:

$ django-admin migrate <app_name>

Per mostrare tutte le tue migrazioni, esegui:

$ django-admin showmigrations app_name
app_name
  [X] 0001_initial
  [X] 0002_auto_20160115_1027
  [X] 0003_somemodel
  [ ] 0004_auto_20160323_1826
  • [X] significa che la migrazione è stata propagata al tuo database
  • [ ] significa che la migrazione non è stata propagata al tuo database. Usa la django-admin migrate di django-admin migrate per propagarlo

Chiama anche ripristinare le migrazioni, questo può essere fatto passando il nome della migrate command . Dato l'elenco di migrazioni di cui sopra (mostrato da django-admin showmigrations ):

$ django-admin migrate app_name 0002  # Roll back to migration 0002
$ django-admin showmigrations app_name
app_name
  [X] 0001_initial
  [X] 0002_auto_20160115_1027
  [ ] 0003_somemodel
  [ ] 0004_auto_20160323_1826

Migrazioni manuali

A volte, le migrazioni generate da Django non sono sufficienti. Ciò è particolarmente vero quando si desidera effettuare migrazioni di dati .

Ad esempio, disponiamo di tale modello:

class Article(models.Model):
    title = models.CharField(max_length=70)

Questo modello ha già dati esistenti e ora vuoi aggiungere uno SlugField :

class Article(models.Model):
    title = models.CharField(max_length=70)
    slug = models.SlugField(max_length=70)

Hai creato le migrazioni per aggiungere il campo, ma ora ti piacerebbe impostare lo slug per tutti gli articoli esistenti, in base al loro title .

Certo, potresti semplicemente fare qualcosa del genere nel terminale:

$ django-admin shell
>>> from my_app.models import Article
>>> from django.utils.text import slugify
>>> for article in Article.objects.all():
...     article.slug = slugify(article.title)
...     article.save()
...
>>>

Ma dovrai farlo in tutti i tuoi ambienti (ad esempio il tuo desktop dell'ufficio, il tuo laptop, ...), tutti i tuoi colleghi dovranno farlo anche tu, e dovrai pensarci su come mettere in scena e quando spingi vivere.

Per farlo una volta per tutte, lo faremo in una migrazione. Per prima cosa crea una migrazione vuota:

$ django-admin makemigrations --empty app_name

Questo creerà un file di migrazione vuoto. Aprilo, contiene uno scheletro di base. Supponiamo che la tua precedente migrazione sia stata denominata 0023_article_slug e che questa sia denominata 0024_auto_20160719_1734 . Ecco cosa scriveremo nel nostro file di migrazione:

# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-19 15:34
from __future__ import unicode_literals

from django.db import migrations
from django.utils.text import slugify


def gen_slug(apps, schema_editor):
    # We can't import the Article model directly as it may be a newer
    # version than this migration expects. We use the historical version.
    Article = apps.get_model('app_name', 'Article')
    for row in Article.objects.all():
        row.slug = slugify(row.name)
        row.save()


class Migration(migrations.Migration):

    dependencies = [
        ('hosting', '0023_article_slug'),
    ]

    operations = [
        migrations.RunPython(gen_slug, reverse_code=migrations.RunPython.noop),
        # We set `reverse_code` to `noop` because we cannot revert the migration
        # to get it back in the previous state.
        # If `reverse_code` is not given, the migration will not be reversible,
        # which is not the behaviour we expect here.
    ]

Migrazioni false

Quando viene eseguita una migrazione, Django memorizza il nome della migrazione in una tabella django_migrations.

Crea e simula le migrazioni iniziali per lo schema esistente

Se la tua app ha già modelli e tabelle di database e non ha migrazioni. Per prima cosa crea le migrazioni iniziali per la tua app.

python manage.py makemigrations your_app_label

Ora false migrazioni iniziali come applicate

python manage.py migrate --fake-initial

Fake tutte le migrazioni in tutte le app

python manage.py migrate --fake

Migrazioni di app singole false

python manage.py migrate --fake core

File di migrazione singola falso

python manage.py migrate myapp migration_name

Nomi personalizzati per i file di migrazione

Utilizzare l' makemigrations --name <your_migration_name> per consentire la denominazione delle migrazioni (s) anziché utilizzare un nome generato.

python manage.py makemigrations --name <your_migration_name> <app_name>

Risolvere i conflitti di migrazione

introduzione

A volte le migrazioni entrano in conflitto, con il risultato di rendere la migrazione non riuscita. Questo può accadere in un sacco di scenerio, tuttavia può verificarsi regolarmente durante lo sviluppo di un'app con un team.

I conflitti di migrazione comuni si verificano durante l'utilizzo del controllo del codice sorgente, soprattutto quando viene utilizzato il metodo funzione-per-ramo. Per questo scenario useremo un modello chiamato Reporter con gli attributi name e address .

Due sviluppatori a questo punto svilupperanno una funzionalità, quindi entrambi avranno questa copia iniziale del modello Reporter . Lo sviluppatore A aggiunge age che risulta nel file 0002_reporter_age.py . Lo sviluppatore B aggiunge un campo bank_account che viene 0002_reporter_bank_account in 0002_reporter_bank_account . Una volta che questi sviluppatori uniscono il loro codice e tentano di migrare le migrazioni, si è verificato un conflitto di migrazione.

Questo conflitto si verifica perché queste migrazioni modificano entrambi lo stesso modello, Reporter . Inoltre, i nuovi file iniziano entrambi con 0002.

Unione di migrazioni

Ci sono diversi modi per farlo. Quanto segue è nell'ordine consigliato:

  1. La soluzione più semplice è eseguire il comando makemigrations con un flag --merge.

    python manage.py makemigrations --merge <my_app>
    

    Questo creerà una nuova migrazione per risolvere il conflitto precedente.

  2. Quando questo file extra non è benvenuto nell'ambiente di sviluppo per motivi personali, un'opzione è quella di eliminare le migrazioni in conflitto. Quindi, è possibile eseguire una nuova migrazione utilizzando il normale comando makemigrations . Quando vengono scritte le migrazioni personalizzate, ad esempio migrations.RunPython , è necessario tenere conto dell'utilizzo di questo metodo.

Cambia un CharField in un ForeignKey

Prima di tutto, supponiamo che questo sia il tuo modello iniziale, all'interno di un'applicazione chiamata discography :

from django.db import models

class Album(models.Model):
    name = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)

Ora, ti rendi conto che vuoi usare una ForeignKey per l'artista. Questo è un processo un po 'complesso, che deve essere fatto in diversi passaggi.

Passaggio 1, aggiungere un nuovo campo per ForeignKey, assicurandosi di contrassegnarlo come null (si noti che ora è incluso anche il modello a cui stiamo collegando):

from django.db import models

class Album(models.Model):
    name = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)
    artist_link = models.ForeignKey('Artist', null=True)

class Artist(models.Model):
    name = models.CharField(max_length=255)

... e creare una migrazione per questo cambiamento.

./manage.py makemigrations discography

Passaggio 2, compilare il nuovo campo. Per fare ciò, devi creare una migrazione vuota.

./manage.py makemigrations --empty --name transfer_artists discography

Una volta che hai questa migrazione vuota, vuoi aggiungere una singola operazione RunPython ad essa per collegare i tuoi record. In questo caso, potrebbe assomigliare a questo:

def link_artists(apps, schema_editor):
    Album = apps.get_model('discography', 'Album')
    Artist = apps.get_model('discography', 'Artist')
    for album in Album.objects.all():
        artist, created = Artist.objects.get_or_create(name=album.artist)
        album.artist_link = artist
        album.save()

Ora che i tuoi dati vengono trasferiti nel nuovo campo, potresti effettivamente essere fatto e lasciare tutto come è, usando il nuovo campo artist_link per tutto. Oppure, se vuoi fare un po 'di pulizia, vuoi creare altre due migrazioni.

Per la tua prima migrazione, vorrai cancellare il tuo campo originale, artist . Per la tua seconda migrazione, rinomina il nuovo campo artist_link con l' artist .

Questo viene fatto in più passaggi per garantire che Django riconosca le operazioni correttamente.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow