Merge pull request #17 develop into master
This commit is contained in:
commit
0faf00b851
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
lambda/mbj-newdwh2021-staging-NoticeToSlack/package-lock.json
|
||||||
|
lambda/mbj-newdwh2021-staging-NoticeToSlack/node_modules/*
|
||||||
|
lambda/mbj-newdwh2021-staging-PublishFromLog/package-lock.json
|
||||||
|
lambda/mbj-newdwh2021-staging-PublishFromLog/node_modules/*
|
||||||
12
config/data_import/encise/CITFD_Merck01.txt
Normal file
12
config/data_import/encise/CITFD_Merck01.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citfd
|
||||||
|
org01.en_citfd_01
|
||||||
|
|
||||||
12
config/data_import/encise/CITFD_Merck06.txt
Normal file
12
config/data_import/encise/CITFD_Merck06.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citfd
|
||||||
|
org01.en_citfd_06
|
||||||
|
|
||||||
12
config/data_import/encise/CITFD_Merck07.txt
Normal file
12
config/data_import/encise/CITFD_Merck07.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citfd
|
||||||
|
org01.en_citfd_07
|
||||||
|
|
||||||
12
config/data_import/encise/CITFD_Merck10.txt
Normal file
12
config/data_import/encise/CITFD_Merck10.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citfd
|
||||||
|
org01.en_citfd_10
|
||||||
|
|
||||||
12
config/data_import/encise/CITFM_PROADD.txt
Normal file
12
config/data_import/encise/CITFM_PROADD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
49
|
||||||
|
統一商品コード,販売元コード,販売元名称,製造販売元コード,製造販売元名称,製品分類コード(大),製品分類名称(大),製品分類コード(中),製品分類名称(中),製品分類コード(小),製品分類名称(小),Encise ATC分類コード(第1レベル),Encise ATC分類名称(第1レベル),Encise ATC分類コード(第2レベル),Encise ATC分類名称(第2レベル),Encise ATC分類コード(第3レベル),Encise ATC分類名称(第3レベル),Encise ATC分類コード(第4レベル),Encise ATC分類名称(第4レベル),WHO ATC分類コード(第1レベル),WHO ATC分類名称(第1レベル),WHO ATC分類コード(第2レベル),WHO ATC分類名称(第2レベル),WHO ATC分類コード(第3レベル),WHO ATC分類名称(第3レベル),WHO ATC分類コード(第4レベル),WHO ATC分類名称(第4レベル),日本標準商品分類番号薬効分類コード(大),日本標準商品分類番号薬効分類名称(大),日本標準商品分類番号薬効分類コード(中),日本標準商品分類番号薬効分類名称(中),日本標準商品分類番号薬効分類コード(小),日本標準商品分類番号薬効分類名称(小),日本標準商品分類番号薬効分類コード(細),日本標準商品分類番号薬効分類名称(細),使用区分コード,使用区分名称,剤型区分コード,剤型区分名称,長期収載品区分コード,長期収載品区分名,薬価基準収載区分コード,薬価基準収載区分名,後発医薬品区分コード,後発医薬品区分名,有効成分一般名コード,有効成分一般名,新薬創出加算区分,更新日(西暦)
|
||||||
|
universal_product_code,seller_code,seller_name,manufacturer_code,manufacturer_name,product_brand_code,product_brand_name,product_item_code,product_item_name,product_SKU_code,product_SKU_name,Encise_ATC_1_code,Encise_ATC_1_name,Encise_ATC_2_code,Encise_ATC_2_name,Encise_ATC_3_code,Encise_ATC_3_name,Encise_ATC_4_code,Encise_ATC_4_name,WHO_ATC_1_code,WHO_ATC_1_name,WHO_ATC_2_code,WHO_ATC_2_name,WHO_ATC_3_code,WHO_ATC_3_name,WHO_ATC_4_code,WHO_ATC_4_name,JPN_pharma_category_1_code,JPN_pharma_category_1_name,JPN_pharma_category_2_code,JPN_pharma_category_2_name,JPN_pharma_category_3_code,JPN_pharma_category_3_name,JPN_pharma_category_4_code,JPN_pharma_category_4_name,drug_usage_code,drug_usage_name,drug_form_code,drug_form_name,long_listed_code,long_listed_flag,NHI_pricing_code,NHI_pricing_flag,generic_code,generic_flag,active_ingredient_code,active_ingredient_name,new_drug_premium_code,update_date
|
||||||
|
src01.en_citfm_proadd
|
||||||
|
org01.en_citfm_proadd
|
||||||
|
|
||||||
12
config/data_import/encise/CITFM_PROLST.txt
Normal file
12
config/data_import/encise/CITFM_PROLST.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
7
|
||||||
|
統一商品コード,製品名,包装単位,販売元名,更新日(西暦),薬効分類コード,薬効分類名
|
||||||
|
universal_product_code,product_SKU_name,package,seller_name,update_date,data_file_code,data_file_name
|
||||||
|
src01.en_citfm_prolst
|
||||||
|
org01.en_citfm_prolst
|
||||||
|
|
||||||
12
config/data_import/encise/CITFM_REGION.txt
Normal file
12
config/data_import/encise/CITFM_REGION.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
3
|
||||||
|
地域コード,地域名,更新日(西暦)
|
||||||
|
region_code,region_name,update_date
|
||||||
|
src01.en_citfm_region
|
||||||
|
org01.en_citfm_region
|
||||||
|
|
||||||
12
config/data_import/encise/CITFM_SEGMNT.txt
Normal file
12
config/data_import/encise/CITFM_SEGMNT.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
3
|
||||||
|
セグメントコード,セグメント名,更新日(西暦)
|
||||||
|
segment_code,segment_name,update_date
|
||||||
|
src01.en_citfm_segmnt
|
||||||
|
org01.en_citfm_segmnt
|
||||||
|
|
||||||
12
config/data_import/encise/CITQD_Merck01.txt
Normal file
12
config/data_import/encise/CITQD_Merck01.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citqd
|
||||||
|
org01.en_citqd_01
|
||||||
|
|
||||||
12
config/data_import/encise/CITQD_Merck06.txt
Normal file
12
config/data_import/encise/CITQD_Merck06.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citqd
|
||||||
|
org01.en_citqd_06
|
||||||
|
|
||||||
12
config/data_import/encise/CITQD_Merck07.txt
Normal file
12
config/data_import/encise/CITQD_Merck07.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citqd
|
||||||
|
org01.en_citqd_07
|
||||||
|
|
||||||
12
config/data_import/encise/CITQD_Merck10.txt
Normal file
12
config/data_import/encise/CITQD_Merck10.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_citqd
|
||||||
|
org01.en_citqd_10
|
||||||
|
|
||||||
12
config/data_import/encise/CITQM_PROADD.txt
Normal file
12
config/data_import/encise/CITQM_PROADD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
49
|
||||||
|
統一商品コード,販売元コード,販売元名称,製造販売元コード,製造販売元名称,製品分類コード(大),製品分類名称(大),製品分類コード(中),製品分類名称(中),製品分類コード(小),製品分類名称(小),Encise ATC分類コード(第1レベル),Encise ATC分類名称(第1レベル),Encise ATC分類コード(第2レベル),Encise ATC分類名称(第2レベル),Encise ATC分類コード(第3レベル),Encise ATC分類名称(第3レベル),Encise ATC分類コード(第4レベル),Encise ATC分類名称(第4レベル),WHO ATC分類コード(第1レベル),WHO ATC分類名称(第1レベル),WHO ATC分類コード(第2レベル),WHO ATC分類名称(第2レベル),WHO ATC分類コード(第3レベル),WHO ATC分類名称(第3レベル),WHO ATC分類コード(第4レベル),WHO ATC分類名称(第4レベル),日本標準商品分類番号薬効分類コード(大),日本標準商品分類番号薬効分類名称(大),日本標準商品分類番号薬効分類コード(中),日本標準商品分類番号薬効分類名称(中),日本標準商品分類番号薬効分類コード(小),日本標準商品分類番号薬効分類名称(小),日本標準商品分類番号薬効分類コード(細),日本標準商品分類番号薬効分類名称(細),使用区分コード,使用区分名称,剤型区分コード,剤型区分名称,長期収載品区分コード,長期収載品区分名,薬価基準収載区分コード,薬価基準収載区分名,後発医薬品区分コード,後発医薬品区分名,有効成分一般名コード,有効成分一般名,新薬創出加算区分,更新日(西暦)
|
||||||
|
universal_product_code,seller_code,seller_name,manufacturer_code,manufacturer_name,product_brand_code,product_brand_name,product_item_code,product_item_name,product_SKU_code,product_SKU_name,Encise_ATC_1_code,Encise_ATC_1_name,Encise_ATC_2_code,Encise_ATC_2_name,Encise_ATC_3_code,Encise_ATC_3_name,Encise_ATC_4_code,Encise_ATC_4_name,WHO_ATC_1_code,WHO_ATC_1_name,WHO_ATC_2_code,WHO_ATC_2_name,WHO_ATC_3_code,WHO_ATC_3_name,WHO_ATC_4_code,WHO_ATC_4_name,JPN_pharma_category_1_code,JPN_pharma_category_1_name,JPN_pharma_category_2_code,JPN_pharma_category_2_name,JPN_pharma_category_3_code,JPN_pharma_category_3_name,JPN_pharma_category_4_code,JPN_pharma_category_4_name,drug_usage_code,drug_usage_name,drug_form_code,drug_form_name,long_listed_code,long_listed_flag,NHI_pricing_code,NHI_pricing_flag,generic_code,generic_flag,active_ingredient_code,active_ingredient_name,new_drug_premium_code,update_date
|
||||||
|
src01.en_citqm_proadd
|
||||||
|
org01.en_citqm_proadd
|
||||||
|
|
||||||
12
config/data_import/encise/CITQM_PROLST.txt
Normal file
12
config/data_import/encise/CITQM_PROLST.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
7
|
||||||
|
統一商品コード,製品名,包装単位,販売元名,更新日(西暦),薬効分類コード,薬効分類名
|
||||||
|
universal_product_code,product_SKU_name,package,seller_name,update_date,data_file_code,data_file_name
|
||||||
|
src01.en_citqm_prolst
|
||||||
|
org01.en_citqm_prolst
|
||||||
|
|
||||||
12
config/data_import/encise/CITQM_REGION.txt
Normal file
12
config/data_import/encise/CITQM_REGION.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
3
|
||||||
|
地域コード,地域名,更新日(西暦)
|
||||||
|
region_code,region_name,update_date
|
||||||
|
src01.en_citqm_region
|
||||||
|
org01.en_citqm_region
|
||||||
|
|
||||||
12
config/data_import/encise/CITQM_SEGMNT.txt
Normal file
12
config/data_import/encise/CITQM_SEGMNT.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
3
|
||||||
|
セグメントコード,セグメント名,更新日(西暦)
|
||||||
|
segment_code,segment_name,update_date
|
||||||
|
src01.en_citqm_segmnt
|
||||||
|
org01.en_citqm_segmnt
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFD_Merck02.txt
Normal file
12
config/data_import/encise/CLUFD_Merck02.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
11
|
||||||
|
クラスターコード,クラスター名,セグメントコード,セグメント名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
cluster_code,cluster_name,segment_code,segment_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_clufd
|
||||||
|
org01.en_clufd_02
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFD_Merck02_D.txt
Normal file
12
config/data_import/encise/CLUFD_Merck02_D.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
utf-8-sig
|
||||||
|
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
12
|
||||||
|
クラスターコード,クラスター名,セグメントコード,セグメント名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月,direct_flg
|
||||||
|
cluster_code,cluster_name,segment_code,segment_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month,direct_flg
|
||||||
|
src01.en_clufd
|
||||||
|
org01.en_clufd_d_02
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFD_Merck03.txt
Normal file
12
config/data_import/encise/CLUFD_Merck03.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
11
|
||||||
|
クラスターコード,クラスター名,セグメントコード,セグメント名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
cluster_code,cluster_name,segment_code,segment_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_clufd
|
||||||
|
org01.en_clufd_03
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFD_Merck03_D.txt
Normal file
12
config/data_import/encise/CLUFD_Merck03_D.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
utf-8-sig
|
||||||
|
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
12
|
||||||
|
クラスターコード,クラスター名,セグメントコード,セグメント名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月,direct_flg
|
||||||
|
cluster_code,cluster_name,segment_code,segment_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month,direct_flg
|
||||||
|
src01.en_clufd
|
||||||
|
org01.en_clufd_d_03
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFD_Merck04.txt
Normal file
12
config/data_import/encise/CLUFD_Merck04.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
11
|
||||||
|
クラスターコード,クラスター名,セグメントコード,セグメント名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
cluster_code,cluster_name,segment_code,segment_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_clufd
|
||||||
|
org01.en_clufd_04
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFD_Merck04_D.txt
Normal file
12
config/data_import/encise/CLUFD_Merck04_D.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
utf-8-sig
|
||||||
|
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
12
|
||||||
|
クラスターコード,クラスター名,セグメントコード,セグメント名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月,direct_flg
|
||||||
|
cluster_code,cluster_name,segment_code,segment_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month,direct_flg
|
||||||
|
src01.en_clufd
|
||||||
|
org01.en_clufd_d_04
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFM_CLUMST.txt
Normal file
12
config/data_import/encise/CLUFM_CLUMST.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
12
|
||||||
|
対象期間,クラスターコード,クラスター名,都道府県コード,都道府県名,施設コード,施設名,更新日,更新事由,適用年月,セグメントコード,セグメント名
|
||||||
|
data_period,cluster_code,cluster_name,pref_code,pref_name,HCO_coce,HCO_name,update_date,update_remarks,master_YM,segment_code,segment_name
|
||||||
|
src01.en_clufm_clumst
|
||||||
|
org01.en_clufm_clumst
|
||||||
|
CLUFM_CLUMST_ex.sql
|
||||||
7
config/data_import/encise/CLUFM_CLUMST_ex.sql
Normal file
7
config/data_import/encise/CLUFM_CLUMST_ex.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/* クラスターマスタのTO年月をセットする */
|
||||||
|
update src01.en_clufm_clumst set
|
||||||
|
to_ym = case when substr(data_period,9,7) is null then '0000/00'
|
||||||
|
else substr(data_period,9,7)
|
||||||
|
end
|
||||||
|
where to_ym is null;
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFM_PROADD.txt
Normal file
12
config/data_import/encise/CLUFM_PROADD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
encise
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
49
|
||||||
|
統一商品コード,販売元コード,販売元名称,製造販売元コード,製造販売元名称,製品分類コード(大),製品分類名称(大),製品分類コード(中),製品分類名称(中),製品分類コード(小),製品分類名称(小),Encise ATC分類コード(第1レベル),Encise ATC分類名称(第1レベル),Encise ATC分類コード(第2レベル),Encise ATC分類名称(第2レベル),Encise ATC分類コード(第3レベル),Encise ATC分類名称(第3レベル),Encise ATC分類コード(第4レベル),Encise ATC分類名称(第4レベル),WHO ATC分類コード(第1レベル),WHO ATC分類名称(第1レベル),WHO ATC分類コード(第2レベル),WHO ATC分類名称(第2レベル),WHO ATC分類コード(第3レベル),WHO ATC分類名称(第3レベル),WHO ATC分類コード(第4レベル),WHO ATC分類名称(第4レベル),日本標準商品分類番号薬効分類コード(大),日本標準商品分類番号薬効分類名称(大),日本標準商品分類番号薬効分類コード(中),日本標準商品分類番号薬効分類名称(中),日本標準商品分類番号薬効分類コード(小),日本標準商品分類番号薬効分類名称(小),日本標準商品分類番号薬効分類コード(細),日本標準商品分類番号薬効分類名称(細),使用区分コード,使用区分名称,剤型区分コード,剤型区分名称,長期収載品区分コード,長期収載品区分名,薬価基準収載区分コード,薬価基準収載区分名,後発医薬品区分コード,後発医薬品区分名,有効成分一般名コード,有効成分一般名,新薬創出加算区分,更新日(西暦)
|
||||||
|
universal_product_code,seller_code,seller_name,manufacturer_code,manufacturer_name,product_brand_code,product_brand_name,product_item_code,product_item_name,product_SKU_code,product_SKU_name,Encise_ATC_1_code,Encise_ATC_1_name,Encise_ATC_2_code,Encise_ATC_2_name,Encise_ATC_3_code,Encise_ATC_3_name,Encise_ATC_4_code,Encise_ATC_4_name,WHO_ATC_1_code,WHO_ATC_1_name,WHO_ATC_2_code,WHO_ATC_2_name,WHO_ATC_3_code,WHO_ATC_3_name,WHO_ATC_4_code,WHO_ATC_4_name,JPN_pharma_category_1_code,JPN_pharma_category_1_name,JPN_pharma_category_2_code,JPN_pharma_category_2_name,JPN_pharma_category_3_code,JPN_pharma_category_3_name,JPN_pharma_category_4_code,JPN_pharma_category_4_name,drug_usage_code,drug_usage_name,drug_form_code,drug_form_name,long_listed_code,long_listed_flag,NHI_pricing_code,NHI_pricing_flag,generic_code,generic_flag,active_ingredient_code,active_ingredient_name,new_drug_premium_code,update_date
|
||||||
|
src01.en_clufm_proadd
|
||||||
|
org01.en_clufm_proadd
|
||||||
|
|
||||||
12
config/data_import/encise/CLUFM_PROLST.txt
Normal file
12
config/data_import/encise/CLUFM_PROLST.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
7
|
||||||
|
統一商品コード,製品名,包装単位,販売元名,更新日(西暦),薬効分類コード,薬効分類名
|
||||||
|
universal_product_code,product_SKU_name,package,seller_name,update_date,data_file_code,data_file_name
|
||||||
|
src01.en_clufm_prolst
|
||||||
|
org01.en_clufm_prolst
|
||||||
|
|
||||||
12
config/data_import/encise/MST_BRAND.txt
Normal file
12
config/data_import/encise/MST_BRAND.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
30
|
||||||
|
JANコード,統一商品コード,YJコード,使用区分名,剤型コード,剤型名,商品名,一般名,規格容量,規格単位名,販売元コード,販売元名,製造元コード,製造元名,Route of Administration,Form,Brand_Name,Molecule_Name,Strength,SalesCompany,Manufacturer,薬効分類コード,薬効分類名,日本標準薬効2,日本標準薬効名2,薬価基準収載医薬品コード,処方せん医薬品,薬価基準収載区分,ENCODE,名称
|
||||||
|
jan_code,universal_product_code,yj_code,drug_usage_name,drug_form_code,drug_form_name,product_SKU_name,active_ingredient_name,package,SKU_name,seller_code,seller_name,manufacturer_code,manufacturer_name,eng_route_of_administration,eng_form,eng_brand_name,eng_molecule_name,eng_strength,eng_seller_name,eng_manufacturer_name,JPN_pharma_category_4_code,JPN_pharma_category_4_name,JPN_pharma_category_2_code,JPN_pharma_category_2_name,NHI_pricing_code,ethical_drug_flag,NHI_pricing_flag,encode,encise_active_ingredient_name
|
||||||
|
src01.en_mst_brand
|
||||||
|
org01.en_mst_brand
|
||||||
|
|
||||||
12
config/data_import/encise/NATFD.txt
Normal file
12
config/data_import/encise/NATFD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_natfd
|
||||||
|
org01.en_natfd
|
||||||
|
|
||||||
12
config/data_import/encise/NATFD_D.txt
Normal file
12
config/data_import/encise/NATFD_D.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
utf-8-sig
|
||||||
|
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
14
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月,direct_flg
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month,direct_flg
|
||||||
|
src01.en_natfd
|
||||||
|
org01.en_natfd_d
|
||||||
|
|
||||||
12
config/data_import/encise/NATFM_PROADD.txt
Normal file
12
config/data_import/encise/NATFM_PROADD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
encise
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
49
|
||||||
|
統一商品コード,販売元コード,販売元名称,製造販売元コード,製造販売元名称,製品分類コード(大),製品分類名称(大),製品分類コード(中),製品分類名称(中),製品分類コード(小),製品分類名称(小),Encise ATC分類コード(第1レベル),Encise ATC分類名称(第1レベル),Encise ATC分類コード(第2レベル),Encise ATC分類名称(第2レベル),Encise ATC分類コード(第3レベル),Encise ATC分類名称(第3レベル),Encise ATC分類コード(第4レベル),Encise ATC分類名称(第4レベル),WHO ATC分類コード(第1レベル),WHO ATC分類名称(第1レベル),WHO ATC分類コード(第2レベル),WHO ATC分類名称(第2レベル),WHO ATC分類コード(第3レベル),WHO ATC分類名称(第3レベル),WHO ATC分類コード(第4レベル),WHO ATC分類名称(第4レベル),日本標準商品分類番号薬効分類コード(大),日本標準商品分類番号薬効分類名称(大),日本標準商品分類番号薬効分類コード(中),日本標準商品分類番号薬効分類名称(中),日本標準商品分類番号薬効分類コード(小),日本標準商品分類番号薬効分類名称(小),日本標準商品分類番号薬効分類コード(細),日本標準商品分類番号薬効分類名称(細),使用区分コード,使用区分名称,剤型区分コード,剤型区分名称,長期収載品区分コード,長期収載品区分名,薬価基準収載区分コード,薬価基準収載区分名,後発医薬品区分コード,後発医薬品区分名,有効成分一般名コード,有効成分一般名,新薬創出加算区分,更新日(西暦)
|
||||||
|
universal_product_code,seller_code,seller_name,manufacturer_code,manufacturer_name,product_brand_code,product_brand_name,product_item_code,product_item_name,product_SKU_code,product_SKU_name,Encise_ATC_1_code,Encise_ATC_1_name,Encise_ATC_2_code,Encise_ATC_2_name,Encise_ATC_3_code,Encise_ATC_3_name,Encise_ATC_4_code,Encise_ATC_4_name,WHO_ATC_1_code,WHO_ATC_1_name,WHO_ATC_2_code,WHO_ATC_2_name,WHO_ATC_3_code,WHO_ATC_3_name,WHO_ATC_4_code,WHO_ATC_4_name,JPN_pharma_category_1_code,JPN_pharma_category_1_name,JPN_pharma_category_2_code,JPN_pharma_category_2_name,JPN_pharma_category_3_code,JPN_pharma_category_3_name,JPN_pharma_category_4_code,JPN_pharma_category_4_name,drug_usage_code,drug_usage_name,drug_form_code,drug_form_name,long_listed_code,long_listed_flag,NHI_pricing_code,NHI_pricing_flag,generic_code,generic_flag,active_ingredient_code,active_ingredient_name,new_drug_premium_code,update_date
|
||||||
|
src01.en_natfm_proadd
|
||||||
|
org01.en_natfm_proadd
|
||||||
|
|
||||||
12
config/data_import/encise/NATFM_SEGMNT.txt
Normal file
12
config/data_import/encise/NATFM_SEGMNT.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
3
|
||||||
|
セグメントコード,セグメント名,更新日(西暦)
|
||||||
|
segment_code,segment_name,update_date
|
||||||
|
src01.en_natfm_segmnt
|
||||||
|
org01.en_natfm_segmnt
|
||||||
|
|
||||||
12
config/data_import/encise/NATQD.txt
Normal file
12
config/data_import/encise/NATQD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
13
|
||||||
|
地域コード,地域名,セグメントコード,セグメント名,施設コード,施設名,統一商品コード,製品名,包装単位,数量,金額(薬価),年,月
|
||||||
|
region_code,region_name,segment_code,segment_name,HCO_code,HCO_name,universal_product_code,product_SKU_name,package,qty,value_NHI,year,month
|
||||||
|
src01.en_natqd
|
||||||
|
org01.en_natqd
|
||||||
|
|
||||||
12
config/data_import/encise/NATQM_PROADD.txt
Normal file
12
config/data_import/encise/NATQM_PROADD.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
encise
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
49
|
||||||
|
統一商品コード,販売元コード,販売元名称,製造販売元コード,製造販売元名称,製品分類コード(大),製品分類名称(大),製品分類コード(中),製品分類名称(中),製品分類コード(小),製品分類名称(小),Encise ATC分類コード(第1レベル),Encise ATC分類名称(第1レベル),Encise ATC分類コード(第2レベル),Encise ATC分類名称(第2レベル),Encise ATC分類コード(第3レベル),Encise ATC分類名称(第3レベル),Encise ATC分類コード(第4レベル),Encise ATC分類名称(第4レベル),WHO ATC分類コード(第1レベル),WHO ATC分類名称(第1レベル),WHO ATC分類コード(第2レベル),WHO ATC分類名称(第2レベル),WHO ATC分類コード(第3レベル),WHO ATC分類名称(第3レベル),WHO ATC分類コード(第4レベル),WHO ATC分類名称(第4レベル),日本標準商品分類番号薬効分類コード(大),日本標準商品分類番号薬効分類名称(大),日本標準商品分類番号薬効分類コード(中),日本標準商品分類番号薬効分類名称(中),日本標準商品分類番号薬効分類コード(小),日本標準商品分類番号薬効分類名称(小),日本標準商品分類番号薬効分類コード(細),日本標準商品分類番号薬効分類名称(細),使用区分コード,使用区分名称,剤型区分コード,剤型区分名称,長期収載品区分コード,長期収載品区分名,薬価基準収載区分コード,薬価基準収載区分名,後発医薬品区分コード,後発医薬品区分名,有効成分一般名コード,有効成分一般名,新薬創出加算区分,更新日(西暦)
|
||||||
|
universal_product_code,seller_code,seller_name,manufacturer_code,manufacturer_name,product_brand_code,product_brand_name,product_item_code,product_item_name,product_SKU_code,product_SKU_name,Encise_ATC_1_code,Encise_ATC_1_name,Encise_ATC_2_code,Encise_ATC_2_name,Encise_ATC_3_code,Encise_ATC_3_name,Encise_ATC_4_code,Encise_ATC_4_name,WHO_ATC_1_code,WHO_ATC_1_name,WHO_ATC_2_code,WHO_ATC_2_name,WHO_ATC_3_code,WHO_ATC_3_name,WHO_ATC_4_code,WHO_ATC_4_name,JPN_pharma_category_1_code,JPN_pharma_category_1_name,JPN_pharma_category_2_code,JPN_pharma_category_2_name,JPN_pharma_category_3_code,JPN_pharma_category_3_name,JPN_pharma_category_4_code,JPN_pharma_category_4_name,drug_usage_code,drug_usage_name,drug_form_code,drug_form_name,long_listed_code,long_listed_flag,NHI_pricing_code,NHI_pricing_flag,generic_code,generic_flag,active_ingredient_code,active_ingredient_name,new_drug_premium_code,update_date
|
||||||
|
src01.en_natqm_proadd
|
||||||
|
org01.en_natqm_proadd
|
||||||
|
|
||||||
12
config/data_import/encise/NATQM_SEGMNT.txt
Normal file
12
config/data_import/encise/NATQM_SEGMNT.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
ensice
|
||||||
|
,
|
||||||
|
cp932
|
||||||
|
"
|
||||||
|
CRLF
|
||||||
|
1
|
||||||
|
3
|
||||||
|
セグメントコード,セグメント名,更新日(西暦)
|
||||||
|
segment_code,segment_name,update_date
|
||||||
|
src01.en_natqm_segmnt
|
||||||
|
org01.en_natqm_segmnt
|
||||||
|
|
||||||
37
config/data_import/encise/configmap.config
Normal file
37
config/data_import/encise/configmap.config
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* 第3営業日:速報データ */
|
||||||
|
CITQD_Merck01_496_[0-9]{6}\.(CSV|csv) CITQD_Merck01.txt
|
||||||
|
CITQD_Merck06_496_[0-9]{6}\.(CSV|csv) CITQD_Merck06.txt
|
||||||
|
CITQD_Merck07_496_[0-9]{6}\.(CSV|csv) CITQD_Merck07.txt
|
||||||
|
CITQD_Merck10_496_[0-9]{6}\.(CSV|csv) CITQD_Merck10.txt
|
||||||
|
CITQM_PROADD_496_[0-9]{6}\.(CSV|csv) CITQM_PROADD.txt
|
||||||
|
CITQM_PROLST_496_[0-9]{6}\.(CSV|csv) CITQM_PROLST.txt
|
||||||
|
CITQM_REGION_496_[0-9]{6}\.(CSV|csv) CITQM_REGION.txt
|
||||||
|
CITQM_SEGMNT_496_[0-9]{6}\.(CSV|csv) CITQM_SEGMNT.txt
|
||||||
|
NATQD_496_[0-9]{6}\.(CSV|csv) NATQD.txt
|
||||||
|
NATQM_PROADD_496_[0-9]{6}\.(CSV|csv) NATQM_PROADD.txt
|
||||||
|
NATQM_SEGMNT_496_[0-9]{6}\.(CSV|csv) NATQM_SEGMNT.txt
|
||||||
|
/* 毎月15日:確定データ */
|
||||||
|
CITFD_Merck01_496_[0-9]{6}\.(CSV|csv) CITFD_Merck01.txt
|
||||||
|
CITFD_Merck06_496_[0-9]{6}\.(CSV|csv) CITFD_Merck06.txt
|
||||||
|
CITFD_Merck07_496_[0-9]{6}\.(CSV|csv) CITFD_Merck07.txt
|
||||||
|
CITFD_Merck10_496_[0-9]{6}\.(CSV|csv) CITFD_Merck10.txt
|
||||||
|
CITFM_PROADD_496_[0-9]{6}\.(CSV|csv) CITFM_PROADD.txt
|
||||||
|
CITFM_PROLST_496_[0-9]{6}\.(CSV|csv) CITFM_PROLST.txt
|
||||||
|
CITFM_REGION_496_[0-9]{6}\.(CSV|csv) CITFM_REGION.txt
|
||||||
|
CITFM_SEGMNT_496_[0-9]{6}\.(CSV|csv) CITFM_SEGMNT.txt
|
||||||
|
MST_BRAND[0-9]{6}\.(CSV|csv) MST_BRAND.txt
|
||||||
|
NATFD_496_[0-9]{6}\.(CSV|csv) NATFD.txt
|
||||||
|
NATFM_PROADD_496_[0-9]{6}\.(CSV|csv) NATFM_PROADD.txt
|
||||||
|
NATFM_SEGMNT_496_[0-9]{6}\.(CSV|csv) NATFM_SEGMNT.txt
|
||||||
|
/* 毎月20日:En-Cluster */
|
||||||
|
CLUFD_Merck02_496_[0-9]{6}\.(CSV|csv) CLUFD_Merck02.txt
|
||||||
|
CLUFD_Merck03_496_[0-9]{6}\.(CSV|csv) CLUFD_Merck03.txt
|
||||||
|
CLUFD_Merck04_496_[0-9]{6}\.(CSV|csv) CLUFD_Merck04.txt
|
||||||
|
CLUFM_CLUMST_496_01_[0-9]{6}\.(CSV|csv) CLUFM_CLUMST.txt
|
||||||
|
CLUFM_PROADD_496_[0-9]{6}\.(CSV|csv) CLUFM_PROADD.txt
|
||||||
|
CLUFM_PROLST_496_[0-9]{6}\.(CSV|csv) CLUFM_PROLST.txt
|
||||||
|
/* 直販データ */
|
||||||
|
CLUFD_Merck02_496_[0-9]{6}D\.(CSV|csv) CLUFD_Merck02_D.txt
|
||||||
|
CLUFD_Merck03_496_[0-9]{6}D\.(CSV|csv) CLUFD_Merck03_D.txt
|
||||||
|
CLUFD_Merck04_496_[0-9]{6}D\.(CSV|csv) CLUFD_Merck04_D.txt
|
||||||
|
NATFD_496_[0-9]{6}D\.(CSV|csv) NATFD_D.txt
|
||||||
10
ecs/Dockerfile/Dockerfile
Normal file
10
ecs/Dockerfile/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM python:3.9
|
||||||
|
|
||||||
|
ENV TZ="Asia/Tokyo"
|
||||||
|
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
COPY requirements.txt ./
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
COPY dataimport ./
|
||||||
|
|
||||||
|
CMD [ "python", "./controller.py" ]
|
||||||
116
ecs/Dockerfile/dataimport/chk.py
Normal file
116
ecs/Dockerfile/dataimport/chk.py
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import boto3
|
||||||
|
import io
|
||||||
|
import csv
|
||||||
|
import sys
|
||||||
|
from end import end
|
||||||
|
from error import error
|
||||||
|
from common import debug_log
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
DIRECTORY_WORK = '/work/'
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
LINE_FEED_CODE = {
|
||||||
|
'CR': '\r',
|
||||||
|
'LF': '\n',
|
||||||
|
'CRLF': '\r\n',
|
||||||
|
}
|
||||||
|
|
||||||
|
# クラス変数
|
||||||
|
s3_resource = boto3.resource('s3')
|
||||||
|
|
||||||
|
|
||||||
|
# チェック例外クラス
|
||||||
|
class CheckError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def check(bucket_name, target_data_source, target_file_name, settings_key, log_info, mode):
|
||||||
|
"""チェック処理
|
||||||
|
Args:
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
settings_key : 投入データに該当する個別設定ファイルのフルパス
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
mode : 処理モード
|
||||||
|
Raises:
|
||||||
|
CheckError : チェックでエラーがあった場合に発生する例外
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
debug_log(f'引数 bucket_name : {bucket_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_data_source : {target_data_source}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_file_name : {target_file_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 settings_key : {settings_key}', log_info, mode)
|
||||||
|
debug_log(f'引数 log_info : {log_info}', log_info, mode)
|
||||||
|
debug_log(f'引数 mode : {mode}', log_info, mode)
|
||||||
|
|
||||||
|
# ① チェック処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-01 - チェック処理を開始します')
|
||||||
|
|
||||||
|
# データ読込
|
||||||
|
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('\n'))
|
||||||
|
|
||||||
|
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_data = io.TextIOWrapper(io.BytesIO(work_response["Body"].read()), encoding=settings_list[SETTINGS_ITEM["charCode"]], newline=LINE_FEED_CODE[settings_list[SETTINGS_ITEM["lineFeedCode"]]])
|
||||||
|
work_header_list = []
|
||||||
|
for line in csv.reader(work_data, quotechar=settings_list[SETTINGS_ITEM["quotechar"]], delimiter=settings_list[SETTINGS_ITEM["delimiter"]]):
|
||||||
|
work_header_list = line
|
||||||
|
break
|
||||||
|
|
||||||
|
# ② C-0のデータ件数チェックを開始する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-02 - C-0のチェックを開始します')
|
||||||
|
if not len(work_header_list):
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-03 - 投入ファイルが0バイトのため処理を終了します')
|
||||||
|
end(bucket_name, target_data_source, target_file_name, '', log_info, mode)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-04 - 終了処理完了')
|
||||||
|
sys.exit()
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-05 - C-0:正常終了')
|
||||||
|
|
||||||
|
# ③ C-1の項目数チェックを開始する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-06 - C-1のチェックを開始します')
|
||||||
|
work_header_list_len = len(work_header_list)
|
||||||
|
if work_header_list_len == int(settings_list[SETTINGS_ITEM["csvNumItems"]]):
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-07 - C-1:正常終了')
|
||||||
|
else:
|
||||||
|
raise CheckError(f'E-CHK-01 - 項目数が一致しません 個別設定ファイル項目数:{settings_list[SETTINGS_ITEM["csvNumItems"]]} 投入データ項目数:{work_header_list_len}')
|
||||||
|
|
||||||
|
# ④ C-2の項目並び順チェック開始する
|
||||||
|
if int(settings_list[SETTINGS_ITEM["headerFlag"]]) == True:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-08 - 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] == work_header_list[i]:
|
||||||
|
raise CheckError(f'E-CHK-02 - 項目順序が一致しません {i + 1}番目の項目 個別設定ファイル項目:{settings_header_list[i]} 投入データ項目:{work_header_list[i]}')
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-09 - C-2:正常終了')
|
||||||
|
|
||||||
|
# ⑤ チェック処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-10 - チェック処理を終了します')
|
||||||
|
except CheckError as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} {e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-CHK-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
13
ecs/Dockerfile/dataimport/common.py
Normal file
13
ecs/Dockerfile/dataimport/common.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
LOG_LEVEL = {"d": 'Debug'}
|
||||||
|
MODE_TYPE = {
|
||||||
|
'n': 'normal',
|
||||||
|
'd': 'debug',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def debug_log(log, log_info, mode):
|
||||||
|
if MODE_TYPE['d'] == mode:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["d"]} {log}')
|
||||||
58
ecs/Dockerfile/dataimport/controller.py
Normal file
58
ecs/Dockerfile/dataimport/controller.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
from ini import init
|
||||||
|
from chk import check
|
||||||
|
from main import main
|
||||||
|
from end import end
|
||||||
|
from error import error
|
||||||
|
|
||||||
|
# 引数
|
||||||
|
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"]
|
||||||
|
MODE = os.environ["MODE"]
|
||||||
|
|
||||||
|
# 環境変数
|
||||||
|
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}
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
LOG_LEVEL = {"i": 'Info'}
|
||||||
|
LOG_INFO = f'{DATA_SOURCE_NAME} {FILE_NAME}'
|
||||||
|
|
||||||
|
|
||||||
|
"""コントロール処理
|
||||||
|
|
||||||
|
各処理を呼び出すコントローラー
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ① データ取込処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-01 - データ取込処理を開始します')
|
||||||
|
|
||||||
|
# ② 初期処理を呼び出す
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-02 - 初期処理の呼び出し')
|
||||||
|
settings_key = init(BUCKET_NAME, TARGET_KEY, DATA_SOURCE_NAME, FILE_NAME, LOG_INFO, MODE)
|
||||||
|
|
||||||
|
# ③ チェック処理を呼び出す
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-03 - チェック処理の呼び出し')
|
||||||
|
check(BUCKET_NAME, DATA_SOURCE_NAME, FILE_NAME, settings_key, LOG_INFO, MODE)
|
||||||
|
|
||||||
|
# ④ メイン処理を呼び出す
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-04 - メイン処理の呼び出し')
|
||||||
|
warning_info = main(BUCKET_NAME, DATA_SOURCE_NAME, FILE_NAME, settings_key, DB_INFO, LOG_INFO, MODE)
|
||||||
|
|
||||||
|
# ⑤ 終了処理を呼び出す
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-05 - 終了処理の呼び出し')
|
||||||
|
end(BUCKET_NAME, DATA_SOURCE_NAME, FILE_NAME, warning_info, LOG_INFO, MODE)
|
||||||
|
|
||||||
|
# ⑥ データ取込処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["i"]} I-CTRL-06 - データ取込処理を終了します')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {LOG_INFO} {LOG_LEVEL["e"]} E-CTRL-99 - エラー内容:{e}')
|
||||||
|
error(BUCKET_NAME, DATA_SOURCE_NAME, FILE_NAME, LOG_INFO)
|
||||||
90
ecs/Dockerfile/dataimport/end.py
Normal file
90
ecs/Dockerfile/dataimport/end.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import boto3
|
||||||
|
from error import error
|
||||||
|
from common import debug_log
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
|
||||||
|
DIRECTORY_TARGET = '/target/'
|
||||||
|
DIRECTORY_WORK = '/work/'
|
||||||
|
DIRECTORY_DONE = '/done/'
|
||||||
|
DIRECTORY_WARNING = '/warning/'
|
||||||
|
|
||||||
|
# クラス変数
|
||||||
|
s3_client = boto3.client('s3')
|
||||||
|
s3_resource = boto3.resource('s3')
|
||||||
|
|
||||||
|
|
||||||
|
def end(bucket_name, target_data_source, target_file_name, warning_info, log_info, mode):
|
||||||
|
"""終了処理
|
||||||
|
Args:
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
warning_info : Warning情報
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
mode : 処理モード
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
debug_log(f'引数 bucket_name : {bucket_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_data_source : {target_data_source}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_file_name : {target_file_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 warning_info : {warning_info}', log_info, mode)
|
||||||
|
debug_log(f'引数 log_info : {log_info}', log_info, mode)
|
||||||
|
debug_log(f'引数 mode : {mode}', log_info, mode)
|
||||||
|
|
||||||
|
# ① 終了処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-01 - 終了処理を開始します')
|
||||||
|
|
||||||
|
# ② 投入データファイルをS3バケット内のworkディレクトリから、以下ファイル名でdoneディレクトリに移動(コピー削除)する
|
||||||
|
work_key = target_data_source + DIRECTORY_WORK + target_file_name
|
||||||
|
copy_source = {
|
||||||
|
'Bucket': bucket_name,
|
||||||
|
'Key': work_key
|
||||||
|
}
|
||||||
|
done_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}'
|
||||||
|
done_key = target_data_source + DIRECTORY_DONE + done_file_name
|
||||||
|
done_obj = s3_resource.Object(bucket_name, done_key)
|
||||||
|
done_obj.copy(copy_source)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=work_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-02 - workディレクトリの {target_file_name} をdoneディレクトリに移動しました 移動後ファイル名:{done_file_name}')
|
||||||
|
|
||||||
|
# ③ S3バケット内のtargetディレクトリに存在する「投入データファイル名.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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-03 - targetディレクトリの {doing_file_name} を削除しました')
|
||||||
|
|
||||||
|
# ④ Warning情報が存在するか確認する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-04 - Warning情報の存在チェック')
|
||||||
|
if warning_info:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-05 - Warning情報は存在しました')
|
||||||
|
|
||||||
|
# warningファイルの作成
|
||||||
|
warning_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{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'{datetime.now():%Y-%m-%d %H:%M:%S} {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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-07 - targetディレクトリに {result_warning_file_name} を作成しました')
|
||||||
|
else:
|
||||||
|
# done処理結果ファイルの作成
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-09 - targetディレクトリに {result_done_file_name} を作成しました')
|
||||||
|
|
||||||
|
# ⑤ 終了処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-10 - 終了処理を終了します')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-END-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
102
ecs/Dockerfile/dataimport/error.py
Normal file
102
ecs/Dockerfile/dataimport/error.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import boto3
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
|
||||||
|
DIRECTORY_TARGET = '/target/'
|
||||||
|
DIRECTORY_WORK = '/work/'
|
||||||
|
DIRECTORY_ERROR = '/error/'
|
||||||
|
|
||||||
|
# クラス変数
|
||||||
|
s3_client = boto3.client('s3')
|
||||||
|
s3_resource = boto3.resource('s3')
|
||||||
|
|
||||||
|
|
||||||
|
def error(bucket_name, target_data_source, target_file_name, log_info):
|
||||||
|
"""エラー処理
|
||||||
|
Args:
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ① エラー処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-01 - エラー処理を開始します')
|
||||||
|
|
||||||
|
# ② 投入データファイルをS3バケット内のworkディレクトリから、以下ファイル名でerrorディレクトリに移動(コピー削除)する
|
||||||
|
work_key = target_data_source + DIRECTORY_WORK + target_file_name
|
||||||
|
copy_source = {
|
||||||
|
'Bucket': bucket_name,
|
||||||
|
'Key': work_key
|
||||||
|
}
|
||||||
|
error_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}'
|
||||||
|
error_key = target_data_source + DIRECTORY_ERROR + error_file_name
|
||||||
|
error_obj = s3_resource.Object(bucket_name, error_key)
|
||||||
|
error_obj.copy(copy_source)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=work_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-02 - workディレクトリの {target_file_name} をerrorディレクトリに移動しました 移動後ファイル名:{error_file_name}')
|
||||||
|
|
||||||
|
# ③ S3バケット内のtargetディレクトリに存在する「投入データファイル名.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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-03 - targetディレクトリの {doing_file_name} を削除しました')
|
||||||
|
|
||||||
|
# ④ S3バケット内のtargetディレクトリに、「投入データファイル名.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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-04 - targetディレクトリに {result_error_file_name} を作成しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}')
|
||||||
|
finally:
|
||||||
|
# ⑤ 終了処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-05 - エラー処理を終了します')
|
||||||
|
|
||||||
|
# ⑥ 処理を終了する
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
def error_doing_file_exists(bucket_name, target_key, target_data_source, target_file_name, log_info):
|
||||||
|
""".doingファイルが存在した時のエラー処理
|
||||||
|
Args:
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_key : 投入データのフルパス
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ① エラー処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-06 - doingファイルが存在した時のエラー処理を開始します')
|
||||||
|
|
||||||
|
# ② 投入データファイルをS3バケット内のtargetディレクトリから、以下ファイル名でerrorディレクトリに移動(コピー削除)する
|
||||||
|
copy_source = {
|
||||||
|
'Bucket': bucket_name,
|
||||||
|
'Key': target_key
|
||||||
|
}
|
||||||
|
error_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}'
|
||||||
|
error_key = target_data_source + DIRECTORY_ERROR + error_file_name
|
||||||
|
error_obj = s3_resource.Object(bucket_name, error_key)
|
||||||
|
error_obj.copy(copy_source)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=target_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-07 - targetディレクトリの {target_file_name} をerrorディレクトリに移動しました 移動後ファイル名:{error_file_name}')
|
||||||
|
|
||||||
|
# ③ S3バケット内のtargetディレクトリに、「投入データファイル名.exclusive_error」ファイルを作成する
|
||||||
|
result_error_file_name = target_file_name + '.exclusive_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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-08 - targetディレクトリに {result_error_file_name} を作成しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}')
|
||||||
|
finally:
|
||||||
|
# ④ 終了処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-ERR-09 - doingファイルが存在した時のエラー処理を終了します')
|
||||||
|
|
||||||
|
# ⑤ 処理を終了する
|
||||||
|
sys.exit()
|
||||||
161
ecs/Dockerfile/dataimport/ini.py
Normal file
161
ecs/Dockerfile/dataimport/ini.py
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import boto3
|
||||||
|
import io
|
||||||
|
import csv
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from error import error
|
||||||
|
from error import error_doing_file_exists
|
||||||
|
from common import debug_log
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
LOG_LEVEL = {"i": 'Info', "e": 'Error'}
|
||||||
|
MAPPING_FILE_NAME = 'configmap.config'
|
||||||
|
DIRECTORY_TARGET = '/target/'
|
||||||
|
DIRECTORY_WORK = '/work/'
|
||||||
|
DIRECTORY_SETTINGS = '/settings/'
|
||||||
|
|
||||||
|
# クラス変数
|
||||||
|
s3_client = boto3.client('s3')
|
||||||
|
s3_resource = boto3.resource('s3')
|
||||||
|
|
||||||
|
|
||||||
|
def init(bucket_name, target_key, target_data_source, target_file_name, log_info, mode):
|
||||||
|
"""初期処理
|
||||||
|
Args:
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_key : 投入データのフルパス
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
mode : 処理モード
|
||||||
|
Returns:
|
||||||
|
settings_key : 投入データに該当する個別設定ファイルのフルパス
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
debug_log(f'引数 bucket_name : {bucket_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_key : {target_key}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_data_source : {target_data_source}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_file_name : {target_file_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 log_info : {log_info}', log_info, mode)
|
||||||
|
debug_log(f'引数 mode : {mode}', log_info, mode)
|
||||||
|
|
||||||
|
# ① 初期処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-01 - 初期処理を開始します')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ② S3バケット内のtargetディレクトリに「投入データファイル名.doing」ファイルが存在するかチェックする
|
||||||
|
doing_file_name = target_file_name + '.doing'
|
||||||
|
doing_key = target_data_source + DIRECTORY_TARGET + doing_file_name
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-02 - doingファイル:{doing_file_name} の存在チェック')
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=doing_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-01 - 投入データ {target_file_name} は既に処理中です')
|
||||||
|
error_doing_file_exists(bucket_name, target_key, target_data_source, target_file_name, log_info)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-03 - doingファイルは存在しませんでした')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ③ S3バケット内のtargetディレクトリに、「投入データファイル名.doing」ファイルを作成する
|
||||||
|
doing_obj = s3_resource.Object(bucket_name, doing_key)
|
||||||
|
doing_obj.put(Body='')
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-04 - targetディレクトリに {doing_file_name} を作成しました')
|
||||||
|
|
||||||
|
# ④ 投入データファイルをS3バケット内のtargetディレクトリから、workディレクトリに移動(コピー削除)する
|
||||||
|
copy_source = {
|
||||||
|
'Bucket': bucket_name,
|
||||||
|
'Key': target_key
|
||||||
|
}
|
||||||
|
work_key = target_data_source + DIRECTORY_WORK + target_file_name
|
||||||
|
work_obj = s3_resource.Object(bucket_name, work_key)
|
||||||
|
work_obj.copy(copy_source)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=target_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-05 - 投入データ {target_file_name} をworkディレクトリに移動しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ⑤ S3バケット内のtargetディレクトリの以下ファイル群を削除(前回分の削除)する
|
||||||
|
# doneファイルの存在確認
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {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'
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=result_done_key)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=result_done_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-07 - doneファイルが存在したため削除しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-08 - doneファイルは存在しませんでした')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# warningファイルの存在確認
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {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'
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=result_warning_key)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=result_warning_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-10 - warningファイルが存在したため削除しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-11 - warningファイルは存在しませんでした')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# errorファイルの存在確認
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {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'
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=result_error_key)
|
||||||
|
s3_client.delete_object(Bucket=bucket_name, Key=result_error_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-13 - errorファイルが存在したため削除しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-14 - errorファイルは存在しませんでした')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ⑥ 個別設定マッピングリストが存在するかチェックする
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-15 - 個別設定マッピングリスト:{MAPPING_FILE_NAME} の存在チェック')
|
||||||
|
mapping_key = target_data_source + DIRECTORY_SETTINGS + MAPPING_FILE_NAME
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=mapping_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-16 - 個別設定マッピングリストの存在を確認しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-02 - 個別設定マッピングリストが存在しません')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ⑦ 個別設定ファイルを特定する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-17 - 個別設定ファイルを検索します')
|
||||||
|
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')
|
||||||
|
settings_file_name = ''
|
||||||
|
for row in csv.reader(mapping_body, delimiter='\t'):
|
||||||
|
if row:
|
||||||
|
match_result = re.fullmatch(row[0], target_file_name)
|
||||||
|
if match_result is not None:
|
||||||
|
settings_file_name = row[1].rstrip()
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-18 - 個別設定ファイル:{settings_file_name} を特定しました')
|
||||||
|
break
|
||||||
|
|
||||||
|
if not settings_file_name:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-03 - 個別設定ファイルが特定出来ません')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ⑧ ⑦の個別設定ファイルが存在するかチェックする
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-19 - 個別設定ファイル:{settings_file_name} の存在チェック')
|
||||||
|
settings_key = target_data_source + DIRECTORY_SETTINGS + settings_file_name
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=settings_key)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-20 - 個別設定ファイルの存在を確認しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-04 - 個別設定ファイルが存在しません')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ⑨ 初期処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-21 - 初期処理を終了します')
|
||||||
|
|
||||||
|
return settings_key
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
274
ecs/Dockerfile/dataimport/main.py
Normal file
274
ecs/Dockerfile/dataimport/main.py
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import boto3
|
||||||
|
import pymysql
|
||||||
|
from pymysql.constants import CLIENT
|
||||||
|
import io
|
||||||
|
import csv
|
||||||
|
from error import error
|
||||||
|
from common import debug_log
|
||||||
|
|
||||||
|
# 定数
|
||||||
|
DIRECTORY_WORK = '/work/'
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
LINE_FEED_CODE = {
|
||||||
|
'CR': '\r',
|
||||||
|
'LF': '\n',
|
||||||
|
'CRLF': '\r\n',
|
||||||
|
}
|
||||||
|
DIRECTORY_SETTINGS = '/settings/'
|
||||||
|
|
||||||
|
# クラス変数
|
||||||
|
s3_client = boto3.client('s3')
|
||||||
|
s3_resource = boto3.resource('s3')
|
||||||
|
|
||||||
|
|
||||||
|
def main(bucket_name, target_data_source, target_file_name, settings_key, db_info, log_info, mode):
|
||||||
|
"""メイン処理
|
||||||
|
Args:
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
settings_key : 投入データに該当する個別設定ファイルのフルパス
|
||||||
|
db_info : データベース情報
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
mode : 処理モード
|
||||||
|
Returns:
|
||||||
|
warning_info : Warning情報
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
debug_log(f'引数 bucket_name : {bucket_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_data_source : {target_data_source}', log_info, mode)
|
||||||
|
debug_log(f'引数 target_file_name : {target_file_name}', log_info, mode)
|
||||||
|
debug_log(f'引数 settings_key : {settings_key}', log_info, mode)
|
||||||
|
debug_log(f'引数 db_info : {db_info}', log_info, mode)
|
||||||
|
debug_log(f'引数 log_info : {log_info}', log_info, mode)
|
||||||
|
debug_log(f'引数 mode : {mode}', log_info, mode)
|
||||||
|
|
||||||
|
# ① メイン処理開始ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-01 - メイン処理を開始します')
|
||||||
|
|
||||||
|
# ② DB接続を開始する
|
||||||
|
conn = pymysql.connect(host=db_info["host"], user=db_info["user"], passwd=db_info["pass"], db=db_info["name"], connect_timeout=5, client_flag=CLIENT.MULTI_STATEMENTS)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-02 - DB接続を開始しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ③ タイムゾーンを変更する
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(f'SET time_zone = "+9:00"')
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-03 - タイムゾーンを変更しました')
|
||||||
|
|
||||||
|
# ④ 個別設定ファイルのロードスキーマのテーブル名に記載されているテーブルをTRUNCATEする
|
||||||
|
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('\n'))
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
sql_truncate = f'TRUNCATE table {settings_list[SETTINGS_ITEM["loadSchemaName"]]}'
|
||||||
|
cur.execute(sql_truncate)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-04 - {settings_list[SETTINGS_ITEM["loadSchemaName"]]} をTRUNCATEしました')
|
||||||
|
|
||||||
|
# ⑤ 投入データファイルを1行ごとにループする
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-05 - 投入データ {target_file_name} の読み込みを開始します')
|
||||||
|
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_data = io.TextIOWrapper(io.BytesIO(work_response["Body"].read()), encoding=settings_list[SETTINGS_ITEM["charCode"]], newline=LINE_FEED_CODE[settings_list[SETTINGS_ITEM["lineFeedCode"]]])
|
||||||
|
|
||||||
|
process_count = 0 # 処理件数カウンタ
|
||||||
|
normal_count = 0 # 正常終了件数カウンタ
|
||||||
|
warning_count = 0 # ワーニング終了件数カウンター
|
||||||
|
warning_info = '' # ワーニング情報
|
||||||
|
index = 0 # ループインデックス
|
||||||
|
settings_db_columu_list = settings_list[SETTINGS_ITEM["dbColumuName"]].rstrip().split(',')
|
||||||
|
|
||||||
|
for line in csv.reader(work_data, quotechar=settings_list[SETTINGS_ITEM["quotechar"]], delimiter=settings_list[SETTINGS_ITEM["delimiter"]]):
|
||||||
|
try:
|
||||||
|
if int(settings_list[SETTINGS_ITEM["headerFlag"]]) == True and index == 0:
|
||||||
|
index += 1
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-06 - ヘッダー行をスキップします')
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 処理件数カウント
|
||||||
|
process_count += 1
|
||||||
|
|
||||||
|
# SQL文生成
|
||||||
|
sql = f'INSERT INTO {settings_list[SETTINGS_ITEM["loadSchemaName"]]} ('
|
||||||
|
for i in range(len(settings_db_columu_list)):
|
||||||
|
sql = f'{sql} {settings_db_columu_list[i]},'
|
||||||
|
sql = f'{sql} file_name,' # システム項目:取込ファイル名
|
||||||
|
sql = f'{sql} file_row_cnt,' # システム項目:取込ファイル行番号
|
||||||
|
sql = f'{sql} delete_flg,' # システム項目:論理削除フラグ
|
||||||
|
sql = f'{sql} ins_user,' # システム項目:登録者
|
||||||
|
sql = f'{sql} ins_date,' # システム項目:登録日時
|
||||||
|
sql = f'{sql} upd_user,' # システム項目:更新者
|
||||||
|
sql = f'{sql} upd_date)' # システム項目:更新日時
|
||||||
|
sql = f'{sql} VALUES ('
|
||||||
|
for i in range(len(line)):
|
||||||
|
# データ項目値が0桁より大きいかチェックする
|
||||||
|
if len(line[i]) > 0:
|
||||||
|
# 0桁より大きい場合
|
||||||
|
replace_line = line[i].replace('\\', '\\\\')
|
||||||
|
sql = f'{sql} "{replace_line}",'
|
||||||
|
else:
|
||||||
|
# 上記以外の場合
|
||||||
|
sql = f'{sql} NULL,'
|
||||||
|
sql = f'{sql} "{target_file_name}",' # システム項目:取込ファイル名
|
||||||
|
sql = f'{sql} "{index + 1}",' # システム項目:取込ファイル行番号
|
||||||
|
sql = f'{sql} "0",' # システム項目:論理削除フラグ
|
||||||
|
sql = f'{sql} CURRENT_USER(),' # システム項目:登録者
|
||||||
|
sql = f'{sql} CURRENT_TIMESTAMP(),' # システム項目:登録日時
|
||||||
|
sql = f'{sql} NULL,' # システム項目:更新者
|
||||||
|
sql = f'{sql} NULL)' # システム項目:更新日時
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
debug_log(sql, log_info, mode)
|
||||||
|
|
||||||
|
# ロードスキーマのトランザクション開始
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql)
|
||||||
|
conn.commit()
|
||||||
|
normal_count += 1
|
||||||
|
except Exception as e:
|
||||||
|
warning_count += 1
|
||||||
|
warning_info = f'{warning_info}{index} ロードスキーマ登録時にエラーが発生しました {line} {e}\n'
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["w"]} W-MAIN-01 {index} ロードスキーマ登録時にエラーが発生しました {line} {e}')
|
||||||
|
|
||||||
|
# ⑥ ⑤の処理結果件数をログ出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-07 - 投入データ件数:{process_count} 正常終了件数:{normal_count}')
|
||||||
|
if warning_info:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["w"]} W-MAIN-02 - Warning終了件数:{warning_count}')
|
||||||
|
|
||||||
|
# ⑦ ロードスキーマのデータを蓄積スキーマにUPSERTする
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-08 - ロードスキーマ({settings_list[SETTINGS_ITEM["loadSchemaName"]]})のデータを蓄積スキーマ({settings_list[SETTINGS_ITEM["storageSchemaName"]]})に登録します')
|
||||||
|
|
||||||
|
# SQL文生成
|
||||||
|
sql = f'INSERT INTO {settings_list[SETTINGS_ITEM["storageSchemaName"]]} ('
|
||||||
|
for i in range(len(settings_db_columu_list)):
|
||||||
|
sql = f'{sql} {settings_db_columu_list[i]},'
|
||||||
|
sql = f'{sql} file_name,' # システム項目:取込ファイル名
|
||||||
|
sql = f'{sql} file_row_cnt,' # システム項目:取込ファイル行番号
|
||||||
|
sql = f'{sql} delete_flg,' # システム項目:論理削除フラグ
|
||||||
|
sql = f'{sql} ins_user,' # システム項目:登録者
|
||||||
|
sql = f'{sql} ins_date,' # システム項目:登録日時
|
||||||
|
sql = f'{sql} upd_user,' # システム項目:更新者
|
||||||
|
sql = f'{sql} upd_date)' # システム項目:更新日時
|
||||||
|
sql = f'{sql} SELECT'
|
||||||
|
for i in range(len(settings_db_columu_list)):
|
||||||
|
sql = f'{sql} t.{settings_db_columu_list[i]},'
|
||||||
|
sql = f'{sql} t.file_name,' # システム項目:取込ファイル名
|
||||||
|
sql = f'{sql} t.file_row_cnt,' # システム項目:取込ファイル行番号
|
||||||
|
sql = f'{sql} t.delete_flg,' # システム項目:論理削除フラグ
|
||||||
|
sql = f'{sql} t.ins_user,' # システム項目:登録者
|
||||||
|
sql = f'{sql} t.ins_date,' # システム項目:登録日時
|
||||||
|
sql = f'{sql} t.upd_user,' # システム項目:更新者
|
||||||
|
sql = f'{sql} t.upd_date' # システム項目:更新日時
|
||||||
|
sql = f'{sql} FROM {settings_list[SETTINGS_ITEM["loadSchemaName"]]} as t'
|
||||||
|
sql = f'{sql} ON DUPLICATE KEY UPDATE'
|
||||||
|
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} delete_flg={settings_list[SETTINGS_ITEM["storageSchemaName"]]}.delete_flg,' # システム項目:論理削除フラグ
|
||||||
|
sql = f'{sql} ins_user=t.ins_user,' # システム項目:登録者
|
||||||
|
sql = f'{sql} ins_date=t.ins_date,' # システム項目:登録日時
|
||||||
|
sql = f'{sql} upd_user={settings_list[SETTINGS_ITEM["storageSchemaName"]]}.upd_user,' # システム項目:更新者
|
||||||
|
sql = f'{sql} upd_date={settings_list[SETTINGS_ITEM["storageSchemaName"]]}.upd_date' # システム項目:更新日時
|
||||||
|
|
||||||
|
debug_log(sql, log_info, mode)
|
||||||
|
|
||||||
|
# トランザクション開始
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-09 - 標準SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のトランザクションを開始します')
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql)
|
||||||
|
conn.commit()
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-10 - 標準SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のCOMIIT処理が正常終了しました')
|
||||||
|
|
||||||
|
# ⑧ 個別設定ファイルに拡張SQLファイル名が設定されているかチェック
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-11 - 拡張SQL設定が存在するかチェックします')
|
||||||
|
if settings_list[SETTINGS_ITEM["exSqlFileName"]]:
|
||||||
|
try:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-12 - 拡張SQL設定の存在を確認しました')
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-13 - 拡張SQLファイル名:{settings_list[SETTINGS_ITEM["exSqlFileName"]]} の存在チェック')
|
||||||
|
ex_sql_key = target_data_source + DIRECTORY_SETTINGS + settings_list[SETTINGS_ITEM["exSqlFileName"]]
|
||||||
|
s3_client.head_object(Bucket=bucket_name, Key=ex_sql_key)
|
||||||
|
ex_sql_file_exists = True
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-14 - 拡張SQLファイル名の存在を確認しました')
|
||||||
|
except Exception as e:
|
||||||
|
warning_info = f'{warning_info}- 拡張SQLファイルが存在しません\n'
|
||||||
|
ex_sql_file_exists = False
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["w"]} W-MAIN-03 - 拡張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'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-15 - 拡張SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のトランザクションを開始します')
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(ex_sql)
|
||||||
|
conn.commit()
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-16 - 拡張SQL:{settings_list[SETTINGS_ITEM["storageSchemaName"]]} のCOMIIT処理が正常終了しました')
|
||||||
|
except Exception as e:
|
||||||
|
warning_info = f'{warning_info}- 拡張SQLにエラーが発生しました:{e}\n'
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["w"]} W-MAIN-04 - 拡張SQLにエラーが発生しました:{e}')
|
||||||
|
else:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-17 - 拡張SQL設定の存在はありませんでした')
|
||||||
|
|
||||||
|
# ⑨ DB接続を終了する
|
||||||
|
connection_close(conn, bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||||
|
connection_close(conn, bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# ⑩ メイン処理終了ログを出力する
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-19 - メイン処理を終了します')
|
||||||
|
|
||||||
|
return warning_info
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
|
|
||||||
|
|
||||||
|
def connection_close(conn, bucket_name, target_data_source, target_file_name, log_info):
|
||||||
|
"""DB接続切断処理
|
||||||
|
Args:
|
||||||
|
conn : DBコネクション
|
||||||
|
bucket_name : バケット名
|
||||||
|
target_data_source : 投入データのディレクトリ名よりデータソースに該当する部分
|
||||||
|
target_file_name : 投入データのファイル名
|
||||||
|
log_info : ログに記載するデータソース名とファイル名
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
conn.close()
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-18 - DB接続を終了しました')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-MAIN-99 - エラー内容:{e}')
|
||||||
|
error(bucket_name, target_data_source, target_file_name, log_info)
|
||||||
2
ecs/Dockerfile/requirements.txt
Normal file
2
ecs/Dockerfile/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
boto3
|
||||||
|
PyMySQL
|
||||||
37
lambda/mbj-newdwh2021-staging-NoticeToSlack/index.js
Normal file
37
lambda/mbj-newdwh2021-staging-NoticeToSlack/index.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
"use-strict";
|
||||||
|
|
||||||
|
const request = require("request-promise");
|
||||||
|
exports.handler = (event, context, callback) => {
|
||||||
|
const attaches = event.Records.map(evt => {
|
||||||
|
return {
|
||||||
|
"fallback":`Notification from mbj-newdwh2021 AWS: ${evt.EventSubscriptionArn}`,
|
||||||
|
"pretext":`Notification from mbj-newdwh2021 AWS: ${evt.EventSubscriptionArn}`,
|
||||||
|
"color":"#0000D0",
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"title": `${evt.Sns.Subject}`,
|
||||||
|
"value": `${evt.Sns.Timestamp}: ${evt.Sns.Message} (MessageId: ${evt.Sns.MessageId})`,
|
||||||
|
"short": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
request({
|
||||||
|
method: "POST",
|
||||||
|
url: process.env.webhookurl,
|
||||||
|
body: {
|
||||||
|
attachments: attaches
|
||||||
|
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
}).then((body => {
|
||||||
|
callback(null, `Request succeed. ${body}`);
|
||||||
|
})).catch((err) => {
|
||||||
|
callback("failed to request to slack.", {
|
||||||
|
result: "ERROR",
|
||||||
|
event: event,
|
||||||
|
cause: `request failed. ${err}.`
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
Binary file not shown.
15
lambda/mbj-newdwh2021-staging-NoticeToSlack/package.json
Normal file
15
lambda/mbj-newdwh2021-staging-NoticeToSlack/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "mbj-newdwh2021-staging-noticetoslack",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"request": "^2.88.2",
|
||||||
|
"request-promise": "^4.2.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
lambda/mbj-newdwh2021-staging-PublishFromLog/index.js
Normal file
30
lambda/mbj-newdwh2021-staging-PublishFromLog/index.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const zlib = require("zlib");
|
||||||
|
const aws = require("aws-sdk");
|
||||||
|
const sns = new aws.SNS({
|
||||||
|
apiVersion: "2010-03-31",
|
||||||
|
region: 'ap-northeast-1'
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.handler = function(input, context) {
|
||||||
|
var payload = new Buffer.from(input.awslogs.data, 'base64');
|
||||||
|
zlib.gunzip(payload, function(e, result) {
|
||||||
|
if (e) {
|
||||||
|
context.fail(e);
|
||||||
|
} else {
|
||||||
|
result = JSON.parse(result.toString('UTF-8'));
|
||||||
|
const publishMessage = {
|
||||||
|
Subject: `Detect Error(or Warning) in ${result.logGroup}`,
|
||||||
|
Message: result.logEvents.map((l) => l.message).join('\n'),
|
||||||
|
TopicArn: process.env.topicArn
|
||||||
|
};
|
||||||
|
console.log(publishMessage);
|
||||||
|
|
||||||
|
sns.publish(publishMessage, (err, data) => {
|
||||||
|
console.log(err, data);
|
||||||
|
if(err){
|
||||||
|
context.fail(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
Binary file not shown.
15
lambda/mbj-newdwh2021-staging-PublishFromLog/package.json
Normal file
15
lambda/mbj-newdwh2021-staging-PublishFromLog/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "mbj-newdwh2021-staging-publishfromlog",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"aws-sdk": "^2.1011.0",
|
||||||
|
"zlib": "^1.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
71
lambda/mbj-newdwh2021-staging-lambda-dataimport.py
Normal file
71
lambda/mbj-newdwh2021-staging-lambda-dataimport.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
import boto3
|
||||||
|
|
||||||
|
# 環境変数
|
||||||
|
CLUSTER_NAME = os.environ["CLUSTER_NAME"]
|
||||||
|
TASK_NAME = os.environ["TASK_NAME"]
|
||||||
|
CONTAINER_NAME = os.environ["CONTAINER_NAME"]
|
||||||
|
SUBNET_ID_AP_NORTHEAST_1A = os.environ["SUBNET_ID_AP_NORTHEAST_1A"]
|
||||||
|
SUBNET_ID_AP_NORTHEAST_1D = os.environ["SUBNET_ID_AP_NORTHEAST_1D"]
|
||||||
|
SECURITY_GROUP_ID_ECRAPI = os.environ["SECURITY_GROUP_ID_ECRAPI"]
|
||||||
|
SECURITY_GROUP_ID_ECRDKR = os.environ["SECURITY_GROUP_ID_ECRDKR"]
|
||||||
|
SECURITY_GROUP_ID_LOGS = os.environ["SECURITY_GROUP_ID_LOGS"]
|
||||||
|
SECURITY_GROUP_ID_RDS = os.environ["SECURITY_GROUP_ID_RDS"]
|
||||||
|
MODE = os.environ["MODE"]
|
||||||
|
|
||||||
|
# クラス変数
|
||||||
|
ecs_client = boto3.client('ecs')
|
||||||
|
|
||||||
|
|
||||||
|
def lambda_handler(event, context):
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info I-1 駆動処理開始')
|
||||||
|
|
||||||
|
# イベント情報を取得する
|
||||||
|
s3_event = event["Records"][0]["s3"]
|
||||||
|
event_bucket_name = s3_event["bucket"]["name"]
|
||||||
|
event_object_key = s3_event["object"]["key"]
|
||||||
|
event_file_name = os.path.basename(event_object_key)
|
||||||
|
event_data_source_name = os.path.dirname(event_object_key).split('/')[0]
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info I-2 バケット名:{event_bucket_name}')
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info I-3 ファイル名:{event_file_name}')
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info I-4 データソース名:{event_data_source_name}')
|
||||||
|
|
||||||
|
# ECSを起動する
|
||||||
|
response = ecs_client.run_task(
|
||||||
|
launchType='FARGATE',
|
||||||
|
cluster=CLUSTER_NAME,
|
||||||
|
taskDefinition=TASK_NAME,
|
||||||
|
networkConfiguration={
|
||||||
|
"awsvpcConfiguration": {
|
||||||
|
"subnets": [
|
||||||
|
SUBNET_ID_AP_NORTHEAST_1A,
|
||||||
|
SUBNET_ID_AP_NORTHEAST_1D,
|
||||||
|
],
|
||||||
|
"securityGroups": [
|
||||||
|
SECURITY_GROUP_ID_ECRAPI,
|
||||||
|
SECURITY_GROUP_ID_ECRDKR,
|
||||||
|
SECURITY_GROUP_ID_LOGS,
|
||||||
|
SECURITY_GROUP_ID_RDS,
|
||||||
|
],
|
||||||
|
"assignPublicIp": 'ENABLED',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
overrides={
|
||||||
|
"containerOverrides": [
|
||||||
|
{
|
||||||
|
"name": CONTAINER_NAME,
|
||||||
|
"environment": [
|
||||||
|
{"name": 'BUCKET_NAME', "value": event_bucket_name},
|
||||||
|
{"name": 'TARGET_KEY', "value": event_object_key},
|
||||||
|
{"name": 'DATA_SOURCE_NAME', "value": event_data_source_name},
|
||||||
|
{"name": 'FILE_NAME', "value": event_file_name},
|
||||||
|
{"name": 'MODE', "value": MODE},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info I-5 ECS起動レスポンス:{str(response)}')
|
||||||
|
|
||||||
|
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} Info I-6 駆動処理終了')
|
||||||
Loading…
x
Reference in New Issue
Block a user