2016-03-20 18 views
9

yeni bir benzersiz bir alan eklerken düzgün geçişleri nasıl yapılır: boş olamaz bu alanda gibibenim modellerinden birine yeni bir alan ekledi

class Agency(models.Model): 
    email = models.EmailField(unique=True, verbose_name=_("e-mail")) 

, django-admin makemigrations kerelik varsayılan sağlamak beni talebinde bulunduğu Yaptım. İşte oluşturulan göç:

psycopg2.IntegrityError: could not create unique index "accounts_agency_email_key" 
DETAIL: Key (email)=([email protected]) is duplicate. 

ben alan benzersiz yapmadan önce benzersiz değerleri ayarlamak için göçü düzenlemek düşündüm:

Beklendiği gibi
# 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, 
     ), 
    ] 

, django-admin migrate bir hata throwed. Yani Denedim: django-admin migrate çalıştırırken

# -*- 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, 
     ), 
    ] 

Ne yazık ki bu hatayı alıyorum:

django.db.utils.OperationalError: cannot ALTER TABLE "accounts_agency" because it has pending trigger events 

Benim tahminim operations eşzamanlı yapılmaz olmasıdır.

Bu sorunu, geçişi iki geçişe bölerek çözebilirim, ancak bunu yalnızca bir geçişte yapıp yapamayacağımı bilmek istiyorum. Modelde yeni bir alan eklerken geçişleri oluşturmanın ortak yolu nedir?

PS: Ben de varsayılan (default=models.F('name') + '@example.fr') olarak bir F ifadesini kullanmaya çalıştı ama başarısız oldu:

django.db.utils.IntegrityError: could not create unique index "accounts_agency_email_key" 
DETAIL: Key (email)=(F(name) + Vallu(@example.fr)) is duplicated. 
+3

Tam olarak bu sorunla ilgilenen dokümanlar bölümünü okudunuz mu? https://docs.djangoproject.com/en/1.9/howto/writing-migrations/#migrations-that-add-unique-fields – koniiiik

+0

@koniiiik, Yanlış sayfada arama yaptım https://docs.djangoproject.com/ tr/1.9/topics/migrations/Yani, sadece bir göçle çalışmanın bir yolu yok gibi görünüyor. –

+1

İki geçişi kullanmak istememenizin bir nedeni var mı? – koniiiik

cevap

2

Belki çok geç ama belki başkası için işe yarayabilir

bunu yapabilirsiniz piton manage.py makemigrations size modeline yeni bir alan ekledi sonra örnek kodu için migrations.RunSQL yöntemi

kullanarak ve çalıştırmak yoluyla bir göçün komutu (eğer tablo komutunuzda var olan satırlarınız var ise burada seçim yapmak istediğiniz varsayılan değeri seçmek isteyebilirsiniz) "Şimdi bir defaya mahsus varsayılan" seçeneği sağlayın ve biraz dize değeri verin, çünkü önemli değil çünkü aslında kullanmadık.) ardından taşıma dosyasına gidip

operations = [ 
     migrations.RunSQL(
     'ALTER TABLE "agency" ADD COLUMN "email" varchar(254) NULL;ALTER TABLE "agency" ALTER COLUMN "email" DROP DEFAULT;COMMIT;', 
     ), 
     migrations.RunSQL(
     "UPDATE agency SET email= Concat(country_code, '@example.fr');COMMIT;", 
     ), 
     migrations.RunSQL(
     'ALTER TABLE "agency" ALTER COLUMN "email" SET NOT NULL;ALTER TABLE "agency" ADD CONSTRAINT "agency_email_b551ad2a_uniq" UNIQUE ("email");ALTER TABLE "agency" ALTER COLUMN "email" DROP DEFAULT;CREATE INDEX "agency_email_b551ad2a_like" ON "agency" ("email" varchar_pattern_ops);COMMIT;' 
     ) 
    ] 

sonra çalıştırmak öyle komutunu " piton göç ​​manage.py" (i size veritabanı için SQL değiştirebilir Postgresql'i kullanmak Not) bununla İşlemleri kısmını değiştirmek.

+0

Bu harika oldu. Çok teşekkürler – Martin

İlgili konular