models.E026: The model cannot have more than one field with primary_key=True.

1,559 views
Skip to first unread message

Marcin Nowak

unread,
Apr 1, 2020, 6:34:53 AM4/1/20
to Django developers (Contributions to Django itself)
Hi.

I'd ask about  "models.E026: The model cannot have more than one field with primary_key=True".
It's not a true. The table or view can have more than one column as a part of a primary key.
It's pretty common, when you have views with cross joins or unpivots.

I can add models.E026 to silenced system checks, but Django is mapping PK to the first field of the complex primary keys. This can introduce some issues.

I know that supporting complex PKs is hard and generally unsupported, but how about removing auto-mapping ".pk" attribute for models with complex primary key
As a result there will be no possibility to declare foreign keys to such models, but there will be possibility to change E026to W0nn (just a warning).

Regards,
Marcin

Adam Johnson

unread,
Apr 1, 2020, 7:04:26 AM4/1/20
to django-d...@googlegroups.com
Hi Marcin

Multiple column primary keys is a long-open feature request. There's a wiki page: https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys and the ticket, still open, is #373: https://code.djangoproject.com/ticket/373 .

I'm not sure your suggestion of removing the ".pk" mapping will either be easy ("pk" is used a LOT throughout the ORM, not just for foreign keys), or really help you very much (how would insertions really work, etc.)

I've thought of a technique before for making composite PK's work, though haven't tested it. It should be possible to put a database view in front of your table that combines your primary key columns into one string. For example:

CREATE VIEW book_view AS SELECT CONCAT(catalogue_id, '-', book_id) AS primary_key, author_id, ... FROM book;

Then define your model as having a CharField as a primary key. PostgreSQL and MariaDB/MySQL will both automatically make single-table views map inserts and updates to the underlying table. Though you might need a trigger to allow inserts (new object saves) to work, splitting the parts back out.

If you try this, let me know.

Thanks,

Adam

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/7b948901-e643-4bd0-917a-54ff7a18e9f9%40googlegroups.com.


--
Adam

Marcin Nowak

unread,
Apr 1, 2020, 7:07:47 AM4/1/20
to Django developers (Contributions to Django itself)
Good point about concat. Thanks.
I think that introducing views in Django solve such issues (probably no pk in views will be allowed).

PS. I'll discuss this (and the 2nd topic) later, because I'm quite busy today. Thanks again for the hint.


W dniu środa, 1 kwietnia 2020 13:04:26 UTC+2 użytkownik Adam Johnson napisał:
Hi Marcin

Multiple column primary keys is a long-open feature request. There's a wiki page: https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys and the ticket, still open, is #373: https://code.djangoproject.com/ticket/373 .

I'm not sure your suggestion of removing the ".pk" mapping will either be easy ("pk" is used a LOT throughout the ORM, not just for foreign keys), or really help you very much (how would insertions really work, etc.)

I've thought of a technique before for making composite PK's work, though haven't tested it. It should be possible to put a database view in front of your table that combines your primary key columns into one string. For example:

CREATE VIEW book_view AS SELECT CONCAT(catalogue_id, '-', book_id) AS primary_key, author_id, ... FROM book;

Then define your model as having a CharField as a primary key. PostgreSQL and MariaDB/MySQL will both automatically make single-table views map inserts and updates to the underlying table. Though you might need a trigger to allow inserts (new object saves) to work, splitting the parts back out.

If you try this, let me know.

Thanks,

Adam

On Wed, 1 Apr 2020 at 11:34, Marcin Nowak <marcin...@gmail.com> wrote:
Hi.

I'd ask about  "models.E026: The model cannot have more than one field with primary_key=True".
It's not a true. The table or view can have more than one column as a part of a primary key.
It's pretty common, when you have views with cross joins or unpivots.

I can add models.E026 to silenced system checks, but Django is mapping PK to the first field of the complex primary keys. This can introduce some issues.

I know that supporting complex PKs is hard and generally unsupported, but how about removing auto-mapping ".pk" attribute for models with complex primary key
As a result there will be no possibility to declare foreign keys to such models, but there will be possibility to change E026to W0nn (just a warning).

Regards,
Marcin

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-d...@googlegroups.com.


--
Adam
Reply all
Reply to author
Forward
0 new messages