Deprecation of using pk in public ORM API

132 views
Skip to first unread message

Albert

unread,
Jan 27, 2022, 6:19:21 PM1/27/22
to django-d...@googlegroups.com

Hello all,

I would like to know your opinion about deprecation of using "pk"
alias in filters and other places of public ORM API.
I use Django long time and never use "pk" because in my opinion
it is misleading.
I mean, instead:
Car.objects.filter(pk=1)
I use
Car.objects.filter(id=1)
Insted car.pk I use car.id

From SQL point of view it doesn't matter because it is always:
SELECT * FROM car WHERE id=1

It am not sure if using "pk" gives value to users. Field "pk" is not
defined by user.

But from our, django developers, point of view we need to do extra work to
support it.

I think that "pk" could be only a private attribute of a model
("_pk") and only for internal use or avoid using it at all.
I think it would give us more flexibility to develop/improve orm.

What do you think?

Regards,
Albert Defler

Curtis Maloney

unread,
Jan 27, 2022, 6:25:09 PM1/27/22
to 'Mike Hansen' via Django developers (Contributions to Django itself)
Hello Mike,

On Wed, 26 Jan 2022, at 20:46, Albert wrote:

Hello all,

I would like to know your opinion about deprecation of using "pk"
alias in filters and other places of public ORM API.
I use Django long time and never use "pk" because in my opinion
it is misleading.
I mean, instead:
Car.objects.filter(pk=1)
I use
Car.objects.filter(id=1)
Insted car.pk I use car.id

AIUI the purpose of the `pk` alias is you can't assume the primary key will always be named `id`.

Knowing you can always refer to `pk` allows more generic query construction.

This is used, for example, in the generic views.


From SQL point of view it doesn't matter because it is always:
SELECT * FROM car WHERE id=1

It am not sure if using "pk" gives value to users. Field "pk" is not
defined by user.

No, but the model's primary key field might be, which is the point.

--
Curtis

Albert

unread,
Feb 1, 2022, 6:31:19 AM2/1/22
to django-d...@googlegroups.com, Curtis Maloney
Thank you for response.

Now i see that it is not so easy as I thought.
It is used in many other places in Django and probably also in django rest framework and other third parties libraries.


Daryl

unread,
Feb 1, 2022, 1:52:45 PM2/1/22
to django-d...@googlegroups.com
Hi Albert,

I think you are going in the wrong direction here; We should leave the 'pk' alias in place, not because it would be hard to remove, and not because it exists in many places, but because aliasing is a stonking great idea.

It exists in many places for precisely that reason ; its such a great idea that almost every subsystem uses, or at least offers, aliasing in some way.

To successfully argue that having a 'pk' alias is a negative feature of the code base, you would have to also convince all the MySQL, MSSQL, Oracle and PostgreSQL devs , plus all the other framework devs, that aliasing is a bad thing, and that would be a herculean task.

However, you have already reaped the rewards of your investigation; which is a greater understanding of the code base, and how the awesomeness of aliasing is used in Django, and you can now apply the pattern to many other situations.

D



--
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/hpkfxawtvfvrsbioliha%40erjj.


======================

Albert

unread,
Feb 2, 2022, 5:31:28 PM2/2/22
to django-d...@googlegroups.com
Hi Daryl,

I agree and disagree with you, it depends on place and context of using "pk" alias :)

I am not sure if it is good in filter and as object attribute. For our internal use we could use "_pk" or other name.

You motivated me to check one thing.

class Car(models.Model):
    pk = models.IntegerField(primary_key=True)

(fields.E003) 'pk' is a reserved word that cannot be used as a field name.

That is because we implicity create "pk" field (what is against The Zen of Python - Explicit is better than implicit ;))
and it is used in public api and internally.

Basic idea, introduced at the beginning of Django (16 years ago), assumes that every table has primary key. What is not true in real life.

If we released this, developers could create (if they like generic):

class ModelA(models.Model):
    pk = models.IntegerField(primary_key=True, db_column="id")

class ModelB(models.Model):
    pk = models.CharField(max_length=10, primary_key=True, db_column="name")

class ModelC(models.Model):
    pk = models.DateTimeField(primary_key=True, db_column="created_on")

and can filter by "pk" or use as object attribute as they do now.

This is more flexible from our point of view. This also allow create models without prlmary key. Models could have method or property "has_primary_key" that will return True or False
or "get_primary_key" which could return None if PK doesn't exist otherwise dictionary {<field name>: <field value>}. I think that something like this is used internally.

Of course it would involve changes in other parts of Django like generic views, admin panel etc. But step by step we could improve it.

Until we allow users use "pk" alias, created implicity, in filters (public orm api) and as object attribute we have hands tied.
Reply all
Reply to author
Forward
0 new messages