0. Do Django models support composite primary key?
https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys
Django doesn’t officially support composite primary key.
If there is no field for which “primary_key = True” is specified, “id” will be automatically added as the primary key. So if you are using the DB of the legacy system, “update” and “delete” method do not work. You have to add “id” field to your tables or to make your own SQL query.
1. Solutions
Proposal 1:Add a surrogate key
If I add a surrogate key (‘id’) to the DB and put a unique constraint (unique_together) on the composite key, I can use the Django model as it is.
(Problems) DB rebuild takes time and requires planned outage.
Proposal 2:Implement with your own query
Make my own query-write implementation without relying on ORM. I can control the performance of queries by myself.
(Problems) More code and test.
Proposal 3:Extend Django Model
It seems that it was also considered in the Django project, but I’m not sure recent status.
https://code.djangoproject.com/ticket/373
https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys#CurrentStatus
It seems that some people have tried various ways, but in the end, are they all unfinished?
For the time being, by extending the model myself, create a subclass of Model so that I can use it for my own work. It’s not necessary to cover all the features of Django, so it seems possible to cover the INSERT, UPDATE, and DELETE of the standalone mode I need.
(Problems) Understand the code of the current model.
Proposal 4:Make another ORM
When I read the code around the model, I felt a bit spaghetti smell. Looking at the implementation, I felt that the roles in Model, Manager, and QuerySet weren’t clearly separated. I think it’s another option to make my own simple ORM, including support for composite primary key.
(Problems) I don’t have enough time!
Proposal 5:Use another existing ORM
Is the below not supporting the primary key, only for the composite foreign key?
https://github.com/Arisophy/django-composite-foreignkey
(Problems) I haven’t found the right one yet!
2. Conclusion
My current project is gradually migrating a legacy system built with Ruby On Rails to Django. So I don’t want to touch the DB.
In conclusion, I decided to proceed with Proposal 2 and 3.
INSERT,UPDATE,DELETE will be supported by the extension class of Model in Proposal 3. When I actually made it, it worked nicely with a small amount of code. I will proceed with the project while using the extended model.
For SELECT, I can’t rely entirely on the ORM, so I’ll also use my own query.
I will post how I created the extension class at a later.
(2021/01/29)
The extension classes are published below.
https://github.com/Arisophy/django-compositepk-model
(2021/03/16)
My opinion about ticket#373 is below.