diff --git a/ecs/jskult-batch-daily/src/batch/common/calendar_wholestocksaler_file.py b/ecs/jskult-batch-daily/src/batch/common/calendar_wholestocksaler_file.py deleted file mode 100644 index ba687514..00000000 --- a/ecs/jskult-batch-daily/src/batch/common/calendar_wholestocksaler_file.py +++ /dev/null @@ -1,32 +0,0 @@ -from src.system_var import constants - - -class CalendarWholwSalerStockFile: - """V実消化卸在庫データ連携日ファイル""" - - __calendar_file_lines: list[str] - - def __init__(self, calendar_file_path): - with open(calendar_file_path) as f: - self.__calendar_file_lines: list[str] = f.readlines() - - def compare_date(self, date_str: str) -> bool: - """与えられた日付がV実消化卸在庫データ連携日ファイル内に含まれているかどうか - V実消化卸在庫データ連携日ファイル内の日付はyyyy/mm/ddで書かれている前提 - コメント(#)が含まれている行は無視される - - Args: - date_str (str): yyyy/mm/dd文字列 - - Returns: - bool: 含まれていればTrue - """ - for calendar_date in self.__calendar_file_lines: - # コメント行が含まれている場合はスキップ - if constants.CALENDAR_COMMENT_SYMBOL in calendar_date: - continue - - if date_str in calendar_date: - return True - - return False diff --git a/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_data_load_manager.py b/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_data_load_manager.py index c63ac962..909bd041 100644 --- a/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_data_load_manager.py +++ b/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_data_load_manager.py @@ -7,7 +7,7 @@ logger = get_logger('V実消化データ取込(DB登録)') mapper = VjskRecvFileMapper() -class JjskDataLoadManager: +class VjskDataLoadManager: def __init__(self): pass @@ -15,7 +15,9 @@ class JjskDataLoadManager: logger.debug(f"_import_to_db start (src_file_name : {src_file_name}, condkey : {condkey})") db = Database.get_instance() + data_name = mapper.get_data_name(condkey) table_name_org = mapper.get_org_table(condkey) + table_name_src = mapper.get_src_table(condkey) upsert_sql = mapper.get_upsert_sql(condkey) try: @@ -28,14 +30,17 @@ class JjskDataLoadManager: sql = f"LOAD DATA LOCAL INFILE :src_file_name INTO TABLE {table_name_org} " \ " FIELDS TERMINATED BY '\\t' ENCLOSED BY '\"' IGNORE 1 LINES;" result = db.execute(sql, {"src_file_name": src_file_name}) - logger.info(f'tsvデータをorgテーブルにLOAD : 件数({result.rowcount})') + logger.debug(sql) + logger.info(f'{data_name}tsvファイルを{table_name_org}にLOAD : 件数({result.rowcount})') # org→srcにinsert select db.begin() + logger.debug(upsert_sql) db.execute(upsert_sql) - # TODO: insert+select 実質10件なのに、resultのrowcountは20件になってしまう ※sqlalchemyの仕様 - # https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.BaseCursorResult.rowcount - logger.info('orgテーブルをsrcテーブルにUPSERT') + # MEMO: insert+selectの結果件数は、LOAD結果と必ず等しいので、executeの結果件数はログ出力しない + # MEMO: insert+select 実質10件なのに、result.rowcountは20件になってしまう ※sqlalchemyの仕様 + # MEMO: https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.BaseCursorResult.rowcount + logger.info(f'{table_name_org}を{table_name_src}にUPSERT') db.commit() except Exception as e: diff --git a/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_importer.py b/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_importer.py index d667416e..31c42874 100644 --- a/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_importer.py +++ b/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_importer.py @@ -1,8 +1,7 @@ from src.aws.s3 import ConfigBucket, VjskRecieveBucket from src.batch.common.batch_context import BatchContext -from src.batch.common.calendar_wholestocksaler_file import \ - CalendarWholwSalerStockFile -from src.batch.vjsk.vjsk_data_load_manager import JjskDataLoadManager +from src.batch.common.calendar_file import CalendarFile +from src.batch.vjsk.vjsk_data_load_manager import VjskDataLoadManager from src.batch.vjsk.vjsk_recv_file_mapper import VjskRecvFileMapper from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger @@ -102,7 +101,7 @@ def _check_received_files(): logger.debug('_check_received_files done') - return True + return def _import_file_to_db(): @@ -132,49 +131,49 @@ def _import_file_to_db(): # DB登録 卸在庫データファイル(卸在庫データ処理対象日のみ実施) if batch_context.is_import_target_vjsk_stockslipdata: - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_STOCK_SLIP_DATA]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_STOCK_SLIP_DATA]) # DB登録 卸販売データ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_SLIP_DATA]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_SLIP_DATA]) # DB登録 卸組織変換マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_ORG_CNV_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_ORG_CNV_MST]) # DB登録 施設統合マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_VOP_HCO_MERGE]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_VOP_HCO_MERGE]) # DB登録 卸マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_WHS_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_WHS_MST]) # DB登録 卸ホールディングスマスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_HLD_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_HLD_MST]) # DB登録 施設マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_FCL_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_FCL_MST]) # DB登録 メーカー卸組織展開表 - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_MKR_ORG_HORIZON]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_MKR_ORG_HORIZON]) # DB登録 取引区分マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_TRAN_KBN_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_TRAN_KBN_MST]) # DB登録 製品マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_PHM_PRD_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_PHM_PRD_MST]) # DB登録 製品価格マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_PHM_PRICE_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_PHM_PRICE_MST]) # DB登録 卸得意先情報マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_WHS_CUSTOMER_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_WHS_CUSTOMER_MST]) # DB登録 MDBコード変換マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_MDB_CONV_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_MDB_CONV_MST]) # DB登録 生物由来データ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_BIO_SLIP_DATA]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_BIO_SLIP_DATA]) # DB登録 製造ロット番号マスタ - JjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_LOT_NUM_MST]) + VjskDataLoadManager.Load(target_dict[vjsk_mapper.CONDKEY_LOT_NUM_MST]) logger.debug('_import_file_to_db done') @@ -187,10 +186,10 @@ def _determine_today_is_stockslipdata_target(): today = batch_context.syor_date # S3バケット上の設定ファイル「V実消化卸在庫データ連携日ファイル」をローカルストレージにdownloadする - config_file_path = ConfigBucket().download_wholesaler_stock_list() + wholesaler_stock_list_file_path = ConfigBucket().download_wholesaler_stock_list() # 設定ファイル「V実消化卸在庫データ連携日ファイル」の定義内容を取得する - target_days = CalendarWholwSalerStockFile(config_file_path) + target_days = CalendarFile(wholesaler_stock_list_file_path) # 処理日付が、設定ファイル「V実消化卸在庫データ連携日ファイル」の定義に該当するかを判定する ret = target_days.compare_date(today) @@ -205,6 +204,11 @@ def exec(): """V実消化データ取込処理""" logger.info('Start Jitsusyouka Torikomi PGM.') + # 非営業日なら何もせず終了 + if batch_context.is_not_business_day: + logger.debug('非営業日なので処理をスキップ') + return + # 卸在庫データ取込対象日であれば、卸在庫データ処理対象フラグを立てる logger.debug('卸在庫データ取込対象日であるかを判定') batch_context.is_import_target_vjsk_stockslipdata = _determine_today_is_stockslipdata_target() @@ -219,7 +223,7 @@ def exec(): _check_received_files() except BatchOperationException as e: - logger.error('受領したV実消化データファイルに未受領もものがあります') + logger.debug('受領したV実消化データファイルに未受領もものがあります') raise e logger.debug('V実消化データファイル受領チェック:終了') @@ -229,7 +233,7 @@ def exec(): # S3バケットにある受領済のV実消化データファイルをデータベースに登録する _import_file_to_db() except Exception as e: - logger.error(f'データベース登録失敗 {e}') + logger.debug(f'データベース登録失敗 {e}') raise e logger.debug('V実消化データ取込:終了') diff --git a/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_recv_file_mapper.py b/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_recv_file_mapper.py index 726e927c..2ba87909 100644 --- a/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_recv_file_mapper.py +++ b/ecs/jskult-batch-daily/src/batch/vjsk/vjsk_recv_file_mapper.py @@ -18,6 +18,7 @@ class VjskRecvFileMapper: CONDKEY_BIO_SLIP_DATA = "BIO_SLIP_DATA" # 生物由来データ CONDKEY_LOT_NUM_MST = "LOT_NUM_MST" # ロットマスタデータ + _KEY_DATA_NAME = "data_name" _KEY_FILE_PREFIX = "file_prefix" _KEY_FILE_SUFFIX = "file_suffix" _KEY_ORG_TABLE = "org_table" @@ -26,6 +27,7 @@ class VjskRecvFileMapper: _VJSK_INTERFACE_MAPPING = { # 販売実績データ CONDKEY_SLIP_DATA: { + _KEY_DATA_NAME: "販売実績データ", _KEY_FILE_PREFIX: "slip_data_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.sales", @@ -294,6 +296,7 @@ class VjskRecvFileMapper: # V卸ホールディングスマスタ CONDKEY_HLD_MST: { + _KEY_DATA_NAME: "V卸ホールディングスマスタ", _KEY_FILE_PREFIX: "hld_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.hld_mst_v", @@ -346,6 +349,7 @@ class VjskRecvFileMapper: # V卸マスタ CONDKEY_WHS_MST: { + _KEY_DATA_NAME: "V卸マスタ", _KEY_FILE_PREFIX: "whs_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.whs_mst_v", @@ -413,6 +417,7 @@ class VjskRecvFileMapper: # Vメーカー卸組織展開表 CONDKEY_MKR_ORG_HORIZON: { + _KEY_DATA_NAME: "Vメーカー卸組織展開表", _KEY_FILE_PREFIX: "mkr_org_horizon_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.mkr_org_horizon_v", @@ -570,6 +575,7 @@ class VjskRecvFileMapper: # V卸組織変換マスタ CONDKEY_ORG_CNV_MST: { + _KEY_DATA_NAME: "V卸組織変換マスタ", _KEY_FILE_PREFIX: "org_cnv_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.org_cnv_mst_v", @@ -622,6 +628,7 @@ class VjskRecvFileMapper: # V取引区分マスタ CONDKEY_TRAN_KBN_MST: { + _KEY_DATA_NAME: "V取引区分マスタ", _KEY_FILE_PREFIX: "tran_kbn_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.tran_kbn_mst_v", @@ -668,6 +675,7 @@ class VjskRecvFileMapper: # V施設マスタ CONDKEY_FCL_MST: { + _KEY_DATA_NAME: "V施設マスタ", _KEY_FILE_PREFIX: "fcl_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.fcl_mst_v", @@ -759,6 +767,7 @@ class VjskRecvFileMapper: # V製品マスタ CONDKEY_PHM_PRD_MST: { + _KEY_DATA_NAME: "V製品マスタ", _KEY_FILE_PREFIX: "phm_prd_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.phm_prd_mst_v", @@ -862,6 +871,7 @@ class VjskRecvFileMapper: # V製品価格マスタ CONDKEY_PHM_PRICE_MST: { + _KEY_DATA_NAME: "V製品価格マスタ", _KEY_FILE_PREFIX: "phm_price_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.phm_price_mst_v", @@ -911,6 +921,7 @@ class VjskRecvFileMapper: # V施設統合マスタ CONDKEY_VOP_HCO_MERGE: { + _KEY_DATA_NAME: "V施設統合マスタ", _KEY_FILE_PREFIX: "vop_hco_merge_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.vop_hco_merge_v", @@ -942,6 +953,7 @@ class VjskRecvFileMapper: # V卸得意先情報マスタ CONDKEY_WHS_CUSTOMER_MST: { + _KEY_DATA_NAME: "V卸得意先情報マスタ", _KEY_FILE_PREFIX: "whs_customer_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.whs_customer_mst_v", @@ -1012,6 +1024,7 @@ class VjskRecvFileMapper: # MDBコード変換表 CONDKEY_MDB_CONV_MST: { + _KEY_DATA_NAME: "MDBコード変換表", _KEY_FILE_PREFIX: "mdb_conv_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.mdb_cnv_mst_v", @@ -1055,6 +1068,7 @@ class VjskRecvFileMapper: # 卸在庫データ CONDKEY_STOCK_SLIP_DATA: { + _KEY_DATA_NAME: "卸在庫データ", _KEY_FILE_PREFIX: "stock_slip_data_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.whole_stock", @@ -1161,6 +1175,7 @@ class VjskRecvFileMapper: # 生物由来データ CONDKEY_BIO_SLIP_DATA: { + _KEY_DATA_NAME: "生物由来データ", _KEY_FILE_PREFIX: "bio_slip_data_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.bio_sales", @@ -1414,6 +1429,7 @@ class VjskRecvFileMapper: # ロットマスタデータ CONDKEY_LOT_NUM_MST: { + _KEY_DATA_NAME: "ロットマスタデータ", _KEY_FILE_PREFIX: "lot_num_mst_", _KEY_FILE_SUFFIX: ".tsv", _KEY_ORG_TABLE: "org05.lot_num_mst", @@ -1450,6 +1466,12 @@ class VjskRecvFileMapper: }, } + def get_data_name(self, condkey: str) -> str: + ret = None + if condkey in self._VJSK_INTERFACE_MAPPING: + ret = self._VJSK_INTERFACE_MAPPING.get(condkey).get(self._KEY_DATA_NAME) + return ret + def get_file_prefix(self, condkey: str) -> str: ret = None if condkey in self._VJSK_INTERFACE_MAPPING: