9

Django is creating the same migrations file repeatedly when calling:

./manage.py makemigrations

The same migrations will be created in a new migrations file every time makemigrations is run regardless of if the changes are migrated or not.

The process looks like so:

./manage.py makemigrations app

Migrations for 'app':
project/app/migrations/0007_auto_20171010_1837.py
- Alter field charge_type on charge
- Alter field fee_type on fee
- Alter field event_type on orderevent


./manage.py migrate app

Running migrations:
Applying mws.0007_auto_20171010_1837... OK


./manage.py makemigrations app

Migrations for 'app':
project/app/migrations/0008_auto_20171010_1838.py
- Alter field charge_type on charge
- Alter field fee_type on fee
- Alter field event_type on orderevent


./manage.py makemigrations app

Migrations for 'app':
project/app/migrations/0009_auto_20171010_1839.py
- Alter field charge_type on charge
- Alter field fee_type on fee
- Alter field event_type on orderevent

I am curious why new identical migrations continue to be created with updated migration file names when no changes are being made to the models between makemigrations and migrate commands.

The models look like this:

Current app models:

class OrderEvent(models.Model):
    client = models.ForeignKey('clients.Client')

    SHIPMENT_EVENT = 'she'
    REFUND_EVENT = 'ree'
    CHARGEBACK_EVENT = 'cbe'
    GUARANTEE_CLAIM_EVENT = 'gce'

    EVENT_TYPE_CHOICES = {
        (SHIPMENT_EVENT, 'Shipment Event'),
        (REFUND_EVENT, 'Refund Event'),
        (CHARGEBACK_EVENT, 'Chargeback Event'),
        (GUARANTEE_CLAIM_EVENT, 'Guarantee Claim Event'),
    }

    event_type = models.CharField(max_length=3, choices=EVENT_TYPE_CHOICES)
    amazon_order_id = models.CharField(max_length=19)
    seller_order_id = models.CharField(max_length=19)
    marketplace_name = models.CharField(max_length=14)
    posted_date = models.DateTimeField(blank=True, null=True)


class ShipmentItem(models.Model):
    order_event = models.ForeignKey('OrderEvent')
    seller_sku = models.CharField(max_length=128)
    order_item_id = models.CharField(max_length=19)
    quantity_shipped = models.IntegerField()



class Charge(models.Model):
    shipment_item = models.ForeignKey('ShipmentItem', blank=True, null=True)

    PAYMENT_METHOD_FEE = 'pmf'
    EXPORT_CHARGE = 'exc'
    SAFET_REIMBURSEMENT = 'str'
    OTHER = 'oth'

    CHARGE_TYPE_CHOICES = {
        (PAYMENT_METHOD_FEE, 'Payment Method Fee'),
        (EXPORT_CHARGE, 'Export Charge'),
        (SAFET_REIMBURSEMENT, 'SAFET Reimbursement'),
        (OTHER, 'Other'),
    }
    charge_type = models.CharField(
        max_length=3,
        choices=CHARGE_TYPE_CHOICES,
        blank=True,
        null=True
    )
    charge_currency_code = models.CharField(
        max_length=3,
        blank=True,
        null=True
    )
    charge_amount = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        blank=True,
        null=True
    )


class Fee(models.Model):
    shipment_item = models.ForeignKey('ShipmentItem', blank=True, null=True)
    TAPING_FEE = 'taf'
    TRANSPORTATION_FEE = 'trf'
    OTHER = 'oth'
    FEE_TYPE_CHOICES = {
        (TAPING_FEE, 'Taping Fee'),
        (TRANSPORTATION_FEE, 'Transportation Fee'),
        (OTHER, 'Other'),
    }
    fee_type = models.CharField(
        max_length=3,
        choices=FEE_TYPE_CHOICES,
        blank=True,
        null=True
    )
    fee_currency_code = models.CharField(
        max_length=3,
        blank=True,
        null=True
    )
    fee_amount = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        blank=True,
        null=True
    )

Client app model:

