11"""Migration commands helper methods."""
22
33from typing import Any
4+ import logging
45
56from django .contrib .auth .models import User # pylint: disable=E5142
67from django .core .management .base import OutputWrapper
2526from forum .utils import make_aware , get_trunc_title
2627
2728
29+ logger = logging .getLogger (__name__ )
30+
31+
2832def get_user_or_none (user_id : Any ) -> User | None :
2933 """Get a user by ID or return None if not found."""
3034 try :
@@ -125,15 +129,39 @@ def create_or_update_comment(comment_data: dict[str, Any]) -> None:
125129 if not author :
126130 return
127131 mongo_thread_id = str (comment_data ["comment_thread_id" ])
128- mongo_thread = MongoContent .objects .get (mongo_id = mongo_thread_id )
129- thread = CommentThread .objects .get (pk = mongo_thread .content_object_id )
132+ mongo_thread = MongoContent .objects .filter (mongo_id = mongo_thread_id ).first ()
133+ if not mongo_thread :
134+ logger .warning (
135+ f"Thread mapping not found for comment { comment_data .get ('_id' )} "
136+ f"(mongo_thread_id={ mongo_thread_id } )"
137+ )
138+ return
139+ thread = CommentThread .objects .filter (pk = mongo_thread .content_object_id ).first ()
140+ if not thread :
141+ logger .warning (
142+ f"Skipping comment { comment_data .get ('_id' )} : thread object not found "
143+ f"(content_object_id={ mongo_thread .content_object_id } )"
144+ )
145+ return
130146 parent = None
131147 if "parent_id" in comment_data and comment_data ["parent_id" ] != "None" :
132148 parent_id = str (comment_data ["parent_id" ])
133- mongo_parent_comment = MongoContent .objects .get (mongo_id = parent_id )
149+ mongo_parent_comment = MongoContent .objects .filter (mongo_id = parent_id ).first ()
150+ if not mongo_parent_comment :
151+ logger .warning (
152+ f"Parent mapping not found for comment { comment_data .get ('_id' )} "
153+ f"(parent_id={ parent_id } )"
154+ )
155+ return
134156 parent = Comment .objects .filter (
135157 id = mongo_parent_comment .content_object_id
136158 ).first ()
159+ if not parent :
160+ logger .warning (
161+ f"Skipping comment { comment_data .get ('_id' )} : parent object not found "
162+ f"(parent_content_object_id={ mongo_parent_comment .content_object_id } )"
163+ )
164+ return
137165
138166 mongo_comment , _ = MongoContent .objects .get_or_create (
139167 mongo_id = str (comment_data ["_id" ])
@@ -186,8 +214,21 @@ def create_or_update_edit_history(content: dict[str, Any]) -> None:
186214 """Create or update edit history for a content."""
187215 edit_history = content .get ("edit_history" , [])
188216 content_type = CommentThread if content ["_type" ] == "CommentThread" else Comment
189- mongo_content = MongoContent .objects .get (mongo_id = str (content ["_id" ]))
190- content_object = content_type .objects .get (pk = mongo_content .content_object_id )
217+ mongo_content = MongoContent .objects .filter (mongo_id = str (content ["_id" ])).first ()
218+ if not mongo_content :
219+ logger .warning (
220+ f"Skipping edit history for content { content .get ('_id' )} : mapping not found"
221+ )
222+ return
223+ content_object = content_type .objects .filter (
224+ pk = mongo_content .content_object_id
225+ ).first ()
226+ if not content_object :
227+ logger .warning (
228+ f"Skipping edit history for content { content .get ('_id' )} : target object not found "
229+ f"(content_object_id={ mongo_content .content_object_id } )"
230+ )
231+ return
191232 for edit in edit_history :
192233 editor = get_user_or_none (edit ["author_id" ])
193234 if not editor :
@@ -207,8 +248,21 @@ def create_or_update_edit_history(content: dict[str, Any]) -> None:
207248def create_or_update_abuse_flaggers (content : dict [str , Any ]) -> None :
208249 """Create or update abuse flaggers for content."""
209250 content_type = CommentThread if content ["_type" ] == "CommentThread" else Comment
210- mongo_content = MongoContent .objects .get (mongo_id = str (content ["_id" ]))
211- content_object = content_type .objects .get (pk = mongo_content .content_object_id )
251+ mongo_content = MongoContent .objects .filter (mongo_id = str (content ["_id" ])).first ()
252+ if not mongo_content :
253+ logger .warning (
254+ f"Skipping abuse flaggers for content { content .get ('_id' )} : mapping not found"
255+ )
256+ return
257+ content_object = content_type .objects .filter (
258+ pk = mongo_content .content_object_id
259+ ).first ()
260+ if not content_object :
261+ logger .warning (
262+ f"Skipping abuse flaggers for content { content .get ('_id' )} : target object not found "
263+ f"(content_object_id={ mongo_content .content_object_id } )"
264+ )
265+ return
212266 for user_id in content ["abuse_flaggers" ]:
213267 user = get_user_or_none (user_id )
214268 if not user :
@@ -245,8 +299,21 @@ def migrate_subscriptions(db: Database[dict[str, Any]], content_id: str) -> None
245299 content_type = (
246300 CommentThread if sub ["source_type" ] == "CommentThread" else Comment
247301 )
248- mongo_content = MongoContent .objects .get (mongo_id = str (content_id ))
249- content = content_type .objects .get (pk = mongo_content .content_object_id )
302+ mongo_content = MongoContent .objects .filter (mongo_id = str (content_id )).first ()
303+ if not mongo_content :
304+ logger .warning (
305+ f"Skipping subscription for source { content_id } : mapping not found"
306+ )
307+ continue
308+ content = content_type .objects .filter (
309+ pk = mongo_content .content_object_id
310+ ).first ()
311+ if not content :
312+ logger .warning (
313+ f"Skipping subscription for source { content_id } : target object not found "
314+ f"(content_object_id={ mongo_content .content_object_id } )"
315+ )
316+ continue
250317 if content :
251318 Subscription .objects .update_or_create (
252319 subscriber = user ,
0 commit comments