ho aggiunto un nuovo campo a uno dei miei modelli:Come fare correttamente le migrazioni quando si aggiunge un nuovo campo unico
class Agency(models.Model):
email = models.EmailField(unique=True, verbose_name=_("e-mail"))
Poiché questo campo non può essere vuoto, django-admin makemigrations
mi ha chiesto di fornire una tantum default, che L'ho fatto. Ecco la migrazione generato:
# Generated by Django 1.9.4 on 2016-03-20 10:38
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0008_auto_20160226_1226'),
]
operations = [
migrations.AddField(
model_name='agency',
name='email',
field=models.EmailField(default='[email protected]', max_length=254, unique=True, verbose_name='e-mail'),
preserve_default=False,
),
]
Come previsto, django-admin migrate
gettò un errore:
psycopg2.IntegrityError: could not create unique index "accounts_agency_email_key"
DETAIL: Key (email)=([email protected]) is duplicate.
pensavo di poter modificare la migrazione per impostare valori unici prima di fare il campo univoco. Così ho provato:
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2016-03-20 10:38
from __future__ import unicode_literals
from django.db import migrations, models
from django.utils.text import slugify
def set_email(apps, schema_editor):
Agency = apps.get_model('accounts', 'Agency')
for agency in Agency.objects.all():
agency.email = '{}@example.fr'.format(slugify(agency.name))
agency.save()
class Migration(migrations.Migration):
dependencies = [
('accounts', '0008_auto_20160226_1226'),
]
operations = [
migrations.AddField(
model_name='agency',
name='email',
field=models.EmailField(default='', max_length=254, blank=True, verbose_name='e-mail'),
preserve_default=False,
),
migrations.RunPython(set_email),
migrations.AlterField(
model_name='agency',
name='email',
field=models.EmailField(max_length=254, unique=True, verbose_name='e-mail'),
preserve_default=False,
),
]
Purtroppo ottengo questo errore durante l'esecuzione django-admin migrate
:
django.db.utils.OperationalError: cannot ALTER TABLE "accounts_agency" because it has pending trigger events
mia ipotesi è che operations
non vengono eseguiti in modo sincrono.
Penso di poter risolvere il problema suddividendo la migrazione in due migrazioni, ma mi piacerebbe sapere se posso farlo in una sola migrazione. Qual è il modo comune per creare migrazioni quando si aggiunge un nuovo campo univoco in un modello?
PS: Ho anche cercato di usare un'espressione F di default (default=models.F('name') + '@example.fr'
), ma è venuto a mancare:
django.db.utils.IntegrityError: could not create unique index "accounts_agency_email_key"
DETAIL: Key (email)=(F(name) + Vallu(@example.fr)) is duplicated.
Hai letto la sezione di documenti che si occupa esattamente di questo problema? https://docs.djangoproject.com/en/1.9/howto/writing-migrations/#migrations-that-add-unique-fields – koniiiik
@koniiiik, cerco sulla pagina sbagliata https://docs.djangoproject.com/ en/1.9/topics/migrations/Quindi, sembra che non ci sia modo di farlo funzionare con una sola migrazione. –
C'è qualche ragione per cui non vuoi usare due migrazioni? – koniiiik