3030
3131from enum import StrEnum
3232
33- from django .db import connections , migrations
33+ from django .db import connections , migrations , transaction
3434
3535EMAIL_REWRITE_OLD = "@pycon.kr"
3636EMAIL_REWRITE_NEW = "@python.or.kr"
@@ -276,7 +276,12 @@ def migrate_data(apps, schema_editor):
276276 if "legacy" not in connections .databases :
277277 return # 개발/테스트 환경 또는 cutover 완료 후 — no-op.
278278
279- with connections ["legacy" ].cursor () as legacy_cur , connections ["default" ].cursor () as target_cur :
279+ # 중간 실패 시 target DB 의 모든 변경을 함께 롤백 (legacy DB 는 SELECT 만 — 롤백 불필요).
280+ with (
281+ transaction .atomic (using = "default" ),
282+ connections ["legacy" ].cursor () as legacy_cur ,
283+ connections ["default" ].cursor () as target_cur ,
284+ ):
280285 user_id_map = _build_user_id_map (target_cur , legacy_cur )
281286 _copy_shifted_users (target_cur , legacy_cur , user_id_map )
282287 _update_matched_unique_id (target_cur , legacy_cur , user_id_map )
@@ -292,6 +297,7 @@ def migrate_data(apps, schema_editor):
292297
293298
294299class Migration (migrations .Migration ):
300+ atomic = True
295301 dependencies = [
296302 ("user" , "0009_alter_historicaluserext_options_and_more" ),
297303 ("order" , "0001_initial" ),
0 commit comments