class Client(models.Model):

    name = models.CharField(max_length=128)
    code = models.CharField(
        max_length=16,
        blank=True,
        unique=True,
        help_text="Example: 00042",
    )
    slug = AutoSlugField(max_length=128, unique=True, populate_from='name')

    INVOICE_LEVEL_PARENT = 'pa'
    INVOICE_LEVEL_CHILD = 'ch'

    INVOICE_LEVEL_CHOICES = {
        (INVOICE_LEVEL_PARENT, 'Parent-level Invoice'),
        (INVOICE_LEVEL_CHILD, 'Child-level Invoice'),
    }

    invoice_level = models.CharField(
        max_length=2,
        choices=INVOICE_LEVEL_CHOICES,
        default=INVOICE_LEVEL_PARENT,
    )
    payment_terms = models.CharField(max_length=30, default='Net 15')
    late_fees = models.DecimalField(default='1.50', max_digits=5, decimal_places=2)

    notes = models.TextField(blank=True)

    def __str__(self):
        return self.name
Josh Dwernychuk
  • 105
  • 1
  • 6

3 Answers3

22

The choice parameter should be a deterministic iterable like a list or tuple.

A set is randomized in Python 3.3+ and it can not be a choice.

Change

EVENT_TYPE_CHOICES = {
    (SHIPMENT_EVENT, 'Shipment Event'), ...
}

to

EVENT_TYPE_CHOICES = (
    (SHIPMENT_EVENT, 'Shipment Event'), ...
)
hynekcer
  • 14,942
  • 6
  • 61
  • 99
0

Recently, I have faced this problem and found the solution which was a little weird even I don't know the root cause of the issue.

I had the model as below in same model.py:

class Status(models.Model):
    status=models.CharField(db_column='status',max_length=50, null=False, blank=False)


class Details(models.Model):
    #notes_names=models.CharField(max_length=50,db_column='notes_names')
    #file=models.FileField(upload_to='notes/%Y/%m/%d',max_length=255,null=True,blank=True)
    #user = models.ForeignKey(User,on_delete=models.CASCADE)
    faculty = models.ForeignKey(Registration,db_column='faculty_id',on_delete=models.CASCADE)
    degree=models.ForeignKey(Notes_Degree,on_delete=models.CASCADE)
    seqNo=models.IntegerField(default=1)
    branch=models.ForeignKey(Notes_Branch,on_delete=models.CASCADE)
    semester=models.ForeignKey(Notes_Semester,on_delete=models.CASCADE)
    subject=models.ForeignKey(Notes_Subject,on_delete=models.CASCADE)
    file=models.FileField(validators=[FileExtensionValidator(allowed_extensions=['pdf'])])
    fileType= models.CharField(db_column='file_type',max_length=30, null=True, blank=True)
    size= models.FloatField(default=0)
    url=models.CharField(db_column='url',max_length=1000, null=True, blank=True)
    pages=models.BigIntegerField(null=False, blank=False)
    # Try later ContentTypeRestrictedFileField(upload_to='uploads/', content_types=['video/x-msvideo', 'application/pdf', 'video/mp4', 'audio/mpeg', ],max_upload_size=5242880,blank=True, null=True)
    #filename= models.CharField(db_column='file_name',max_length=80, null=False, blank=False)
    #sample notes columns
    sampleFile=models.FileField(db_column='sample_file',validators=[FileExtensionValidator(allowed_extensions=['pdf'])])
    sampleSize=models.FloatField(default=0)
    sampleFileType= models.CharField(db_column='sample_file_type',max_length=30, null=True, blank=True)
    sampleUrl=models.CharField(db_column='sample_url',max_length=1000, null=True, blank=True)
    updateSeqNo=models.IntegerField(default=0)
    uploadedAt= models.DateTimeField(db_column='uploaded_date',auto_now_add=False,null=False, blank=False)
    updatedAt= models.DateTimeField(db_column='updated_date',auto_now_add=False,null=False, blank=False)
    active=models.BooleanField(default=True)
    status=models.ForeignKey(Status,on_delete=models.CASCADE,default=1)
    description=models.CharField(db_column='description',max_length=100, null=True, blank=True)
    """
    #url=models.TextField(blank=True, null=True),
    userId/notes/degree/Branch/Semester/SubjectId/Seqno/NotesId/updatedTime/Filename
    """

In this case, every time I was doing make migrations, it was creating the auto_migration.py class on-field "status".

To solve the issue, I added Status class into another module's model.py and imported. It worked and resolved smoothly.

I am really not sure why, because, in the same project, the above kind of structure is working perfectly.

Abhinav Goyal
  • 1,312
  • 7
  • 17
-5

You will have to migrate first before making new migration

./mange.py migrate

Otherwise, it will keep comparing to the current db and create new files.

Anh Do Hoang
  • 156
  • 5