Search code examples
djangomodelsmigrate

insert or update on table "page_content_pagesection" violates foreign key constraint


I just made some changes to my Django models locally, made migrations for them, and pushed up those migrations to my production server. Everything works fine locally, but when I try and perform a migrate in the production server, I get this error. The zero index is throwing me off. The model its dependent on, teamsafetytracker is new, and page sections have never depended on it up until now, so I'm not sure why it would even be looking for instances in the teamsafetytracker table ?

django.db.utils.IntegrityError: insert or update on table "page_content_pagesection" violates foreign key constraint "page_co_safety_tracker_id_f30c4360_fk_team_teamsafetytracker_id"
DETAIL:  Key (safety_tracker_id)=(0) is not present in table "team_teamsafetytracker".

relevant migrations

class Migration(migrations.Migration):

dependencies = [
    ('team', '0037_remove_teampagesection_multi_tracker_one'),
]

operations = [
    migrations.RemoveField(
        model_name='team',
        name='safety_clock_start',
    ),
]


class Migration(migrations.Migration):

dependencies = [
    ('team', '0038_remove_team_safety_clock_start'),
    ('page_content', '0017_auto_20170926_1436'),
]

operations = [
    migrations.RemoveField(
        model_name='webpage',
        name='safety_clock_start',
    ),
    migrations.AddField(
        model_name='pagesection',
        name='multi_tracker_three',
        field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='page_multi_three', to='team.TeamSafetyTracker'),
    ),
    migrations.AddField(
        model_name='pagesection',
        name='multi_tracker_two',
        field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='page_multi_two', to='team.TeamSafetyTracker'),
    ),
    migrations.AddField(
        model_name='pagesection',
        name='tracker_side',
        field=models.CharField(choices=[(b'L', b'Left'), (b'T', b'Three Section'), (b'R', b'Right')], default=b'R', max_length=20),
    ),
    migrations.AlterField(
        model_name='pagesection',
        name='safety_tracker',
        field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='page_section', to='team.TeamSafetyTracker'),
    ),
]

Models

class TeamSafetyTracker(models.Model):
    name = models.CharField(max_length=255)

    label = models.CharField(max_length=200)

    team = models.ForeignKey('Team')

    safety_clock_start = models.DateTimeField(help_text="Date Since Last Accident. Used if You Have Page Sections That Include a Safety Tracker", null=True, blank=True)

    create_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'Team Safety Tracker'
        verbose_name_plural = 'Team Safety Trackers'

    def __str__(self):
        return self.name

class PageSection(models.Model):
    page = models.ForeignKey(WebPage)
    title = models.CharField(max_length=255, null=True, blank=True)
    content = models.TextField(null=True, blank=True)

    has_gallery = models.BooleanField(default=False)
    gallery = models.ForeignKey('PhotoGallery', null=True, blank=True)

    safety_tracker = models.ForeignKey(TeamSafetyTracker, related_name='page_section', null=True, blank=True)

    multi_tracker_two = models.ForeignKey(TeamSafetyTracker, related_name='page_multi_two', null=True, blank=True)
    multi_tracker_three = models.ForeignKey(TeamSafetyTracker, related_name='page_multi_three', null=True, blank=True)

    tracker_side = models.CharField(max_length=20, choices=TRACKER_SIDES, default='R')

    background_choices = models.CharField(max_length=100, choices=BACKGROUND_CHOICES, default='WH')

    display_order = models.IntegerField(default=1)
    is_published = models.BooleanField(default=True)

    def __str__(self):
        return ('Section %s') % self.display_order

    class Meta:
        verbose_name = 'Section'
        verbose_name_plural = 'Sections'
        ordering = ('display_order',)

    def gallery_sets(self):
        if self.gallery:
            gallery_photos = self.gallery.photos.filter(is_published=True)

            set_1 = gallery_photos[:10]

            gallery_sets = [set_1]

            if gallery_photos.count() > 10:
                set_2 = gallery_photos[10:20]
                gallery_sets.append(set_2)

            if gallery_photos.count() > 20:
                set_3 = gallery_photos[20:30]
                gallery_sets.append(set_3)

            if gallery_photos.count() > 30:
                set_4 = gallery_photos[30:40]
                gallery_sets.append(set_4)

            if gallery_photos.count() > 40:
                set_5 = gallery_photos[40:50]
                gallery_sets.append(set_5)

            return gallery_sets
        else:
            return []

    @staticmethod
    def get_published_objects():
        objects = PageSection.objects.filter(is_published=True).order_by('display_order')

        return objects

Traceback

Running migrations:
  Rendering model states... DONE
  Applying team.0032_teamsafetytracker... OK
  Applying team.0033_auto_20180306_1928... OK
  Applying team.0034_auto_20180306_1942... OK
  Applying team.0035_auto_20180306_1944... OK
  Applying team.0036_auto_20180306_1953... OK
  Applying team.0037_remove_teampagesection_multi_tracker_one... OK
  Applying team.0038_remove_team_safety_clock_start... OK
  Applying page_content.0018_auto_20180307_1851...Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.IntegrityError: insert or update on table "page_content_pagesection" violates foreign key constraint "page_co_safety_tracker_id_f30c4360_fk_team_teamsafetytracker_id"
DETAIL:  Key (safety_tracker_id)=(0) is not present in table "team_teamsafetytracker".


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 399, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/migrate.py", line 200, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/executor.py", line 92, in migrate
    self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/executor.py", line 198, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/migration.py", line 123, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/operations/fields.py", line 201, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/schema.py", line 482, in alter_field
    old_db_params, new_db_params, strict)
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/postgresql/schema.py", line 116, in _alter_field
    new_db_params, strict,
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/schema.py", line 717, in _alter_field
    self.execute(self._create_fk_sql(model, new_field, "_fk_%(to_table)s_%(to_column)s"))
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/schema.py", line 110, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.5/dist-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python3.5/dist-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: insert or update on table "page_content_pagesection" violates foreign key constraint "page_co_safety_tracker_id_f30c4360_fk_team_teamsafetytracker_id"
DETAIL:  Key (safety_tracker_id)=(0) is not present in table "team_teamsafetytracker".

Solution

  • This seems to be a problem of old values in that Pagesection table ie. there is a PageSection entry where the safety_tracker is already 0 (This field was previously an IntegerField). When you changed it to a ForeignKey to TeamSafetyTracker Django tried to match that old values with a TeamSafetyTracker ID.

    Make sure all the values of the column safety_tracker are set to null before running the page_content.0018_auto_20180307_1851 migration. You can create a custom migration to do that.