feat: 転送前にファイルプレフィックスの重複を確認するように修正。

This commit is contained in:
shimoda.m@nds-tyo.co.jp 2025-06-06 16:30:31 +09:00
parent f05ec64f41
commit 1d4f20429e

View File

@ -1,5 +1,9 @@
"""実消化&アルトマーク データ転送処理"""
import itertools
import os
import re
from src.aws.s3 import (JskIOBucket, TransferResultOutputBucket, UltmarcBucket,
UltmarcImportBucket)
from src.error.exceptions import BatchOperationException
@ -32,12 +36,12 @@ def exec():
# 日次バッチ処理中の場合、後続の処理は行わない
if batch_processing_flag == constants.BATCH_ACTF_BATCH_START:
logger.error('日次バッチ処理中のため、日次バッチ処理を終了します。')
logger.error('日次バッチ処理中のため、実消化&アルトマークデータ転送を終了します。')
return constants.BATCH_EXIT_CODE_SUCCESS
# dump取得が正常終了していない場合、後続の処理は行わない
if dump_status_kbn != constants.DUMP_STATUS_KBN_COMPLETE:
logger.error('dump取得が正常終了していないため、日次バッチ処理を終了します。')
logger.error('dump取得が正常終了していないため、実消化&アルトマークデータ転送を終了します。')
return constants.BATCH_EXIT_CODE_SUCCESS
logger.info(f'処理日={syor_date}')
@ -54,10 +58,45 @@ def exec():
jsk_receive_file_list = None
try:
jsk_io_bucket = JskIOBucket()
jsk_receive_file_list: str = jsk_io_bucket.get_file_list()
jsk_receive_file_list: list[str] = jsk_io_bucket.get_file_list()
except Exception as e:
logger.exception(f'実消化データリスト取得に失敗しました。{e}')
return constants.BATCH_EXIT_CODE_SUCCESS
# 実消化データリストの中で、ファイル種類(ファイル名のプレフィックス)が重複するものがあるかどうかをチェックする。
# 1) プレフィックスごとにマップを作り、該当するファイル名をリストで集める
# 以下のようなマップが作られる
# {
# "TRN_RESULT_DATA": ["TRN_RESULT_DATA_20250606102030.zip",
# "TRN_RESULT_DATA_20250606112030.zip"],
# "TRN_Recive_Inventry": ["TRN_Recive_Inventry_20250606102030.zip"],
# ...
# }
prefix_map: dict[str, list[str]] = {}
for filename in jsk_receive_file_list:
p = extract_prefix(filename)
prefix_map.setdefault(p, []).append(filename)
# 2) 重複しているプレフィックスを探す
duplicates = {prefix: file_list for prefix,
file_list in prefix_map.items() if len(file_list) > 1}
# 3) 重複があれば転送一覧から除外する
if duplicates:
# マップをフラットなリストに変換する
duplicate_files = list(
itertools.chain.from_iterable(duplicates.values()))
logger.warning(
f'実消化データの中で一部重複データがあります。重複データは転送から除外します。重複データ一覧: {duplicate_files}')
# 転送しなかったファイルもバックアップに移動させる
for filename in duplicate_files:
jsk_io_bucket.backup_file(filename, syor_date)
jsk_io_bucket.delete_file(filename)
# S3内のファイル数と重複ファイルの差集合を取ることで、要素を削除
jsk_receive_file_list = list(
set(jsk_receive_file_list) - set(duplicate_files))
logger.info(f'I-4 実消化データリスト取得終了。取得データ一覧:{jsk_receive_file_list}')
# ④ 取得した実消化データのリストでループ開始
@ -72,7 +111,7 @@ def exec():
# ⑧ 転送が完了したファイル名を転送データリストに追加する
# ファイル名のみ切り出して追加
transfer_file_lists['jsk_transfer_list'].append(
receive_file['filename'].split('/')[1])
receive_file.split('/')[1])
# ⑨ ループ終了後、実消化データ転送終了ログI-6)を出力する
logger.info(f'I-6 実消化データ転送処理終了')
@ -102,12 +141,13 @@ def exec():
# ⑮ 転送が完了したファイル名を転送データリストに追加する
# ファイル名のみ切り出して追加
transfer_file_lists['ult_transfer_list'].append(
receive_file['filename'].split('/')[1])
receive_file.split('/')[1])
# ⑯ ループ終了後、アルトマークデータ転送終了ログI-10)を出力する
logger.info(f'I-6 実消化データ転送処理終了')
logger.info(f'I-10 アルトマークデータ転送処理終了')
# ⑰ 転送データリストをJSONファイル化し、S3バケットにアップロードする
logger.info(f'I-11 データ転送結果アップロード')
TransferResultOutputBucket().put_transfer_result(transfer_file_lists, syor_date)
# ⑱ 処理終了ログ(I-12)を出力する
@ -118,3 +158,20 @@ def exec():
except Exception as e:
logger.exception(f'実消化&アルトマーク データ転送処理中に想定外のエラーが発生しました {e}')
raise e
def extract_prefix(filename: str) -> str:
"""
ファイル名からタイムスタンプ部分 + 拡張子を除いたプレフィックスを返す
: "TRN_RESULT_DATA_20250606102030.zip" -> "TRN_RESULT_DATA"
"""
# 拡張子を取り除く
file, ext = os.path.splitext(os.path.basename(filename))
# ファイル名の末尾がタイムスタンプ数字14桁である想定なので、最後の '_' 以降を削除
# TRN_RESULT_DATA_20250606102030 -> ["TRN_RESULT_DATA", "20250606102030"]
parts = file.rsplit('_', 1)
if len(parts) == 2 and re.fullmatch(r"\d{14}", parts[1]):
return parts[0]
else:
# 「最後がタイムスタンプじゃない」場合、そのままのファイル名全体を返す
return filename