select_for_update + select_related issue

183 views
Skip to first unread message

Dmitrii Ivaniushin

unread,
Sep 23, 2020, 12:15:35 PM9/23/20
to Django users
Hello.
I just wanted to know, whether I run into a bug, and whether I should report it.

Normally select_for_update and select_related try to lock all affected rows in all tables. One can specify "of" for select_for_update to limit tables to lock (to prevent locking nullable relations).

Recently a bug was fixed, which allowed to lock parent nodes with multitable inheritance. But what about proxies? For me the following does not work. Should it?

class Parent(Model):
  foreign = ForeignKey(Foreign, null=True, blank=True)

class Child(Parent):
  class Meta:
    proxy = True

class Foreign(Model):
  pass

with transaction.atomic():
  Child.objects.select_for_update(of=('self',)).select_related('foreign').get(pk=1)

So the (pseudo) code above fails with a message "FOR UPDATE cannot be applied to the nullable side of an outer join"

So is this expected behaviour or a bug? What are possible workarounds for that?

Simon Charette

unread,
Sep 26, 2020, 7:34:10 PM9/26/20
to Django users
I don't think your issue has anything to do with proxy models.

You'll get the exact same error if your use Parent.objects instead of Child.objects as both will generate the same SQL:

SELECT *
FROM parent
LEFT JOIN foreign ON parent.foreign_id = foreign.id
FOR UPDATE OF parent

In this case "parent" cannot be selected for update since it's "foreign_id" column, which is "nullable", is implied in an outer join.

PostgreSQL simply doesn't support that and you'll have to rethink your data model if this is something you need to achieve[0]

Cheers,
Simon

Reply all
Reply to author
Forward
0 new messages