Buscar..


Parámetros

comando django-admin Detalles
makemigrations <my_app> Generar migraciones para my_app
makemigrations Generar migraciones para todas las aplicaciones.
makemigrations --merge Resolver conflictos de migración para todas las aplicaciones.
makemigrations --merge <my_app> Resolver conflictos de migración para my_app
makemigrations --name <migration_name> <my_app> Genera una migración para my_app con el nombre migration_name
migrate <my_app> Aplicar migraciones pendientes de my_app a la base de datos.
migrate Aplicar todas las migraciones pendientes a la base de datos.
migrate <my_app> <migration_name> Aplicar o no aplicar hasta el nombre de migration_name
migrate <my_app> zero Desplegar todas las migraciones en my_app
sqlmigrate <my_app> <migration_name> Imprime el SQL para la migración nombrada.
showmigrations Muestra todas las migraciones para todas las aplicaciones.
showmigrations <my_app> Muestra todas las migraciones en my_app

Trabajando con migraciones

Django usa migraciones para propagar los cambios que realiza a sus modelos en su base de datos. La mayoría de las veces, django puede generarlos por ti.

Para crear una migración, ejecute:

$ django-admin makemigrations <app_name>

Esto creará un archivo de migración en el submódulo de migration de app_name . La primera migración se llamará 0001_initial.py , la otra comenzará con 0002_ , luego 0003 , ...

Si omite <app_name> esto creará migraciones para todas sus INSTALLED_APPS .

Para propagar migraciones a su base de datos, ejecute:

$ django-admin migrate <app_name>

Para mostrar todas sus migraciones, ejecute:

$ django-admin showmigrations app_name
app_name
  [X] 0001_initial
  [X] 0002_auto_20160115_1027
  [X] 0003_somemodel
  [ ] 0004_auto_20160323_1826
  • [X] significa que la migración se propagó a su base de datos
  • [ ] significa que la migración no se propagó a su base de datos. Usa django-admin migrate para propagarlo

También puede llamar a revertir migraciones, esto se puede hacer pasando el nombre de la migrate command . Dada la lista anterior de migraciones (mostrada por 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

Migraciones manuales

A veces, las migraciones generadas por Django no son suficientes. Esto es especialmente cierto cuando desea realizar migraciones de datos .

Por ejemplo, vamos a tener ese modelo:

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

Este modelo ya tiene datos existentes y ahora desea agregar un SlugField :

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

Usted creó las migraciones para agregar el campo, pero ahora le gustaría establecer la babosa para todos los artículos existentes, de acuerdo con su title .

Por supuesto, puedes hacer algo como esto en la terminal:

$ 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()
...
>>>

Pero tendrá que hacer esto en todos sus entornos (es decir, en el escritorio de su oficina, en su computadora portátil, ...), todos sus compañeros de trabajo también deberán hacerlo, y tendrán que pensar en ello durante la puesta en escena y al momento de presionar. vivir.

Para hacerlo de una vez por todas, lo haremos en una migración. Primero crea una migración vacía:

$ django-admin makemigrations --empty app_name

Esto creará un archivo de migración vacío. Ábrelo, contiene un esqueleto base. Digamos que su migración anterior se llamó 0023_article_slug y esta se llama 0024_auto_20160719_1734 . Esto es lo que escribiremos en nuestro archivo de migración:

# -*- 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.
    ]

Migraciones falsas

Cuando se ejecuta una migración, Django almacena el nombre de la migración en una tabla django_migrations.

Crear y falsificar las migraciones iniciales para el esquema existente.

Si su aplicación ya tiene modelos y tablas de base de datos, y no tiene migraciones. Primero crea migraciones iniciales para tu aplicación.

python manage.py makemigrations your_app_label

Ahora falsas migraciones iniciales según lo aplicado

python manage.py migrate --fake-initial

Falsas todas las migraciones en todas las aplicaciones.

python manage.py migrate --fake

Falsas migraciones de una sola aplicación.

python manage.py migrate --fake core

Fake único archivo de migración

python manage.py migrate myapp migration_name

Nombres personalizados para archivos de migración

Use la makemigrations --name <your_migration_name> para permitir nombrar las migraciones en lugar de usar un nombre generado.

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

Resolviendo conflictos migratorios.

Introducción

A veces, las migraciones entran en conflicto, lo que hace que la migración no tenga éxito. Esto puede suceder en muchos escenarios, sin embargo, puede ocurrir de manera regular al desarrollar una aplicación con un equipo.

Los conflictos de migración comunes ocurren mientras se usa el control de origen, especialmente cuando se usa el método de característica por rama. Para este escenario, usaremos un modelo llamado Reporter con el name y la address los atributos.

Dos desarrolladores en este punto van a desarrollar una característica, por lo que ambos obtienen esta copia inicial del modelo Reporter . El desarrollador A agrega una age que da como resultado el archivo 0002_reporter_age.py . El desarrollador B agrega un campo bank_account que da como resultado 0002_reporter_bank_account . Una vez que estos desarrolladores fusionan su código e intentan migrar las migraciones, se produjo un conflicto de migración.

Este conflicto se produce porque estas migraciones alteran el mismo modelo, Reporter . Además de eso, los nuevos archivos comienzan con 0002.

Fusionando migraciones

Hay varias maneras de hacerlo. Lo siguiente está en el orden recomendado:

  1. La solución más simple para esto es ejecutar el comando makemigrations con una marca --merge.

    python manage.py makemigrations --merge <my_app>
    

    Esto creará una nueva migración para resolver el conflicto anterior.

  2. Cuando este archivo adicional no es bienvenido en el entorno de desarrollo por razones personales, una opción es eliminar las migraciones en conflicto. Luego, se puede hacer una nueva migración usando el comando regular makemigrations . Cuando se escriben migraciones personalizadas, como migrations.RunPython , se deben tener en cuenta utilizando este método.

Cambiar un campo de caracteres a una clave foránea

En primer lugar, supongamos que este es su modelo inicial, dentro de una aplicación llamada discography :

from django.db import models

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

Ahora, te das cuenta de que quieres usar una ForeignKey para el artista. Este es un proceso algo complejo, que se debe realizar en varios pasos.

Paso 1, agregue un nuevo campo para ForeignKey, asegurándose de marcarlo como nulo (tenga en cuenta que el modelo al que estamos vinculando también se incluye ahora):

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)

... y crea una migración para este cambio.

./manage.py makemigrations discography

Paso 2, rellena tu nuevo campo. Para hacer esto, tienes que crear una migración vacía.

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

Una vez que tenga esta migración vacía, desea agregar una sola operación RunPython para vincular sus registros. En este caso, podría verse algo como esto:

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()

Ahora que sus datos se transfirieron al nuevo campo, podría terminar y dejar todo como está, usando el nuevo campo artist_link para todo. O, si desea hacer un poco de limpieza, desea crear dos migraciones más.

Para su primera migración, querrá eliminar su campo original, artist . Para su segunda migración, cambie el nombre del nuevo campo artist_link a artist .

Esto se realiza en varios pasos para garantizar que Django reconozca las operaciones correctamente.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow