[Fixed]-Django : ProgrammingError: column "id" does not exist


Your model definition doesn’t identify any of the fields as a primary key, therefore Django assumes a primary key column named id. However this column doesn’t actually exist in the table.

Change your model definition to designate one of the fields as a primary key, and Django won’t try to look for an id column.


class Group(models.Model) :
    name = models.CharField(max_length=30, unique=True)

    class Meta:
        abstract = True

class Projet(Group) :
    presentation = models.CharField(max_length=2500, blank=True)  

Remove your migration and create a new one.

Just adding my two cents.

Nullable fields:

Avoid using null on string-based fields such as CharField and
TextField because empty string values will always be stored as empty
strings, not as NULL. If a string-based field has null=True, that
means it has two possible values for “no data”: NULL, and the empty
string. In most cases, it’s redundant to have two possible values for
“no data;” the Django convention is to use the empty string, not NULL.

See https://docs.djangoproject.com/en/1.10/ref/models/fields/#null


If you specify a max_length attribute, it will be reflected in the
Textarea widget of the auto-generated form field. However it is not
enforced at the model or database level. Use a CharField for that.



if the id column is missing, just add the column in Postgres itself. Go to pgadmin than to the table and there create the column id.

Than back to Django makemigrations than migrate. If this will fail, delete everything in the migration folder of the app without init.py and delete everything in the folder pycache

than makemigrations followed by migrate and it should work.


I have that error happen when I try to use a third party library to upload data to the table with the keyword ‘replace’.

For instance if I use pyodbc/sqlalchemy code and pandas together like

df.to_sql(table_name, engine, if_exists='replace')

where table_name is a table in my model.py file.

I do this on initial load as well as periodically for dashboards where I want to use external sources without keeping existing data.

What pandas does is create a primary key column called ‘index’ instead of id on replace. So, then when I try to use a queryset, it says it can’t find the id field because its’ name got changed.

I don’t know if there is a way using pandas to change the index to id as the default. Perhaps a comment can add flavor. My data doesn’t have a true primary key because I have a lot of redundant data in the data for different levels of aggregation.


Do this:

  • You need to delete the table from the database.

    DROP TABLE <table>;
  • Perform migration:

    python manage.py migrate
  • If this does not help, do the migration using peewee:

    /var/venv3.8/bin/pw_migrate migrate --database=postgresql://postgres@<db>

Leave a comment