@@ -111,12 +111,13 @@ def sync_kc_user(self, kc_user: ch_models.User, is_superuser=False, delete=False
111111 if not username :
112112 raise ValueError (f"Keycloak user { kc_user .id } has no username or email" )
113113
114- # Create user and member atomically
115- user , user_created = User .objects .get_or_create (username = username )
114+ # Create user and member atomically. Pin to the primary DB so lookups
115+ # see our own uncommitted writes when a read replica is configured.
116+ user , user_created = User .objects .using ("default" ).get_or_create (username = username )
116117
117118 # CRITICAL: Ensure Member exists before proceeding
118119 try :
119- member = Member .objects .get (user = user )
120+ member = Member .objects .using ( "default" ). get (user = user )
120121 # Member exists but might have wrong kc_id
121122 if member .kc_id != kc_user .id :
122123 member .kc_id = kc_user .id
@@ -133,8 +134,8 @@ def sync_kc_user(self, kc_user: ch_models.User, is_superuser=False, delete=False
133134 # FINAL SAFETY CHECK: Verify Member exists before returning
134135 # This ensures we never return a user without a Member
135136 try :
136- _ = user . member # Access member to trigger DoesNotExist if missing
137- except :
137+ _ = Member . objects . using ( "default" ). get ( user = user )
138+ except Member . DoesNotExist :
138139 # This should never happen, but if it does, create Member immediately
139140 Member .objects .create (kc_id = kc_user .id , user = user )
140141
@@ -159,9 +160,10 @@ def sync_kc_user_groups(self, kc_user: ch_models.User, user: User = None):
159160 # Sync organization memberships separately
160161 self .sync_kc_user_organizations (kc_user , user = user )
161162
162- # Ensure the member relationship exists and is correct
163+ # Ensure the member relationship exists and is correct. Use the primary
164+ # DB so we see our own uncommitted writes when a read replica is configured.
163165 try :
164- member = user . member
166+ member = Member . objects . using ( "default" ). get ( user = user )
165167 if member .kc_id != kc_user .id :
166168 member .kc_id = kc_user .id
167169 member .save ()
@@ -180,17 +182,18 @@ def sync_kc_organization(self, kc_org: ch_models.Organization) -> Organization:
180182 """
181183 org = None
182184
183- # First try to find by kc_id
185+ # First try to find by kc_id. Pin to the primary DB so lookups see our
186+ # own uncommitted writes when a read replica is configured.
184187 try :
185- org = Organization .objects .get (kc_id = kc_org .id )
188+ org = Organization .objects .using ( "default" ). get (kc_id = kc_org .id )
186189 # Update name if changed
187190 if org .name != kc_org .name :
188191 org .name = kc_org .name
189192 org .save ()
190193 except Organization .DoesNotExist :
191194 # Try to find by name (for organizations created without kc_id)
192195 try :
193- org = Organization .objects .get (name = kc_org .name , kc_id__isnull = True )
196+ org = Organization .objects .using ( "default" ). get (name = kc_org .name , kc_id__isnull = True )
194197 # Update with kc_id from Keycloak
195198 org .kc_id = kc_org .id
196199 org .save ()
@@ -224,14 +227,15 @@ def sync_kc_user_organizations(self, kc_user: ch_models.User, user: User = None)
224227 org = self .sync_kc_organization (kc_org )
225228 current_org_ids .add (org .id )
226229
227- # Create membership if it doesn't exist
228- OrganizationMember .objects .get_or_create (
229- user = user ,
230- organization = org
231- )
230+ # Create membership if it doesn't exist. Pin to primary so the
231+ # existence check sees writes from earlier in this transaction.
232+ try :
233+ OrganizationMember .objects .using ("default" ).get (user = user , organization = org )
234+ except OrganizationMember .DoesNotExist :
235+ OrganizationMember .objects .create (user = user , organization = org )
232236
233237 # Remove memberships that no longer exist in Keycloak
234- OrganizationMember .objects .filter (user = user ).exclude (
238+ OrganizationMember .objects .using ( "default" ). filter (user = user ).exclude (
235239 organization_id__in = current_org_ids
236240 ).delete ()
237241
0 commit comments