feat:ECSコンテナで稼働するアプリケーションファイルを追加した
This commit is contained in:
parent
12b06d0574
commit
b0c6683fbb
86
ecs/Dockerfile/dataimport/chk.py
Normal file
86
ecs/Dockerfile/dataimport/chk.py
Normal file
@ -0,0 +1,86 @@
|
||||
from datetime import datetime
|
||||
import boto3
|
||||
import io
|
||||
import csv
|
||||
from error import error
|
||||
|
||||
s3_resource = boto3.resource('s3')
|
||||
|
||||
LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
|
||||
SETTINGS_ITEM = {
|
||||
'dataSource': 0,
|
||||
'delimiter': 1,
|
||||
'charCode': 2,
|
||||
'quotechar': 3,
|
||||
'lineFeedCode': 4,
|
||||
'headerFlag': 5,
|
||||
'csvNumItems': 6,
|
||||
'csvNameItems': 7,
|
||||
'dbColumuName': 8,
|
||||
'storageSchemaName': 9,
|
||||
'loadSchemaName': 10,
|
||||
'exSqlFileName': 11,
|
||||
}
|
||||
|
||||
|
||||
class CheckError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def check(bucket_name, target_key, target_data_source, target_file_name, settings_key, log_info):
|
||||
"""チェック処理
|
||||
Args:
|
||||
bucket_name : バケット名
|
||||
target_key : 投入データのフルパス
|
||||
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||
target_file_name : 投入データのファイル名
|
||||
settings_key : 投入データに該当する個別設定ファイルのフルパス
|
||||
log_info : ログに記載するデータソース名とファイル名
|
||||
Raises:
|
||||
CheckError : チェックでエラーがあった場合に発生する例外
|
||||
"""
|
||||
# ① 開始ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-CHK-01 - チェック処理を開始します')
|
||||
|
||||
try:
|
||||
# データ読込
|
||||
settings_obj = s3_resource.Object(bucket_name, settings_key)
|
||||
settings_response = settings_obj.get()
|
||||
settings_list = []
|
||||
for line in io.TextIOWrapper(io.BytesIO(settings_response["Body"].read()), encoding='utf-8'):
|
||||
settings_list.append(line.rstrip())
|
||||
|
||||
target_obj = s3_resource.Object(bucket_name, target_key)
|
||||
target_response = target_obj.get()
|
||||
target_data = io.TextIOWrapper(io.BytesIO(target_response["Body"].read()), encoding=settings_list[SETTINGS_ITEM["charCode"]], newline=settings_list[SETTINGS_ITEM["lineFeedCode"]])
|
||||
for line in csv.reader(target_data, quotechar=settings_list[SETTINGS_ITEM["quotechar"]], delimiter=settings_list[SETTINGS_ITEM["delimiter"]]):
|
||||
target_header_list = line.rstrip()
|
||||
break
|
||||
|
||||
# ② C-1 項目数チェック
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-CHK-02 - C-1のチェックを開始します')
|
||||
target_header_list_len = len(target_header_list)
|
||||
if not target_header_list_len == int(settings_list[SETTINGS_ITEM["csvNumItems"]]):
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-CHK-03 - C-1:正常終了')
|
||||
else:
|
||||
raise CheckError('E-CHK-01 - 項目数が一致しません')
|
||||
|
||||
# ③ C-2 項目並び順チェック
|
||||
if int(settings_list[SETTINGS_ITEM["headerFlag"]]) == True:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-CHK-04 - C-2のチェックを開始します')
|
||||
settings_header_list = settings_list[SETTINGS_ITEM["csvNameItems"]].rstrip().split(',')
|
||||
for i in range(len(settings_header_list)):
|
||||
if not settings_header_list[i] == target_header_list[i]:
|
||||
raise CheckError('E-CHK-02 - 項目順序が一致しません')
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-CHK-05 - C-2:正常終了')
|
||||
|
||||
except CheckError as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} {e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-CHK-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ④ 終了ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-CHK-06 - チェック処理を終了します')
|
||||
63
ecs/Dockerfile/dataimport/controller.py
Normal file
63
ecs/Dockerfile/dataimport/controller.py
Normal file
@ -0,0 +1,63 @@
|
||||
import os
|
||||
from datetime import datetime
|
||||
import boto3
|
||||
import sys
|
||||
|
||||
|
||||
from ini import init
|
||||
from chk import check
|
||||
from end import end
|
||||
|
||||
# 引数
|
||||
BUCKET_NAME = os.environ["BUCKET_NAME"]
|
||||
TARGET_KEY = os.environ["TARGET_KEY"]
|
||||
DATA_SOURCE_NAME = os.environ["DATA_SOURCE_NAME"]
|
||||
FILE_NAME = os.environ["FILE_NAME"]
|
||||
|
||||
# 環境変数
|
||||
DB_HOST = os.environ["DB_HOST"]
|
||||
DB_NAME = os.environ["DB_NAME"]
|
||||
DB_PASS = os.environ["DB_PASS"]
|
||||
DB_USER = os.environ["DB_USER"]
|
||||
DB_INFO = {"host": DB_HOST, "name": DB_NAME, "pass": DB_PASS, "user": DB_USER}
|
||||
|
||||
s3_client = boto3.client('s3')
|
||||
s3_resource = boto3.resource('s3')
|
||||
|
||||
LOG_LEVEL = {"i": 'Info', "e": 'Error'}
|
||||
LOG_INFO = f' {DATA_SOURCE_NAME} {FILE_NAME} '
|
||||
DIRECTORY_TARGET = '/target/'
|
||||
DIRECTORY_WORK = '/work/'
|
||||
DIRECTORY_DONE = '/done/'
|
||||
DIRECTORY_WARNING = '/warning/'
|
||||
|
||||
|
||||
def controller():
|
||||
"""コントロール処理
|
||||
|
||||
各処理を呼び出すコントローラー
|
||||
|
||||
"""
|
||||
|
||||
# ① 開始ログの出力
|
||||
print(f'{str(datetime.now())} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-01 - データ取込処理を開始します')
|
||||
|
||||
# ② 初期処理
|
||||
print(f'{str(datetime.now())} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-02 - 初期処理の呼び出し')
|
||||
settings_key = init(BUCKET_NAME, TARGET_KEY, DATA_SOURCE_NAME, FILE_NAME, LOG_INFO)
|
||||
|
||||
# ③ チェック処理
|
||||
print(f'{str(datetime.now())} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-03 - チェック処理の呼び出し')
|
||||
check(BUCKET_NAME, TARGET_KEY, DATA_SOURCE_NAME, FILE_NAME, settings_key, LOG_INFO)
|
||||
|
||||
# ④ メイン処理
|
||||
print(f'{str(datetime.now())} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-04 - メイン処理の呼び出し')
|
||||
warning_info = ''
|
||||
# warning_info = main(BUCKET_NAME, TARGET_KEY, DATA_SOURCE_NAME, FILE_NAME, settings_key, DB_INFO, LOG_INFO)
|
||||
|
||||
# ⑤ 終了処理
|
||||
print(f'{str(datetime.now())} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-05 - 終了処理の呼び出し')
|
||||
end(BUCKET_NAME, DATA_SOURCE_NAME, FILE_NAME, warning_info, LOG_INFO)
|
||||
|
||||
# ⑥ 終了ログの出力
|
||||
print(f'{str(datetime.now())} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-06 - データ取込処理を終了します')
|
||||
76
ecs/Dockerfile/dataimport/end.py
Normal file
76
ecs/Dockerfile/dataimport/end.py
Normal file
@ -0,0 +1,76 @@
|
||||
from datetime import datetime
|
||||
import boto3
|
||||
from error import error
|
||||
|
||||
s3_client = boto3.client('s3')
|
||||
s3_resource = boto3.resource('s3')
|
||||
|
||||
LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
|
||||
DIRECTORY_TARGET = '/target/'
|
||||
DIRECTORY_WORK = '/work/'
|
||||
DIRECTORY_DONE = '/done/'
|
||||
DIRECTORY_WARNING = '/warning/'
|
||||
|
||||
|
||||
def end(bucket_name, target_data_source, target_file_name, warning_info, log_info):
|
||||
"""終了処理
|
||||
Args:
|
||||
bucket_name : バケット名
|
||||
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||
target_file_name : 投入データのファイル名
|
||||
warning_info : Warning情報
|
||||
log_info : ログに記載するデータソース名とファイル名
|
||||
"""
|
||||
# ① 開始ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-01 - 終了処理を開始します')
|
||||
|
||||
try:
|
||||
# ② 投入データファイルをdoneディレクトリに移動
|
||||
work_key = target_data_source + DIRECTORY_WORK + target_file_name
|
||||
work_obj = s3_resource.Object(bucket_name, work_key)
|
||||
work_response = work_obj.get()
|
||||
work_body = work_response["Body"].read()
|
||||
done_file_name = str(datetime.now()) + '_' + target_file_name
|
||||
done_key = target_data_source + DIRECTORY_DONE + done_file_name
|
||||
done_obj = s3_resource.Object(bucket_name, done_key)
|
||||
done_obj.put(Body=work_body)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-02 - workディレクトリの {target_file_name} をdoneディレクトリに移動しました 移動後ファイル名:{done_file_name}')
|
||||
|
||||
# ③ doingファイルの削除
|
||||
doing_file_name = target_file_name + '.doing'
|
||||
doing_key = target_data_source + DIRECTORY_TARGET + doing_file_name
|
||||
s3_client.delete_object(Bucket=bucket_name, Key=doing_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-03 - targetディレクトリの {doing_file_name} を削除しました')
|
||||
|
||||
# ④ Warning情報の存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-04 - Warning情報の存在チェック')
|
||||
if warning_info:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-05 - Warning情報は存在しました')
|
||||
|
||||
# warningファイルの作成
|
||||
warning_file_name = str(datetime.now()) + '_' + target_file_name + '_war.log'
|
||||
warning_key = target_data_source + DIRECTORY_WARNING + warning_file_name
|
||||
warning_obj = s3_resource.Object(bucket_name, warning_key)
|
||||
warning_obj.put(Body=warning_info)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-06 - warningディレクトリに {warning_file_name} を作成しました')
|
||||
|
||||
# warning処理結果ファイルの作成
|
||||
result_warning_file_name = target_file_name + '.warning'
|
||||
result_warning_key = target_data_source + DIRECTORY_TARGET + result_warning_file_name
|
||||
result_warning_obj = s3_resource.Object(bucket_name, result_warning_key)
|
||||
result_warning_obj.put(Body='')
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-07 - targetディレクトリに {result_warning_file_name} を作成しました')
|
||||
else:
|
||||
# done処理結果ファイルの作成
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-08 - Warning情報は存在しませんでした')
|
||||
result_done_file_name = target_file_name + '.done'
|
||||
result_done_key = target_data_source + DIRECTORY_TARGET + result_done_file_name
|
||||
result_done_obj = s3_resource.Object(bucket_name, result_done_key)
|
||||
result_done_obj.put(Body='')
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-09 - targetディレクトリに {result_done_file_name} を作成しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-END-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ⑤ 終了ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-END-0 - 終了処理を終了します')
|
||||
57
ecs/Dockerfile/dataimport/error.py
Normal file
57
ecs/Dockerfile/dataimport/error.py
Normal file
@ -0,0 +1,57 @@
|
||||
from datetime import datetime
|
||||
import boto3
|
||||
import sys
|
||||
|
||||
s3_client = boto3.client('s3')
|
||||
s3_resource = boto3.resource('s3')
|
||||
|
||||
LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
|
||||
DIRECTORY_TARGET = '/target/'
|
||||
DIRECTORY_WORK = '/work/'
|
||||
DIRECTORY_DONE = '/done/'
|
||||
|
||||
|
||||
def error(bucket_name, target_data_source, target_file_name, log_info):
|
||||
"""エラー処理
|
||||
Args:
|
||||
bucket_name : バケット名
|
||||
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||
target_file_name : 投入データのファイル名
|
||||
log_info : ログに記載するデータソース名とファイル名
|
||||
"""
|
||||
|
||||
# ① 開始ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-ERR-01 - エラー処理を開始します')
|
||||
|
||||
try:
|
||||
# ② 投入データファイルをerrorディレクトリに移動
|
||||
work_key = target_data_source + DIRECTORY_WORK + target_file_name
|
||||
work_obj = s3_resource.Object(bucket_name, work_key)
|
||||
work_response = work_obj.get()
|
||||
work_body = work_response["Body"].read()
|
||||
error_file_name = str(datetime.now()) + '_' + target_file_name
|
||||
error_key = target_data_source + DIRECTORY_DONE + error_file_name
|
||||
error_obj = s3_resource.Object(bucket_name, error_key)
|
||||
error_obj.put(Body=work_body)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-ERR-02 - workディレクトリの {target_file_name} をerrorディレクトリに移動しました 移動後ファイル名:{error_file_name}')
|
||||
|
||||
# ③ doingファイルの削除
|
||||
doing_file_name = target_file_name + '.doing'
|
||||
doing_key = target_data_source + DIRECTORY_TARGET + doing_file_name
|
||||
s3_client.delete_object(Bucket=bucket_name, Key=doing_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-ERR-03 - targetディレクトリの {doing_file_name} を削除しました')
|
||||
|
||||
# ④ error処理結果ファイルの作成
|
||||
result_error_file_name = target_file_name + '.error'
|
||||
result_error_key = target_data_source + DIRECTORY_TARGET + result_error_file_name
|
||||
result_error_obj = s3_resource.Object(bucket_name, result_error_key)
|
||||
result_error_obj.put(Body='')
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-ERR-04 - targetディレクトリに {result_error_file_name} を作成しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}')
|
||||
finally:
|
||||
# ⑤ 終了ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-ERR-05 - エラー処理を終了します')
|
||||
|
||||
# ⑥ 処理終了
|
||||
sys.exit()
|
||||
142
ecs/Dockerfile/dataimport/ini.py
Normal file
142
ecs/Dockerfile/dataimport/ini.py
Normal file
@ -0,0 +1,142 @@
|
||||
from datetime import datetime
|
||||
import boto3
|
||||
import io
|
||||
import csv
|
||||
import re
|
||||
from error import error
|
||||
|
||||
ecs_client = boto3.client('ecs')
|
||||
s3_client = boto3.client('s3')
|
||||
s3_resource = boto3.resource('s3')
|
||||
|
||||
LOG_LEVEL = {"i": 'Info', "e": 'Error'}
|
||||
MAPPING_FILE_NAME = 'configmap.config'
|
||||
DIRECTORY_TARGET = '/target/'
|
||||
DIRECTORY_WORK = '/work/'
|
||||
DIRECTORY_SETTINGS = '/settings/'
|
||||
|
||||
|
||||
def init(bucket_name, target_key, target_data_source, target_file_name, log_info):
|
||||
"""初期処理
|
||||
Args:
|
||||
bucket_name : バケット名
|
||||
target_key : 投入データのフルパス
|
||||
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||
target_file_name : 投入データのファイル名
|
||||
log_info : ログに記載するデータソース名とファイル名
|
||||
Returns:
|
||||
settings_key : 投入データに該当する個別設定ファイルのフルパス
|
||||
"""
|
||||
|
||||
# ① 開始ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-01 - 初期処理を開始します')
|
||||
|
||||
# doingファイル情報作成
|
||||
doing_file_name = target_file_name + '.doing'
|
||||
doing_key = target_data_source + DIRECTORY_TARGET + doing_file_name
|
||||
|
||||
# ② doingファイルの存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-02 - doingファイル:{doing_file_name} の存在チェック')
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=doing_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-01 - 投入データ {target_file_name} は既に処理中です')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-03 - doingファイルは存在しませんでした')
|
||||
|
||||
# ③ doingファイルの作成
|
||||
try:
|
||||
doing_obj = s3_resource.Object(bucket_name, doing_key)
|
||||
doing_obj.put(Body='')
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-04 - targetディレクトリに {doing_file_name} を作成しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ④ 投入データファイルをworkディレクトリに移動
|
||||
try:
|
||||
target_obj = s3_resource.Object(bucket_name, target_key)
|
||||
target_response = target_obj.get()
|
||||
work_key = target_data_source + DIRECTORY_WORK + target_file_name
|
||||
work_body = target_response["Body"].read()
|
||||
work_obj = s3_resource.Object(bucket_name, work_key)
|
||||
work_obj.put(Body=work_body)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-05 - 投入データ {target_file_name} をworkディレクトリに移動しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ⑤ 処理結果ファイルの削除
|
||||
# doneファイルの存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-06 - doneファイル:{target_file_name}.done の存在チェック')
|
||||
result_done_key = target_data_source + DIRECTORY_TARGET + target_file_name + '.done'
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=result_done_key)
|
||||
s3_client.delete_object(Bucket=bucket_name, Key=result_done_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-07 - doneファイルが存在したため削除しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-08 - doneファイルは存在しませんでした')
|
||||
|
||||
# warningファイルの存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-09 - warningファイル:{target_file_name}.warning の存在チェック')
|
||||
result_warning_key = target_data_source + DIRECTORY_TARGET + target_file_name + '.warning'
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=result_warning_key)
|
||||
s3_client.delete_object(Bucket=bucket_name, Key=result_warning_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-10 - warningファイルが存在したため削除しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-11 - warningファイルは存在しませんでした')
|
||||
|
||||
# errorファイルの存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-12 - errorファイル:{target_file_name}.error の存在チェック')
|
||||
result_error_key = target_data_source + DIRECTORY_TARGET + target_file_name + '.error'
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=result_error_key)
|
||||
s3_client.delete_object(Bucket=bucket_name, Key=result_error_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-13 - errorファイルが存在したため削除しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-14 - errorファイルは存在しませんでした')
|
||||
|
||||
# ⑥ 個別設定マッピングリストの存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-15 - 個別設定マッピングリスト:{MAPPING_FILE_NAME} の存在チェック')
|
||||
mapping_key = target_data_source + DIRECTORY_SETTINGS + MAPPING_FILE_NAME
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=mapping_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-16 - 個別設定マッピングリストの存在を確認しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-02 - 個別設定マッピングリストが存在しません')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ⑦ 個別設定ファイルの特定
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-17 - 個別設定ファイルを検索します')
|
||||
try:
|
||||
mapping_obj = s3_resource.Object(bucket_name, mapping_key)
|
||||
mapping_response = mapping_obj.get()
|
||||
mapping_body = io.TextIOWrapper(io.BytesIO(mapping_response["Body"].read()), encoding='utf-8')
|
||||
for row in csv.reader(mapping_body, delimiter='\t'):
|
||||
match_result = re.fullmatch(row[0], target_file_name)
|
||||
if match_result is not None:
|
||||
settings_file_name = row[1].rstrip()
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-18 - 個別設定ファイル:{settings_file_name} を特定しました')
|
||||
break
|
||||
|
||||
if settings_file_name is None:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-03 - 個別設定ファイルが特定出来ません')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ⑧ 個別設定ファイルの存在確認
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-19 - 個別設定ファイル:{settings_file_name} の存在チェック')
|
||||
settings_key = target_data_source + DIRECTORY_SETTINGS + settings_file_name
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=settings_key)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-20 - 個別設定ファイルの存在を確認しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-INI-04 - 個別設定ファイルが存在しません')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ⑨ 終了ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-INI-21 - 初期処理を終了します')
|
||||
return settings_key
|
||||
@ -1,19 +1,195 @@
|
||||
from datetime import datetime
|
||||
import boto3
|
||||
import os
|
||||
from os import path
|
||||
import pymysql
|
||||
import io
|
||||
import csv
|
||||
from error import error
|
||||
|
||||
# EVENT_BUCKET = os.environ["EVENT_BUCKET"]
|
||||
# EVENT_OBJECKT_KEY = os.environ["EVENT_OBJECKT_KEY"]
|
||||
ecs_client = boto3.client('ecs')
|
||||
s3_client = boto3.client('s3')
|
||||
s3_resource = boto3.resource('s3')
|
||||
|
||||
# DESTINATION_BUCKET = os.environ["DESTINATION_BUCKET"]
|
||||
# DESTINATION_OBJECKT_DIR = os.environ["DESTINATION_OBJECKT_DIR"]
|
||||
LOG_LEVEL = {"i": 'Info', "e": 'Error', "w": 'Warning'}
|
||||
SETTINGS_ITEM = {
|
||||
'dataSource': 0,
|
||||
'delimiter': 1,
|
||||
'charCode': 2,
|
||||
'quotechar': 3,
|
||||
'lineFeedCode': 4,
|
||||
'headerFlag': 5,
|
||||
'csvNumItems': 6,
|
||||
'csvNameItems': 7,
|
||||
'dbColumuName': 8,
|
||||
'storageSchemaName': 9,
|
||||
'loadSchemaName': 10,
|
||||
'exSqlFileName': 11,
|
||||
}
|
||||
DIRECTORY_SETTINGS = '/settings/'
|
||||
|
||||
# s3 = boto3.resource("s3")
|
||||
|
||||
# destination_object_key = path.join(
|
||||
# DESTINATION_OBJECKT_DIR, path.basename(EVENT_OBJECKT_KEY)
|
||||
# )
|
||||
# event_object = s3.Object(DESTINATION_BUCKET, destination_object_key)
|
||||
# event_object.copy({"Bucket": EVENT_BUCKET, "Key": EVENT_OBJECKT_KEY})
|
||||
def init(bucket_name, target_key, target_data_source, target_file_name, settings_key, db_info, log_info):
|
||||
"""メイン処理
|
||||
Args:
|
||||
bucket_name : バケット名
|
||||
target_key : 投入データのフルパス
|
||||
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||
target_file_name : 投入データのファイル名
|
||||
settings_key : 投入データに該当する個別設定ファイルのフルパス
|
||||
db_info : データベース情報
|
||||
log_info : ログに記載するデータソース名とファイル名
|
||||
Returns:
|
||||
warning_info : Warning情報
|
||||
"""
|
||||
|
||||
print('呼び出し成功')
|
||||
# ① メイン処理開始ログを出力する
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-01 - メイン処理を開始します')
|
||||
|
||||
# ② DB接続を開始する
|
||||
try:
|
||||
conn = pymysql.connect(host=db_info["host"], user=db_info["user"], passwd=db_info["pass"], db=db_info["name"], connect_timeout=5)
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-02 - DB接続を開始しました')
|
||||
|
||||
# ③ 個別設定ファイルのロードスキーマのテーブル名に記載されているテーブルをTRUNCATEする
|
||||
try:
|
||||
# 個別設定ファイルの読込
|
||||
settings_obj = s3_resource.Object(bucket_name, settings_key)
|
||||
settings_response = settings_obj.get()
|
||||
settings_list = []
|
||||
for line in io.TextIOWrapper(io.BytesIO(settings_response["Body"].read()), encoding='utf-8'):
|
||||
settings_list.append(line.rstrip())
|
||||
|
||||
# TRUNCATE実行
|
||||
with conn.cursor() as cur:
|
||||
sql_truncate = f'TRUNCATE table {settings_list[SETTINGS_ITEM["loadSchemaName"]]}'
|
||||
cur.execute(sql_truncate)
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-03 - {settings_list[SETTINGS_ITEM["loadSchemaName"]]} をTRUNCATEしました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ④ 投入データファイルを1行ごとにループする
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-04 - 投入データ {target_file_name} の読み込みを開始します')
|
||||
try:
|
||||
target_obj = s3_resource.Object(bucket_name, target_key)
|
||||
target_response = target_obj.get()
|
||||
target_data = io.TextIOWrapper(io.BytesIO(target_response["Body"].read()), encoding=settings_list[SETTINGS_ITEM["charCode"]], newline=settings_list[SETTINGS_ITEM["lineFeedCode"]])
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
process_count = 0 # 処理件数カウンタ
|
||||
normal_count = 0 # 正常終了件数カウンタ
|
||||
warning_count = 0 # ワーニング終了件数カウンター
|
||||
warning_info = '' # ワーニング情報
|
||||
index = 0 # ループインデックス
|
||||
|
||||
for line in csv.reader(target_data, quotechar=settings_list[SETTINGS_ITEM["quotechar"]], delimiter=settings_list[SETTINGS_ITEM["delimiter"]]):
|
||||
try:
|
||||
if settings_list[SETTINGS_ITEM["headerFlag"]] and index == 0:
|
||||
index += 1
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-05 - ヘッダー行をスキップします')
|
||||
continue
|
||||
|
||||
# 処理件数カウント
|
||||
process_count += 1
|
||||
|
||||
# SQL文生成
|
||||
sql = f'INSERT INTO {settings_list[SETTINGS_ITEM["loadSchemaName"]]} VALUES ('
|
||||
for i in range(len(line)):
|
||||
sql = f'{sql} "{line[i]}",'
|
||||
|
||||
sql = f'{sql} "{target_file_name}",' # システム項目:取込ファイル名
|
||||
sql = f'{sql} "{index}",' # システム項目:取込ファイル行番号
|
||||
sql = f'{sql} "0",' # システム項目:論理削除フラグ
|
||||
sql = f'{sql} CURRENT_USER(),' # システム項目:登録者
|
||||
sql = f'{sql} CURRENT_TIMESTAMP(),' # システム項目:登録日時
|
||||
sql = f'{sql} NULL,' # システム項目:更新者
|
||||
sql = f'{sql} NULL)' # システム項目:更新日時
|
||||
|
||||
# ロードスキーマのトランザクション開始
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(sql)
|
||||
conn.commit()
|
||||
normal_count += 1
|
||||
|
||||
index += 1
|
||||
except Exception as e:
|
||||
warning_info = f'{warning_info} {index} ロードスキーマ登録時にエラーが発生しました {line} {e}\n'
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["w"]} W-MAIN-01 {index} ロードスキーマ登録時にエラーが発生しました {line} {e}')
|
||||
|
||||
# ⑤ ④の処理結果件数をログ出力する
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-06 - 投入データ件数:{process_count} 正常終了件数:{normal_count} Warning終了件数:{warning_count}')
|
||||
|
||||
# ⑥ ロードスキーマのデータを蓄積スキーマにUPSERTする
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-07 - ロードスキーマ({settings_list[SETTINGS_ITEM["loadSchemaName"]]})のデータを蓄積スキーマ({settings_list[SETTINGS_ITEM["storageSchemaName"]]})に登録します')
|
||||
try:
|
||||
# SQL文生成
|
||||
sql = f'INSERT INTO {settings_list[SETTINGS_ITEM["storageSchemaName"]]}'
|
||||
sql = f'{sql} SELECT t.*'
|
||||
sql = f'{sql} FROM {settings_list[SETTINGS_ITEM["loadSchemaName"]]} as t'
|
||||
sql = f'{sql} ON DUPLICATE KEY UPDATE'
|
||||
settings_db_columu_list = settings_list[SETTINGS_ITEM["dbColumuName"]].rstrip().split(',')
|
||||
for i in range(len(settings_db_columu_list)):
|
||||
sql = f'{sql} {settings_db_columu_list[i]}=t.{settings_db_columu_list[i]},'
|
||||
sql = f'{sql} file_name=t.file_name,' # システム項目:取込ファイル名
|
||||
sql = f'{sql} file_row_cnt=t.file_row_cnt,' # システム項目:取込ファイル行番号
|
||||
sql = f'{sql} ins_user=t.ins_user,' # システム項目:登録者
|
||||
sql = f'{sql} ins_date=t.ins_date' # システム項目:登録日時
|
||||
|
||||
# トランザクション開始
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-08 - 標準SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のトランザクションを開始します')
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(sql)
|
||||
conn.commit()
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-09 - 標準SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のCOMIIT処理が正常終了しました')
|
||||
except Exception as e:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||
error(bucket_name, target_data_source, target_file_name)
|
||||
|
||||
# ⑦ 個別設定ファイルに拡張SQLファイル名が設定されているかチェック
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-10 - 拡張SQL設定が存在するかチェックします')
|
||||
if settings_list[SETTINGS_ITEM["exSqlFileName"]]:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-11 - 拡張SQL設定の存在を確認しました')
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-12 - 拡張SQLファイル名:{settings_list[SETTINGS_ITEM["exSqlFileName"]]} の存在チェック')
|
||||
ex_sql_key = target_data_source + DIRECTORY_SETTINGS + settings_list[SETTINGS_ITEM["exSqlFileName"]]
|
||||
try:
|
||||
s3_client.head_object(Bucket=bucket_name, Key=ex_sql_key)
|
||||
ex_sql_file_exists = True
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-13 - 拡張SQLファイル名の存在を確認しました')
|
||||
except Exception as e:
|
||||
warning_info = f'{warning_info} - 拡張SQLファイルが存在しません\n'
|
||||
ex_sql_file_exists = False
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["w"]} W-MAIN-02 - 拡張SQLファイルが存在しません')
|
||||
|
||||
try:
|
||||
if ex_sql_file_exists:
|
||||
# 拡張SQLファイルからSQL文生成
|
||||
ex_sqls_obj = s3_resource.Object(bucket_name, ex_sql_key)
|
||||
ex_sql_response = ex_sqls_obj.get()
|
||||
ex_sql = ''
|
||||
for line in io.TextIOWrapper(io.BytesIO(ex_sql_response["Body"].read()), encoding='utf-8'):
|
||||
ex_sql = f'{ex_sql} {line.rstrip()}'
|
||||
|
||||
# トランザクション開始
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-14 - 拡張SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のトランザクションを開始します')
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(ex_sql)
|
||||
conn.commit()
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-15 - 拡張SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のCOMIIT処理が正常終了しました')
|
||||
except Exception as e:
|
||||
warning_info = f'{warning_info} - 拡張SQLにエラーが発生しました:{e}\n'
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["w"]} W-MAIN-03 - 拡張SQLにエラーが発生しました:{e}')
|
||||
else:
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-16 - 拡張SQL設定の存在はありませんでした')
|
||||
|
||||
# ⑧ DB接続を終了する
|
||||
conn.close()
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-17 - DB接続を終了しました')
|
||||
|
||||
# ⑨ 終了ログの出力
|
||||
print(f'{str(datetime.now())} {log_info} {LOG_LEVEL["i"]} I-MAIN-18 - メイン処理を終了します')
|
||||
|
||||
return warning_info
|
||||
|
||||
@ -1 +1,2 @@
|
||||
boto3
|
||||
boto3
|
||||
PyMySQL
|
||||
Loading…
x
Reference in New Issue
Block a user