Opened 10 years ago

Closed 10 years ago

Last modified 6 years ago

#27871 closed Bug (needsinfo)

Django keeps making the same migration over and over again

Reported by: Kyle Agronick Owned by: nobody
Component: Migrations Version: 1.10
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Kyle Agronick)

This is what the migration looks like:

class Migration(migrations.Migration):

    dependencies = [
        ('jobs', '0003_auto_20170222_1154'),
    ]

    operations = [
        migrations.AlterField(
            model_name='joblog',
            name='job',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='logs', to='jobs.Job'),
        ),
    ]

Running ./mange.py migrate makes no difference. I recently moved the codebase to Python 3.
Below is the create table syntax for the relevant tables:

CREATE TABLE `jobs_jobparameter` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `value` longtext NOT NULL,
  `job_group_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `jobs_jobparameter_job_group_id_bbb541f6_uniq` (`job_group_id`,`name`),
  KEY `jobs_jobparameter_name_84b3d6ba_uniq` (`name`),
  CONSTRAINT `jobs_jobparameter_job_group_id_7205c657_fk_jobs_jobgroup_id` FOREIGN KEY (`job_group_id`) REFERENCES `jobs_jobgroup` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=45338 DEFAULT CHARSET=utf8

CREATE TABLE `jobs_joblog` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `command` longtext NOT NULL,
  `command_output` longtext NOT NULL,
  `result` tinyint(1) NOT NULL,
  `job_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `jobs_joblog_job_id_734186c1ec7977e9_fk_jobs_job_id` (`job_id`),
  CONSTRAINT `jobs_joblog_job_id_ae8f8e96_fk_jobs_job_id` FOREIGN KEY (`job_id`) REFERENCES `jobs_job` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7749677 DEFAULT CHARSET=latin1

CREATE TABLE `jobs_jobgroup` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `job_type` varchar(100) NOT NULL,
  `created_by_id` int(11) NOT NULL,
  `created_date` datetime NOT NULL,
  `queued_date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `jobs_jobgroup_created_by_id_769ccba8b90c80f8_fk_auth_user_id` (`created_by_id`),
  KEY `jobs_jobgroup_job_type_c2db1010_uniq` (`job_type`),
  KEY `jobs_jobgroup_created_date_852898d7_uniq` (`created_date`),
  KEY `jobs_jobgroup_queued_date_c38be898_uniq` (`queued_date`),
  CONSTRAINT `jobs_jobgroup_created_by_id_769ccba8b90c80f8_fk_auth_user_id` FOREIGN KEY (`created_by_id`) REFERENCES `auth_user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15290 DEFAULT CHARSET=latin1

