2015-06-19 9 views
10

पर डालने में असमर्थ है। मैं अपनी साइट को SQLite बैकएंड से पोस्टग्रेस बैकएंड में माइग्रेट कर रहा हूं। हम परियोजना की शुरुआत से देशी-डीजेगो शैली प्रवास (यानी दक्षिण नहीं) चला रहे हैं। अधिकांश माइग्रेशन ठीक चलते हैं, लेकिन हमारे हमारे अनुप्रयोगों में एक हिचकी है।Django 1.8 माइग्रेशन कॉलम आईडी को पूर्णांक

हमें पोस्टग्रेज़ माइग्रेशन में अब तक यह मिला है। (सभी अन्य ऐप्स पूरी तरह माइग्रेट किए गए हैं।) सभी माइग्रेशन SQLite3 पर घटना के बिना भाग गया।

processes 
[X] 0001_initial 
[X] 0002_auto_20150508_2149 
[ ] 0003_auto_20150511_1543 
[ ] 0004_auto_20150528_1739 
[ ] 0005_process_upstream 
[ ] 0006_auto_20150605_1436 
[ ] 0007_auto_20150605_1706 
[ ] 0008_milestone_prevailing_process 

इन दोनों माइग्रेशन सही ढंग से भाग गया:

0001_initial.py:

class Migration(migrations.Migration): 

    dependencies = [ 
    ] 

    operations = [ 
     migrations.CreateModel(
      name='DateReason', 
      fields=[ 
       ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 
       ('name', models.CharField(unique=True, max_length=50)), 
       ('active', models.BooleanField(default=True)), 
       ('final', models.BooleanField(default=False)), 
      ], 
     ), 
     migrations.CreateModel(
      name='EventType', 
      fields=[ 
       ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 
       ('name', models.CharField(unique=True, max_length=50)), 
       ('active', models.BooleanField(default=True)), 
      ], 
     ), 
     migrations.CreateModel(
      name='Metric', 
      fields=[ 
       ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 
       ('name', models.CharField(unique=True, max_length=50)), 
       ('active', models.BooleanField(default=True)), 
      ], 
     ), 
     migrations.CreateModel(
      name='Process', 
      fields=[ 
       ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 
       ('name', models.CharField(max_length=50)), 
       ('sequence', models.PositiveIntegerField()), 
       ('sla', models.PositiveSmallIntegerField(null=True, blank=True)), 
       ('milestone', models.BooleanField(default=False)), 
      ], 
      options={ 
       'ordering': ['workflow', 'sequence'], 
      }, 
     ), 
     migrations.CreateModel(
      name='Workflow', 
      fields=[ 
       ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 
       ('name', models.CharField(unique=True, max_length=20)), 
       ('active', models.BooleanField(default=True)), 
      ], 
     ), 
     migrations.AddField(
      model_name='process', 
      name='workflow', 
      field=models.ForeignKey(to='processes.Workflow'), 
     ), 
     migrations.AlterUniqueTogether(
      name='process', 
      unique_together=set([('workflow', 'name'), ('workflow', 'sequence')]), 
     ), 
    ] 

0002_auto_20150508_2149.py:

class Migration(migrations.Migration): 

    dependencies = [ 
     ('processes', '0001_initial'), 
    ] 

    operations = [ 
     migrations.CreateModel(
      name='Milestone', 
      fields=[ 
       ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 
       ('name', models.CharField(max_length=50)), 
       ('sequence', models.PositiveIntegerField()), 
       ('workflow', models.ForeignKey(to='processes.Workflow')), 
      ], 
      options={ 
       'ordering': ['workflow', 'sequence'], 
      }, 
     ), 
     migrations.AlterModelOptions(
      name='process', 
      options={'ordering': ['milestone', 'sequence']}, 
     ), 
     migrations.AlterUniqueTogether(
      name='process', 
      unique_together=set([('milestone', 'name'), ('milestone', 'sequence')]), 
     ), 
     migrations.RemoveField(
      model_name='process', 
      name='workflow', 
     ), 
     migrations.AlterUniqueTogether(
      name='milestone', 
      unique_together=set([('workflow', 'name'), ('workflow', 'sequence')]), 
     ), 
    ] 

इस माइग्रेशन नहीं चलेंगे: 0003_auto_20150511_1543.py

class Migration(migrations.Migration): 

    dependencies = [ 
     ('processes', '0002_auto_20150508_2149'), 
    ] 

    operations = [ 
     migrations.AlterModelOptions(
      name='process', 
      options={'ordering': ['milestone', 'sequence'], 'verbose_name_plural': 'processes'}, 
     ), 
     migrations.AlterField(
      model_name='process', 
      name='milestone', 
      field=models.ForeignKey(to='processes.Milestone'), 
     ), 
    ] 

