django.db.utils.IntegrityError: UNIQUE constraint failed: rango_category__new.slug
Asked Answered
S

15

39

I'm learning Django from Tango with Django but I keep getting this error when I type:

python manage.py makemigrations rango
python manage.py migrate

This is the output:

django.db.utils.IntegrityError: UNIQUE constraint failed: rango_category__new.slug

Models.py:

from django.db import models
from django.template.defaultfilters import slugify

class Category(models.Model):
    name = models.CharField(max_length=128, unique=True)
    views = models.IntegerField(default=0)
    likes = models.IntegerField(default=0)
    slug = models.SlugField(unique=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name


class Page(models.Model):
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=128)
    url = models.URLField()
    views = models.IntegerField(default=0)

    def __unicode__(self):
        return self.title
Smother answered 31/3, 2015 at 16:38 Comment(1)
It's general etiquette to mark an answer as accepted if it worked for you. I had the same problem and @ruddra'a answer worked for me.Inanna
B
47

The reason for this constrain could be that you didn't have any field called slug in Category class when you have initially migrated it (First Migration), and after adding this field in the model, when you ran makemigrations, you have set default value to something static value(i.e None or '' etc), and which broke the unique constrain for the Category's table's slug column in which slug should be unique but it isn't because all the entry will get that default value.

To solve this, you can either drop the database and migration files and re-run makemigrations and migrate or set a unique default value like this:

slug = models.SlugField(unique=True, default=uuid.uuid1)

Edit:

According to Migrations that add unique fields, modify your migration file to overcome unique constrain. For example, modify your migration file (which added the slug field to the model) like this:

import uuid
from app.models import Category  # where app == tango_app_name

class Migration(migrations.Migration):

    dependencies = [
        ('yourproject', '0003_remove_category_slug'),
    ]

    def gen_uuid(apps, schema_editor):
        for row in Category.objects.all():
            row.slug = uuid.uuid4()
            row.save()

    operations = [
        migrations.AddField(
            model_name='category',
            name='slug',
            field=models.SlugField(default=uuid.uuid4),
            preserve_default=True,
        ),
        migrations.RunPython(gen_uuid),

        migrations.AlterField(
            model_name='category',
            name='slug',
            field=models.SlugField(default=uuid.uuid4, unique=True),
        ),
    ]
Bonze answered 31/3, 2015 at 16:51 Comment(5)
The first one gave me error in the admin page: u"Key 'slug' not found in 'CategoryForm'". I couldn't use uuid.uuid1 because I don't know where to import it, it gave 'uuid' is not defined.Smother
for the first problem, check this: https://mcmap.net/q/409551/-hide-fields-in-django-admin, and for 2nd, use import uuid, and for 2nd solution, don't forget to remove the last migration file from migrations directory(ie 005_add_slug.py) of the app and rerun makemigrations/migrate command.Bonze
thank you that helped, but just in case i want to add, i have to delete the last migrations files from the folder as i was still having this issue until i delete the files when i migrate the first time with the issueServiette
@Bonze This is amazing!!! Thank you soo much for this answer...it fixed my problem!Titan
I think this should be noted that sometimes drop the db or delete everything is overkill, you should check that existing data doesn't mess with the new constraint.Dagger
H
21

I got a field with attribute unique, which was not unique [eg 2-time same value]

python3 manage.py migrate --fake

then

python3 manage.py makemigrations

python3 manage.py migrate

this did the trick

Hannahannah answered 21/5, 2018 at 20:28 Comment(0)
E
3

This means a slug should be unique. You may have some data in your model. You need to delete all the data in that model and you need to migrate again.

In this situation, you have two ways to fix the error;

  1. You need to delete it from the Django admin site. More often than not, it may give an error when you are trying to open the model.

  2. Open command prompt

move to project -> py manage.py shell -> from yourappname.models import modelname -> modelname.objects.delete()

Here if you define a product manager for your model. Then you have to define a delete function. Later you should makemigrate, migrate and continue with the second way

Encumber answered 25/5, 2019 at 13:39 Comment(0)
K
1

I just met this simiilar error: Django UNIQUE constraint failed. I tried examine the code for very long time, but didn't solve it. I finally used SQLiteStudio to examine the data, and found the data is problematic: I unintentionally added two SAME instances which violates the UNIQUE constraint. To be frank I haven't thought the error could be this naive and simple, and because so it took me a lot of time to find out!

Kellum answered 23/3, 2020 at 3:32 Comment(1)
Save me a lot of time. Same thing here, everything was fine but I was messing with migrations and I tried to make something unique, but some data in the db didn't match the requirement.Dagger
W
1

