Skip to content
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

MPP-2503: Change Profile.user to OneToOneField #2749

Merged
merged 2 commits into from
Nov 9, 2022

Conversation

jwhitlock
Copy link
Member

Note: This will fail CircleCI migration tests until 2022.11.02 is in production

Change Profile.user from ForeignKey to OneToOneField, to fix issue #2708 / MPP-2503. This requires some follow-on changes:

  • Change user.profile_set.get() to user.profile
  • Change prefetch_related_objects('profile_set') to prefetch_related_objects('profile')
  • Remove ManyProfileDetector (no longer possible)
  • Drop ./manage.py cleanup_data --many-profiles

Also makes some changes suggested by flake8, such as removing unused imports.

@jwhitlock jwhitlock added the 🛑 Do Not Merge Do not merge this PR, even if approved. label Nov 2, 2022
@jwhitlock jwhitlock marked this pull request as draft November 2, 2022 19:35
@netlify
Copy link

netlify bot commented Nov 2, 2022

Deploy Preview for fx-relay-demo canceled.

Name Link
🔨 Latest commit 623bfda
🔍 Latest deploy log https://app.netlify.com/sites/fx-relay-demo/deploys/636c210c3c86dc000a7042c9

@jwhitlock jwhitlock force-pushed the profile-user-one-to-one-2708 branch 2 times, most recently from 426385d to a09fd3c Compare November 9, 2022 00:04
@jwhitlock jwhitlock marked this pull request as ready for review November 9, 2022 00:12
@jwhitlock jwhitlock force-pushed the profile-user-one-to-one-2708 branch from a09fd3c to a100cc2 Compare November 9, 2022 00:13
@jwhitlock jwhitlock added Review: S Code review time: 30 mins to 1 hour and removed 🛑 Do Not Merge Do not merge this PR, even if approved. labels Nov 9, 2022
@jwhitlock jwhitlock requested a review from groovecoder November 9, 2022 00:14
Copy link
Member

@groovecoder groovecoder left a comment

Choose a reason for hiding this comment

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

Code and spot-checks look good! 1 non-blocking question.

@@ -215,66 +215,3 @@ def markdown_report(self) -> str:
)

return "\n".join(lines)


class ManyProfileDetector(DetectorTask):
Copy link
Member

Choose a reason for hiding this comment

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

praise: 🪓

@@ -217,21 +217,21 @@ def test_sns_message_with_hard_bounce(self):

_sns_notification(BOUNCE_SNS_BODIES["hard"])

profile = self.user.profile_set.get()
assert profile.last_hard_bounce >= pre_request_datetime
self.user.refresh_from_db()
Copy link
Member

Choose a reason for hiding this comment

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

question (non-blocking): does refresh_from_db() also refresh related field data? Looks like most of these tests are written such that they might pass even if the data was stale?

Copy link
Member Author

Choose a reason for hiding this comment

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

I had to go prove it to myself, but yes it does. This part of the docs wasn't clear to me:

If you need to reload a model’s values from the database, you can use the refresh_from_db() method. When this method is called without arguments the following is done:

  1. All non-deferred fields of the model are updated to the values currently present in the database.
  2. Any cached relations are cleared from the reloaded instance.

I had to play around in ./manage.py shell to see how it worked:

>>> from django.contrib.auth.models import User
>>> from emails.models import Profile
>>> user = User.objects.latest("date_joined")
>>> profile = user.profile
>>> user.profile.num_address_deleted
0
>>> profile.num_address_deleted
0
>>> # The two are now distinct objects
>>> user.profile.num_address_deleted = 10
>>> profile.num_address_deleted
0
>>> user.profile.save()
>>> profile.num_address_deleted
0
>>> profile.refresh_from_db()
>>> profile.num_address_deleted
10
>>> # Going the other way...
>>> profile.num_address_deleted = 20
>>> profile.save()
>>> user.profile.num_address_deleted
10
>>> # This clears user.profile from the cached relations
>>> user.refresh_from_db()
>>> # And this loads the profile from the database
>>> user.profile.num_address_deleted
20

Change Profile.user from ForeignKey to OneToOneField. Make follow-on
changes:

* Change user.profile_set.get() to user.profile
* Change prefetch_related_objects('profile_set') to profile
* Remove ManyProfileDetector (no longer possible)
* Drop ./manage.py cleanup_data --many-profiles
@groovecoder groovecoder force-pushed the profile-user-one-to-one-2708 branch from a100cc2 to 623bfda Compare November 9, 2022 21:52
@jwhitlock jwhitlock merged commit b394a96 into main Nov 9, 2022
@jwhitlock jwhitlock deleted the profile-user-one-to-one-2708 branch November 9, 2022 22:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review: S Code review time: 30 mins to 1 hour
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants