django-positions icon indicating copy to clipboard operation
django-positions copied to clipboard

django.db.utils.IntegrityError when migrating a Postgres database.

Open danielbraun opened this issue 10 years ago • 9 comments

Trying to upgrade a small Postgres database with the added PositionField. Using Django 1.7 with its new built-in migrations.

django.db.utils.IntegrityError: check constraint "minisites_page_position_check" is violated by some row

I eventually ditched this app and used s plain IntegerField instead (sadly)

danielbraun avatar Oct 07 '14 10:10 danielbraun

can confirm this...

bashu avatar Oct 17 '14 07:10 bashu

Same here

ghost avatar Feb 11 '15 22:02 ghost

facing same issue.

navyad avatar May 23 '15 11:05 navyad

Appears to have something to do with PositionField.get_internal_type() which reports to the database that it is a PositiveIntegerField. i think this causes a constraint to be written such that the value cannot be less than zero, which is a problem since the migration is setting the default to -1.

@jpwatts what is the benefit of overriding get_internal_type()?

smcoll avatar Jun 11 '15 15:06 smcoll

It tells the database that it's a PositiveIntegerField because all valid positions are >= 0. Negative positions are shorthand for positions relative to the end of a collection. You can use them in code, but they are supposed to be resolved to absolute positions prior to being sent to the database. It looks like that isn't happening, but I don't think the fix is to remove the database constraint—it's to make sure invalid positions don't get sent to the database in the first place.

jpwatts avatar Jun 12 '15 22:06 jpwatts

Just tested it again, and it still happens. Just to clarify, I added a new field. Is it possible that the field's definition is missing a default value?

danielbraun avatar Jun 24 '15 20:06 danielbraun

It seems that Django migrations is likely using the default value of -1 at the database level when creating the new column for existing records, which is invalid for a PositiveIntegerField

smcoll avatar Jun 24 '15 21:06 smcoll

Using kwarg default=0 seems to cause the error to go away.

Solanar avatar Nov 26 '15 04:11 Solanar

You can simply change each negative value from your Database manually or create a function for that. (incase if you are trying to SmallIntegerField() -> PositiveSmallIntegerField()

This works for me.

deepanshu-nickelfox avatar Sep 10 '20 09:09 deepanshu-nickelfox