I had the same problem and tried all the suggested answers. What finally worked for me was, after I defined the slug field as a URL in models, and ran the makemigrations. I edited the file in makemigrations adding a random number at the end of a basic URL, like this

Generated by Django 3.2.3 on 2022-02-02 20:58

from django.db import migrations, models from random import randint

class Migration(migrations.Migration):

dependencies = [
    ('blog', '0002_remove_post_slug1'),
]

operations = [
    migrations.AddField(
        model_name='post',
        name='slug',
        field=models.URLField(blank=True, default='http:/salpimientapa.com/' + str(randint(100000,999999))),
    ),
]

After I ran python manage.py migrate

I edit the slug as a SlugModel and ran the makemigrations and migrate again

Wolfe answered 2/2, 2022 at 21:9 Comment(0)
R
0

What worked for me was going to the admin and changing the value of duplicate slug, before running the migrations again.

Rhythmical answered 15/8, 2019 at 18:25 Comment(0)
H
0

Just delete the last migration in the migration folder

Then run

python manage.py makemigrations 
python manage.py migrate
Hammertoe answered 2/5, 2020 at 14:49 Comment(0)
J
0

I faced the same issue and solved by populating my slugfied thro' the admin with unique values and without leaving any of them blank.

Julee answered 14/1, 2021 at 14:28 Comment(0)
G
0

Basically: You add the field without unique=true in one operation, make a data migration that generates the correct shortuuids for you, and then change the field too unique again.

Gennie answered 22/2, 2021 at 6:59 Comment(0)
T
0

i have this error too , i did delete my database in djangoProject ( for example db.sqlite3 ) and then run

python manage.py makemigrations

python manage.py migrate
Touchstone answered 18/10, 2022 at 2:29 Comment(0)
C
0

It's an Integrity Error probably because the migration will temper with the already exiting data in the database. I had this error and here's what I did:

  • Enter in the project folder directory

  • Open the python interpreter

py manage.py shell

  • Import your Models

from yourappname.models import model

  • Delete existing data records in the model

model.objects.all().delete()

  • Exit the Python Interpreter

exit()

.

Another thing you could do is to set unique="false" on the affecting field. I think this should work; not so sure.

Compressor answered 26/1, 2023 at 21:38 Comment(0)
S
0

Deleting migration is not always the best way! In the event, you wish to maintain your db and want to add unique filed to an existing table. Here is a step to bypass the error and still maintain your db records.

  1. Run makemigrations
  2. Edited the migration file and removed unique=True (0039_alter_course_options_rename_created_course_timestamp_and_more).

eg: Before

 migrations.AddField(
        model_name='content',
        name='uuid',
        field=models.UUIDField(default=uuid.uuid4, unique=True),
    ),

After

 migrations.AddField(
        model_name='content',
        name='uuid',
        field=models.UUIDField(default=uuid.uuid4),
    ),
  1. Now if you migrate, it should run fine. Next, you need to update all previous records.

Create a custom managements

courses/
├── __init__.py
├── management/
│   ├── __init__.py
│   └── commands/
│       ├── __init__.py
│       └── check_uuid_uniqueness.py
├── models.py
├── ...
└── ...

Mine looks like so in the check_uuid_uniqueness.py

from django.apps import apps
from django.core.management.base import BaseCommand
import uuid

class Command(BaseCommand):
 help = 'Check the uniqueness of uuid fields in models and generate unique values if necessary.'

 def handle(self, *args, **options):
     app_name = 'courses'
     models = apps.get_app_config(app_name).get_models()

     for model in models:
         if hasattr(model, 'uuid'):
             instances = model.objects.all()
             for instance in instances:
                 list_item = instances.filter(uuid=instance.uuid)
                 if not instance.uuid or len(list_item)>1:
                     instance.uuid = uuid.uuid4()
                     instance.save()
                     print(model, ' updated: ', instance.uuid)

     self.stdout.write(self.style.SUCCESS('UUID uniqueness check completed.'))

Remember, in my case, I was targeting uuid, yours could be slug.

  1. Finally, run the custom command (make sure your python venv is activated)

python manage.py check_uuid_uniqueness

Shill answered 16/6, 2023 at 9:2 Comment(0)
F
0
python manage.py dbshell
>> DROP TABLE rango_category__new.slug;

delete associated migration file;

python manage.py makemigration
python manage.py migrate
February answered 9/8, 2023 at 14:18 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Overmeasure
M
0

For me it was that I was bulk importing 2 records with the same name, so check your import data to see if you have any duplicates

Microhenry answered 20/2 at 11:2 Comment(0)
B
0

When you encounter this error in Django, it means that you have used a field in the user model that is mandatory, but you did not provide that desired field when creating the user.

Bushman answered 2/6 at 16:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.