में इस प्रवास परिणाम को चलाने के लिए प्रयास कर रहा है:

django.db.utils.ProgrammingError: column "milestone_id" cannot be cast automatically to type integer 
HINT: Specify a USING expression to perform the conversion. 

वर्तमान, प्रासंगिक मॉडल तालिकाओं के लिए पूरी तरह से चले गए राज्य है:

class Milestone(models.Model): 
    """A collection of steps in a workflow""" 
    workflow = models.ForeignKey(Workflow, blank=False, null=False) 
    name = models.CharField(max_length=50, blank=False, null=False) 
    sequence = models.PositiveIntegerField(blank=False, null=False) 
    prevailing_process = models.ForeignKey('Process', blank=False, null=True, related_name='controls_milestone') 

    class Meta: 
     ordering = ['workflow', 'sequence'] 
     unique_together = (("workflow", "sequence"), ("workflow", "name")) 

    def __unicode__(self): 
     return u"{0}: {1}".format(self.workflow.name, self.name) 


class Process(models.Model): 
    """A step in a workflow""" 
    milestone = models.ForeignKey(Milestone, blank=False, null=False) 
    name = models.CharField(max_length=50, blank=False, null=False) 
    sequence = models.PositiveIntegerField(blank=False, null=False) 
    sla = models.PositiveSmallIntegerField(blank=True, null=True) 
    upstream = models.ForeignKey('self', blank=True, null=True, on_delete=models.SET_NULL, related_name='downstream_set') 

    class Meta: 
     ordering = ['milestone', 'sequence'] 
     unique_together = (("milestone", "sequence"), ("milestone", "name")) 
     verbose_name_plural = "processes" 

    def __unicode__(self): 
     return u"{0} {1}: {2}".format(self.milestone.workflow.name, self.milestone.name, self.name) 

Squashing माइग्रेशन मदद नहीं की। पोस्टग्रेज़ डेटाबेस तालिका परिभाषाओं को छोड़कर साफ है। उनके पोस्ट फॉर्म में प्रासंगिक पोस्टग्रेज़ टेबल परिभाषाएं हैं:

scorecard=# \d processes_milestone 
            Table "public.processes_milestone" 
    Column |   Type   |       Modifiers 
-------------+-----------------------+------------------------------------------------------------------ 
id   | integer    | not null default nextval('processes_milestone_id_seq'::regclass) 
name  | character varying(50) | not null 
sequence | integer    | not null 
workflow_id | integer    | not null 
Indexes: 
    "processes_milestone_pkey" PRIMARY KEY, btree (id) 
    "processes_milestone_workflow_id_21e7e70ae59594a8_uniq" UNIQUE CONSTRAINT, btree (workflow_id, sequence) 
    "processes_milestone_workflow_id_363216929a08f11e_uniq" UNIQUE CONSTRAINT, btree (workflow_id, name) 
    "processes_milestone_846c77cf" btree (workflow_id) 
Check constraints: 
    "processes_milestone_sequence_check" CHECK (sequence >= 0) 
Foreign-key constraints: 
    "processes_workflow_id_53b7557aa3f3378e_fk_processes_workflow_id" FOREIGN KEY (workflow_id) REFERENCES processes_workflow(id) DEFERRABLE INITIALLY DEFERRED 

scorecard=# \d processes_process 
            Table "public.processes_process" 
    Column |   Type   |       Modifiers 
-----------+-----------------------+---------------------------------------------------------------- 
id  | integer    | not null default nextval('processes_process_id_seq'::regclass) 
name  | character varying(50) | not null 
sequence | integer    | not null 
sla  | smallint    | 
milestone | boolean    | not null 
Indexes: 
    "processes_process_pkey" PRIMARY KEY, btree (id) 
    "processes_process_milestone_20dc77c2825fcc38_uniq" UNIQUE CONSTRAINT, btree (milestone, name) 
    "processes_process_milestone_5bb869985140bf86_uniq" UNIQUE CONSTRAINT, btree (milestone, sequence) 
Check constraints: 
    "processes_process_sequence_check" CHECK (sequence >= 0) 
    "processes_process_sla_check" CHECK (sla >= 0) 
Referenced by: 
    TABLE "collection_implementation" CONSTRAINT "collection__process_id_6461d2ef37b3f126_fk_processes_process_id" FOREIGN KEY (process_id) REFERENCES processes_process(id) DEFERRABLE INITIALLY DEFERRED 

मैं मूल रूप से विचारों से बाहर हूं। ऐसा लगता है कि यह पहले से ही एक पूर्णांक है, और वास्तव में, यह एक Django- निर्दिष्ट प्राथमिक कुंजी होने की अपेक्षा क्या करेगा?

