Search code examples
djangodjango-modelsforeign-keysprimary-keymigrate

Problem with ForeignKey, Django migrations


When I tried to migrate my project to a different version I faced this error:

ProgrammingError: ERROR: the id column specified in the foreign key constraint does not exist.

UPDATE: This is the full log: The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 23, in <module>
    execute_from_command_line(sys.argv)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/core/management/base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 200, in handle
    fake_initial=fake_initial,
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/migrations/migration.py", line 122, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 216, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 525, in alter_field
    old_db_params, new_db_params, strict)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/postgresql/schema.py", line 122, in _alter_field
    new_db_params, strict,
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 750, in _alter_field
    self.execute(self._create_fk_sql(model, new_field, "_fk_%(to_table)s_%(to_column)s"))
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 133, in execute
    cursor.execute(sql, params)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/user/MyProjects/forest-venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)

But I don't have an id column in my model:

from django.db import models
from django.utils.translation import ugettext_lazy as _
from renter.models import RefAbstract, Renter
from django.contrib.gis.db import models
from textwrap import shorten
 
    
class Unitt(RefAbstract):
   ....//some classes
class Task(RefAbstract):
    class Meta(RefAbstract.Meta):
        verbose_name = 'task'
        verbose_name_plural = 'tasks'

class Spatial(models.Model):
    codeq = models.IntegerField('no',help_text='no') 
    code = models.PositiveIntegerField('cutare',primary_key=True,help_text='cutare')//unique column
    codeV = models.IntegerField('novi',help_text='novi') 
    renter = models.ForeignKey(Renter, on_delete=models.DO_NOTHING, verbose_name='renter')
    geometry = models.MultiPolygonField(geography=True, verbose_name='geometry')
   
    class Meta:
        verbose_name = 'cutarea'
        verbose_name_plural = 'cutarea'


class LScharacteristic(models.Model):
    codels = models.ForeignKey(Spatial, on_delete=models.DO_NOTHING, verbose_name = 'cutarea')// Foreign Key
    tract = models.CharField('tract',max_length = 80, help_text='tract') 
    task = models.ForeignKey(Task,  on_delete=models.DO_NOTHING, verbose_name='task')
    totalarea = models.PositiveIntegerField('totarea',help_text = 'totarea')
    explarea = models.PositiveIntegerField('exarea',help_text = 'exarea')
    protecttype = models.CharField('category',max_length = 50, help_text = 'category')

    class Meta:
        verbose_name = 'characteristic'
        verbose_name_plural = 'characteristics'

class PlannedUsing(models.Model):
    codels = models.ForeignKey(Spatial, on_delete=models.DO_NOTHING, verbose_name = 'cutarea') // Foreign Key   
    codeq = models.IntegerField(help_text='number')
    cutareaShape = models.ForeignKey(CutareaShape, on_delete=models.DO_NOTHING, verbose_name='form')
    cuttype = models.ForeignKey(CutareaType, on_delete=models.DO_NOTHING, verbose_name='type1')
    managetype = models.ForeignKey(ManageType, on_delete=models.DO_NOTHING, verbose_name='type2')
    unit = models.ForeignKey(Unitt, on_delete=models.DO_NOTHING, verbose_name='unit')
    composition = models.ForeignKey(Composition, on_delete=models.DO_NOTHING, verbose_name='sort')
    assortment = models.ForeignKey(Assortment, on_delete=models.DO_NOTHING, verbose_name='assort')

    class Meta:
        verbose_name = 'planus'
        verbose_name_plural = 'planuss'

What is the id column and why does it exist if I never defined it? How I can to fix this?


Solution

  • I think that the problem is that your ForeignKey fields do not point explicitly to the field that you have marked as primary (Spatial.code). By marking Spatial.code as primary you prevent Django from creating the id field. See the documentation But if you point a ForeignKey to just a model it will try to link to the id field of that model. To fix this you can add to your ForeignKey field the parameter: to_field='code' and add unique=True to Spatial.code.See documentation