Skip to content

Ticket 36472: Addressed issues with create() and save() on a model with GeneratedField(primary_key=True) #19580

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

shangxiao
Copy link
Contributor

@shangxiao shangxiao commented Jun 19, 2025

Trac ticket number

ticket-36472

Branch description

Looking at some possible fixes to see whether supporting GeneratedField(primary_key=True) can be elegantly patched.

PR broken into a couple of sensible commits:

  • Protect against possible None that get_ancestor_link() may indeed return
  • Prevent infinite recursion of a deferred attribute (via _is_pk_set() -> _get_pk_val() -> back to deferred attribute again) if the field itself is a pk
  • (unsure of this patch but this fixes create()) Use None if AttributeError from DeferredAttribute
  • (unsure of this patch but found this using save() -- this one may actually be a separate issue as this was more of a why empty string for an integer field??) _get_default() returns empty string ("") as the default if none of the other conditions are satisfied, this will break a non-string column. Not sure why deferring to _get_default() is used if NOT_PROVIDED is set 🤔
  • I was thinking we may not need a feature flag but I can't see any other way to skip Maria & SQLite

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

@github-actions github-actions bot added the no ticket Based on PR title, no linked Trac ticket label Jun 19, 2025
@shangxiao shangxiao force-pushed the ticket-36472 branch 4 times, most recently from 4e28820 to f82c8ac Compare June 19, 2025 23:13
Comment on lines 677 to 680
return getattr(self, meta.pk.attname)
try:
return getattr(self, meta.pk.attname)
except AttributeError:
return None
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may need to be removed and dealt with further up the stack... for databases that don't support RETURNING like mysql then a generated pk shouldn't return None but instead continue to raise AttributeError.

if not instance._is_pk_set():
if self.field.primary_key or not instance._is_pk_set():
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually we should be able to write a simple test for this, we should get an AttributeError instead of infinite recursion:

foo = Foo(value=1)
with self.assertRaises(AttributeError):
    foo.generated_value 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realised that self.field.primary_key will not work if it's part of a composite key, which may need to be addressed separately in PR #19569

@shangxiao shangxiao force-pushed the ticket-36472 branch 2 times, most recently from d8e0f24 to 731ab45 Compare June 21, 2025 18:24
@shangxiao shangxiao changed the title (Draft) Ticket 36472 Addressed issues with create() and save() on a model with GeneratedField(primary_key=True) Ticket 36472: Addressed issues with create() and save() on a model with GeneratedField(primary_key=True) Jun 21, 2025
@shangxiao shangxiao marked this pull request as ready for review June 21, 2025 21:11
@shangxiao
Copy link
Contributor Author

buildbot, test on oracle.

@shangxiao shangxiao removed the no ticket Based on PR title, no linked Trac ticket label Jun 21, 2025
setattr(self, meta.pk.attname, pk_val)
pk_set = self._is_pk_set(meta)
# if pk is deferred then this will raise an AttributeError
except AttributeError:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the right approach then we should use a custom exception class so as not mask bugs:

class ModelAttributeError(AttributeError):
    pass

Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants