Search code examples
pythondjangodatabasepsql

Django - Created a web app which is linked to my PSQL, but when inserting data to one of my tables gives error for no ID


I have a table where it has only two columns being exercise_id and muscle_id

create table if not exists exercise_muscle(
    exercise_id INT not null,
    muscle_id INT not null,
    primary key (exercise_id, muscle_id),
    foreign key (exercise_id) references exercise(exercise_id),
    foreign key (muscle_id) references muscle(muscle_id)
);

But when I try and insert data into this with the model seen below

class ExerciseMuscle(models.Model):
    exercise = models.ForeignKey('Exercise', on_delete=models.CASCADE)
    muscle = models.ForeignKey('Muscle', on_delete=models.CASCADE)

    class Meta:
        db_table = 'exercise_muscle'
        unique_together = ('exercise', 'muscle')

I get this error where it tries to return exercise_muscle.id, which doesn't exist

django.db.utils.ProgrammingError: column exercise_muscle.id does not exist
LINE 1: ...xercise_id", "muscle_id") VALUES (1, 1) RETURNING "exercise_...

I have also checked my django dbshell and it looks all fine

\d exercise_muscle
             Table "public.exercise_muscle"
   Column    |  Type   | Collation | Nullable | Default 
-------------+---------+-----------+----------+---------
 exercise_id | integer |           | not null | 
 muscle_id   | integer |           | not null | 
Indexes:
    "exercise_muscle_pkey" PRIMARY KEY, btree (exercise_id, muscle_id)
Foreign-key constraints:
    "exercise_muscle_muscle_id_fkey" FOREIGN KEY (muscle_id) REFERENCES muscle(muscle_id)

And checked my psql table and it doesn't have an id column


Solution

  • Multiple column primary keys are not supported by Django.

    Do Django models support multiple-column primary keys?

    No. Only single-column primary keys are supported.

    But this isn’t an issue in practice, because there’s nothing stopping you from adding other constraints (using the unique_together model option or creating the constraint directly in your database), and enforcing the uniqueness at that level. Single-column primary keys are needed for things such as the admin interface to work; e.g., you need a single value to specify an object to edit or delete.

    Also see: https://stackoverflow.com/a/61320607/9313033

    Django expects a single primary key field. If you don't declare a PK field in the model declaration, Django will add a default AutoField called id when creating the migration for the model. You didn't declare a PK field, so Django expects the default. But the default field doesn't exist since you created the table by hand instead of by running the migrations.

    Either add the primary key id field yourself by hand, or drop the table entirely and let Django create it by running python manage.py makemigrations followed by python manage.py migrate.