+0

fwiw, कुछ मामलों में, मैं पहली बार एक क्षेत्र छोड़ने के लिए है, तो एक susequent प्रवास में क्षेत्र के विभिन्न प्रकार जोड़ने लिया है। – Brandon

+0

यह कोई साफ समाधान नहीं है, लेकिन दोषी माइग्रेशन बहुत छोटा प्रतीत होता है, शायद आप डेटाबेस को मैन्युअल रूप से बदल सकते हैं, फिर माइग्रेशन को नकली कर सकते हैं? – spectras

+0

सेकेंडिंग ब्रैंडन की टिप्पणी, मैंने इसे फ़ील्ड छोड़कर और फिर उसी क्षेत्र को बाद में माइग्रेशन में जोड़कर तय किया। – orange1

उत्तर

19

समस्या प्रोसेस.मिलेस्टोन से एक बूलियन फ़ील्ड के रूप में माइक्रोसॉफ्ट को प्रोसेस.मिलेस्टोन को विदेशी कुंजी के रूप में माइग्रेशन है। Postgres अप्रत्याशित डेटा पर विफल होने के लिए माइग्रेशन की प्रतीक्षा नहीं करता है। यह पहले से ही टेबल को बदलने का नियम चाहता है।

यदि आप दो क्षेत्रों के बीच किसी भी प्रकार के डेटा माइग्रेशन का इरादा नहीं रखते हैं, तो सबसे आसान विकल्प बस ड्रॉप और फ़ील्ड को जोड़ना है। इस विशिष्ट मामले में, यह आपरेशन बदल रहा है के रूप में इस का मतलब होगा:

operations = [ 
    migrations.RemoveField(
     model_name='process', 
     name='milestone' 
    ), 
    migrations.AddField(
     model_name='process', 
     name='milestone', 
     field=models.ForeignKey(to='processes.Milestone'), 
    ), 
    migrations.AlterModelOptions(
     name='process', 
     options={'ordering': ['milestone', 'sequence'], 'verbose_name_plural': 'processes'}, 
    ) 
] 
4

पोस्टग्रेज़ को यह नहीं पता कि एक बुलियन फ़ील्ड को एक पूर्णांक में कैसे परिवर्तित किया जाए, भले ही तालिका खाली हो। आपको इसे एक प्रयोग खंड के साथ बताना होगा। विदेशी कुंजी में कनवर्ट करने से पहले आप पूर्णांक रूपांतरण के लिए SQL माइग्रेशन का उपयोग कर सकते हैं। मुझे नहीं लगता कि बिना किसी एसक्यूएल के ऐसा करने का कोई तरीका है, django को यह नहीं पता कि यह कैसे करना है।

ALTER_SQL = ''' 
    ALTER TABLE processes_process ALTER COLUMN milestone TYPE integer USING (
     CASE milestone 
      when TRUE then ... 
      when FALSE then ... 
     END 
     ); 
    ''' 

class Migration(migrations.Migration): 

    dependencies = [ 
     ('processes', '0002_auto_20150508_2149'), 
    ] 

    operations = [ 
     migrations.AlterModelOptions(
      name='process', 
      options={'ordering': ['milestone', 'sequence'], 'verbose_name_plural': 'processes'}, 
     ), 
     migrations.RunSQL(ALTER_SQL, None, [ 
      migrations.AlterField(
       model_name='process', 
       name='milestone', 
       field=models.IntegerField(), 
       preserve_default=True, 
      ), 
     ]), 
     migrations.AlterField(
      model_name='process', 
      name='milestone', 
      field=models.ForeignKey(to='processes.Milestone'), 
     ), 
    ] 

तो तालिका खाली है, आप एक खाली खंड या एक खाली मामले का उपयोग कर के साथ भाग प्राप्त करने में सक्षम हो सकता है।

+0

एक RunSQL आपरेशन करने के लिए उपयोग कर खंड जोड़ा जा रहा है चाल (यह अब भी वही त्रुटि फेंक दिया गया था) नहीं किया है, लेकिन जहां यह चला गया पता लगाने की कोशिश गलत कम से कम समस्या को हल करने के लिए Django डॉक्स का एक बेहतर भाग के लिए मुझे मिल गया खुद। मैं इसे एक गुच्छा की सराहना करता हूं! –

+0

त्रुटि क्या थी? और आपका उपयोग खंड क्या था? – noamk

+0

त्रुटि बिल्कुल वही थी। मैंने एक खाली उपयोग खंड दोनों की कोशिश की और इसे सत्य और झूठे दोनों के लिए शून्य पर सेट किया। –

संबंधित मुद्दे