CREATE TABLE `jobs_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `state` varchar(1) NOT NULL,
  `start_date` datetime DEFAULT NULL,
  `end_date` datetime DEFAULT NULL,
  `job_group_id` int(11) NOT NULL,
  `store` varchar(40) NOT NULL,
  `payload` longtext NOT NULL,
  PRIMARY KEY (`id`),
  KEY `jobs_job_be96d149` (`job_group_id`),
  KEY `jobs_job_store_6681c0e7_uniq` (`store`),
  KEY `jobs_job_start_date_b8aefdc3_uniq` (`start_date`),
  KEY `jobs_job_state_6ec9b5f7_uniq` (`state`),
  CONSTRAINT `jobs_job_job_group_id_93d2fccf_fk_jobs_jobgroup_id` FOREIGN KEY (`job_group_id`) REFERENCES `jobs_jobgroup` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3316872 DEFAULT CHARSET=latin1

The migrations are attached.

Attachments (1)

migrations.tar.gz (4.1 KB ) - added by Kyle Agronick 10 years ago.
Migrations for the affected app

Download all attachments as: .zip

Change History (13)

by Kyle Agronick, 10 years ago

Attachment: migrations.tar.gz added

Migrations for the affected app

comment:1 by Kyle Agronick, 10 years ago

Description: modified (diff)

comment:2 by Kyle Agronick, 10 years ago

Description: modified (diff)
Type: UncategorizedBug

comment:3 by Tim Graham, 10 years ago

Component: Database layer (models, ORM)Migrations

Could you please provide a minimal set of models that reproduces the issue? Did you change the case of any models recently (#27297)?

Last edited 10 years ago by Tim Graham (previous) (diff)

comment:4 by Tim Graham, 10 years ago

Resolution: needsinfo
Status: newclosed

comment:5 by Kyle Agronick, 10 years ago

Description: modified (diff)
Resolution: needsinfo
Status: closednew

comment:6 by Kyle Agronick, 10 years ago

Description: modified (diff)

Here are all the models:

from django.contrib.auth.models import User
from django.db import models

job_state = (('P', 'Pending'), ('A', 'Active'), ('C', 'Completed'), ('F', 'Failed'))
app_type = (('R', 'RX'), ('W', 'WAR'))
server_types = #taken out


class JobGroup(models.Model):
    job_type = models.CharField(max_length=100, db_index=True)
    created_by = models.ForeignKey(User)
    queued_date = models.DateTimeField(null=True, db_index=True)
    created_date = models.DateTimeField(auto_now_add=True, db_index=True)


class JobParameter(models.Model):
    job_group = models.ForeignKey(JobGroup, related_name='job_param', on_delete=models.CASCADE)
    name = models.CharField(max_length=100, db_index=True)
    value = models.TextField()

    def split_values(self):
        if ',' in self.value and isinstance(self.value, str):
            return self.value.split(', ')
        else:
            return [self.value]

    class Meta:
        unique_together = ('job_group', 'name')


class Job(models.Model):
    job_group = models.ForeignKey(JobGroup, related_name='jobs', on_delete=models.CASCADE)
    state = models.CharField(max_length=1, choices=job_state, default='P', db_index=True)
    start_date = models.DateTimeField(null=True, db_index=True)
    end_date = models.DateTimeField(null=True)
    store = models.CharField(max_length=40, db_index=True)
    payload = models.TextField()

    def get_full_state(self):
        return self.get_state_display() if self.state in dict(job_state) else 'Unknown'

    class Meta:
        permissions = (
            ('deployment_job', 'Access Deployment job'),
            ('services_job', 'Access System Services job'),
            ('offline_status_job', 'Access Offline Status job'),
        )


class JobLog(models.Model):
    job = models.ForeignKey(Job, related_name='logs', on_delete=models.CASCADE)
    command = models.TextField()
    command_output = models.TextField()
    result = models.BooleanField(default=False)


class Service(models.Model):
    service_name = models.CharField(max_length=40)
    human_readable_name = models.CharField(max_length=40)
    server_type = models.CharField(choices=server_types, max_length=5)

    def __str__(self):
        return self.human_readable_name

    class Meta:
        ordering = ['human_readable_name']
        unique_together = ['service_name', 'server_type']

comment:7 by Kyle Agronick, 10 years ago

Description: modified (diff)

comment:8 by Tim Graham, 10 years ago

I cannot reproduce a problem. Can you please debug the issue and provide more specific steps to reproduce it?

comment:9 by Kyle Agronick, 10 years ago

You would probably need to run my create table scripts and load in my migrations on a MySQL DB.

Changing job to Job in the name part of CreateModel seems to have fixed it. I don't know why, but at somepoint after squashing the migrations this became an issue.

        migrations.CreateModel(
            name='Job',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('state', models.CharField(choices=[('P', 'Pending'), ('A', 'Active'), ('C', 'Completed'), ('F', 'Failed')], default='P', max_length=1)),
                ('start_date', models.DateTimeField()),
                ('end_date', models.DateTimeField()),
            ],
        ),

comment:10 by Tim Graham, 10 years ago

makemigrations doesn't examine the database state so loading the schema wouldn't matter but some differences in the old migration files is likely the cause (as opposed to what I did in generating an initial migration from the provided models). Part of putting together a useful bug report is to create a minimal sample project that reproduces the issue. For example, I doubt all 6 models are required.

Again I'll point to #27297 and ask if this might be a duplicate of that issue?

comment:11 by Tim Graham, 10 years ago

Resolution: needsinfo
Status: newclosed

comment:12 by Stanislav Zubov, 6 years ago

Greetings from 2020!

Met this issue today with models like this:

class CRITICALITY(models.ChoiceEnum):
    LOW = 'low'
    NORMAL = 'normal'
    HIGH = 'high'

class Detection(models.Model):
    criticality = models.CharField(
        max_length=10, choices=CRITICALITY.choices(), default=CRITICALITY.NORMAL,
    )
    notification = models.ForeignKey(
        'notifications.UserNotification', related_name='+', blank=True, null=True,
        on_delete=models.SET_NULL
    )

makemigrations generates similar migration on every run:

# Generated by Django 2.2.3 on 2020-09-02 08:29

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

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

    operations = [
        migrations.AlterField(
            model_name='detection',
            name='notification',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='notifications.UserNotification'),
        ),
    ]

p.s.

Python 3.6.8
Django                        2.2.3
django-cors-headers           3.0.2
django-db-geventpool          3.1.0
django-debug-toolbar          1.9.1
django-filter                 2.1.0
django-redis                  4.10.0
django-sendfile2              0.4.2
djangorestframework           3.9.4
pytest-django                 3.6.0
Note: See TracTickets for help on using tickets.
Back to Top