Compare commits

..

No commits in common. "master" and "v4.2.0" have entirely different histories.

197 changed files with 3334 additions and 5706 deletions

View File

@ -1,62 +0,0 @@
# EC2インスタンス管理資材
## NLBゲートウェイ インスタンス 起動スクリプト
### 目的
Merck様のDB接続経路としてのNLBから、Auroraデータベースに踏み台アクセスを行うため、ゲートウェイの機能を提供するEC2インスタンスを稼働している。
EC2インスタンス内では、NLBからの任意のポートをAuroraデータベースのポートにフォワーディングするために、`socat`プロセスを動かす必要がある。
`socat`プロセスを動かすためのコマンドと、EC2インスタンス起動時にプロセスを実行するためのsystemdの設定を配置している。
### フォルダ構成
```txt
.
├── README.md -- 当ファイル
└── gateway
├── staging -- ステージング環境用設定
│ ├── public1-1 -- ap-northeast-1aのインスタンス要設定
│ │ ├── socat-dbconnection-1a.service -- systemdにsocatプロセスを登録するためのファイル
│ │ └── socat-portforwarding-1a.sh -- socatでAuroraデータベースにポートフォワーディングするためのシェルスクリプト
│ └── public2-1 -- ap-northeast-1dのインスタンス要設定
│ ├── socat-dbconnection-1d.service
│ └── socat-portforwarding-1d.sh
├── product -- 本番環境用設定
│ ├── public1-1
│ │ ├── socat-dbconnection-1a.service
│ │ └── socat-portforwarding-1a.sh
│ └── public2-1
│ ├── socat-dbconnection-1d.service
│ └── socat-portforwarding-1d.sh
```
### ファイル配置方法(両環境共通)
- 対象のゲートウェイEC2インスタンスにログインする
- セッションマネージャーでログインした場合は、`ec2-user`に切り替えること(`sudo su --login ec2-user`)
- 以下の操作を実行し、`socat`プロセスを起動するシェルスクリプトを配置する。
- **ap-northeast-1aのインスタンス(public-1-1)の場合**
- `sudo vi /opt/socat-portforwarding-1a.sh`コマンドを実行する。
- `ec2/gateway/<環境名>/public-1-1/socat-portforwarding-1a.sh`の内容をコピペして保存する。
- `sudo chmod 774 /opt/socat-portforwarding-1a.sh`コマンドを実行する。
- **ap-northeast-1dのインスタンス(public-2-1)の場合**
- `sudo vi /opt/socat-portforwarding-1d.sh`コマンドを実行する。
- `ec2/gateway/<環境名>/public-2-1/socat-portforwarding-1d.sh`の内容をコピペして保存する。
- `sudo chmod 774 /opt/socat-portforwarding-1d.sh`コマンドを実行する。
- 以下の操作を実行し、`socat`プロセスを常駐させるためのサービス設定ファイルを配置する。
- **ap-northeast-1aのインスタンス(public-1-1)の場合**
- `sudo vi /etc/systemd/system/socat-dbconnection-1a.service`コマンドを実行する。
- `ec2/gateway/<環境名>/public-1-1/socat-dbconnection-1a.service`の内容をコピペして保存する。
- `sudo chmod 774 /etc/systemd/system/socat-dbconnection-1a.service`コマンドを実行する。
- **ap-northeast-1dのインスタンス(public-2-1)の場合**
- `sudo vi /etc/systemd/system/socat-dbconnection-1d.service`コマンドを実行する。
- `ec2/gateway/<環境名>/public-2-1/socat-dbconnection-1d.service`の内容をコピペして保存する。
- `sudo chmod 774 /etc/systemd/system/socat-dbconnection-1d.service`コマンドを実行する。
- 以下の操作を実行し、`socat`プロセスを起動するスクリプトをsystemdに登録する
- **ap-northeast-1aのインスタンス(public-1-1)の場合**
- `sudo systemctl enable socat-dbconnection-1a.service`コマンドを実行し、サービスを有効化する。
- `sudo systemctl status socat-dbconnection-1a.service`コマンドを実行し、サービスのステータスを確認する。`enabled;`となっていればOK
- **ap-northeast-1dのインスタンス(public-2-1)の場合**
- `sudo systemctl enable socat-dbconnection-1d.service`コマンドを実行し、サービスを有効化する。
- `sudo systemctl status socat-dbconnection-1d.service`コマンドを実行し、サービスのステータスを確認する。`enabled;`となっていればOK

View File

@ -1,10 +0,0 @@
[Unit]
Description = socat-dbconnection-1a
[Service]
ExecStart = /opt/socat-portforwarding-1a.sh
Type = oneshot
RemainAfterExit = yes
[Install]
WantedBy = default.target

View File

@ -1,3 +0,0 @@
#!/bin/bash
socat tcp4-listen:40001,reuseaddr,fork TCP:mbj-newdwh2021-product-dbcluster-instance-1.chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &
socat tcp4-listen:50001,reuseaddr,fork TCP:mbj-newdwh2021-product-dbcluster.cluster-chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &

View File

@ -1,10 +0,0 @@
[Unit]
Description = socat-dbconnection-1d
[Service]
ExecStart = /opt/socat-portforwarding-1d.sh
Type = oneshot
RemainAfterExit = yes
[Install]
WantedBy = default.target

View File

@ -1,3 +0,0 @@
#!/bin/bash
socat tcp4-listen:40001,reuseaddr,fork TCP:mbj-newdwh2021-product-dbcluster-instance-1-ap-northeast-1d.chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &
socat tcp4-listen:50001,reuseaddr,fork TCP:mbj-newdwh2021-product-dbcluster.cluster-chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &

View File

@ -1,10 +0,0 @@
[Unit]
Description = socat-dbconnection-1a
[Service]
ExecStart = /opt/socat-portforwarding-1a.sh
Type = oneshot
RemainAfterExit = yes
[Install]
WantedBy = default.target

View File

@ -1,3 +0,0 @@
#!/bin/bash
socat tcp4-listen:40001,reuseaddr,fork TCP:mbj-newdwh2021-staging-dbcluster-instance-1.chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &
socat tcp4-listen:50001,reuseaddr,fork TCP:mbj-newdwh2021-staging-dbcluster.cluster-chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &

View File

@ -1,10 +0,0 @@
[Unit]
Description = socat-dbconnection-1d
[Service]
ExecStart = /opt/socat-portforwarding-1d.sh
Type = oneshot
RemainAfterExit = yes
[Install]
WantedBy = default.target

View File

@ -1,3 +0,0 @@
#!/bin/bash
socat tcp4-listen:40001,reuseaddr,fork TCP:mbj-newdwh2021-staging-dbcluster-instance-1-ap-northeast-1d.chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &
socat tcp4-listen:50001,reuseaddr,fork TCP:mbj-newdwh2021-staging-dbcluster.cluster-chs11qsgoyix.ap-northeast-1.rds.amazonaws.com:3306 &

View File

@ -1,15 +1,15 @@
FROM python:3.12-slim-bookworm FROM python:3.9
ENV TZ="Asia/Tokyo" ENV TZ="Asia/Tokyo"
# pythonの標準出力をバッファリングしないフラグ
ENV PYTHONUNBUFFERED=1
# pythonのバイトコードを生成しないフラグ
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY Pipfile Pipfile.lock ./ COPY Pipfile Pipfile.lock ./
RUN \ RUN \
apt update -y && \ apt update -y && \
# パッケージのセキュリティアップデートのみを適用するコマンド
apt install -y unattended-upgrades && \
unattended-upgrades && \
pip install --upgrade pip wheel setuptools && \
pip install pipenv --no-cache-dir && \ pip install pipenv --no-cache-dir && \
pipenv install --system --deploy && \ pipenv install --system --deploy && \
pip uninstall -y pipenv virtualenv-clone virtualenv pip uninstall -y pipenv virtualenv-clone virtualenv

View File

@ -11,7 +11,7 @@ test = "pytest tests/"
[packages] [packages]
boto3 = "*" boto3 = "*"
simple-salesforce = "==1.12.6" simple-salesforce = "==1.12.4"
tenacity = "*" tenacity = "*"
[dev-packages] [dev-packages]
@ -23,4 +23,4 @@ pytest-html = "*"
moto = "*" moto = "*"
[requires] [requires]
python_version = "3.12" python_version = "3.9"

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
### ツールのバージョン ### ツールのバージョン
- Python 3.12.x - Python 3.9.x
- PipEnv(Pythonの依存関係管理用モジュール) - PipEnv(Pythonの依存関係管理用モジュール)
### 開発環境 ### 開発環境

View File

@ -12,87 +12,87 @@ from src.system_var.environments import (CRM_BACKUP_BUCKET, CRM_CONFIG_BUCKET,
RESPONSE_JSON_BACKUP_FOLDER) RESPONSE_JSON_BACKUP_FOLDER)
class S3Client: class S3Resource:
def __init__(self, bucket_name: str) -> None: def __init__(self, bucket_name: str) -> None:
self.__s3_client = boto3.client(AWS_RESOURCE_S3) self.__s3_resource = boto3.resource(AWS_RESOURCE_S3)
self.__s3_bucket = bucket_name self.__s3_bucket = self.__s3_resource.Bucket(bucket_name)
def get_object(self, object_key: str) -> str: def get_object(self, object_key: str) -> str:
response = self.__s3_client.get_object(Bucket=self.__s3_bucket, Key=object_key) response = self.__s3_bucket.Object(object_key).get()
body = response[S3_RESPONSE_BODY].read() body = response[S3_RESPONSE_BODY].read()
return body.decode(S3_CHAR_CODE) return body.decode(S3_CHAR_CODE)
def put_object(self, object_key: str, local_file_path: str) -> None: def put_object(self, object_key: str, local_file_path: str) -> None:
self.__s3_client.upload_file(Filename=local_file_path, Bucket=self.__s3_bucket, Key=object_key) self.__s3_bucket.upload_file(Key=object_key, Filename=local_file_path)
return return
def copy(self, src_bucket: str, src_key: str, dest_bucket: str, dest_key: str) -> None: def copy(self, src_bucket: str, src_key: str, dest_bucket: str, dest_key: str) -> None:
copy_source = {'Bucket': src_bucket, 'Key': src_key} copy_source = {'Bucket': src_bucket, 'Key': src_key}
self.__s3_client.copy_object(CopySource=copy_source, Bucket=dest_bucket, Key=dest_key) self.__s3_resource.meta.client.copy(copy_source, dest_bucket, dest_key)
return return
class ConfigBucket: class ConfigBucket:
__s3_client: S3Client = None __s3_resource: S3Resource = None
def __init__(self) -> None: def __init__(self) -> None:
self.__s3_client = S3Client(CRM_CONFIG_BUCKET) self.__s3_resource = S3Resource(CRM_CONFIG_BUCKET)
def __str__(self) -> str: def __str__(self) -> str:
return CRM_CONFIG_BUCKET return CRM_CONFIG_BUCKET
def get_object_info_file(self) -> str: def get_object_info_file(self) -> str:
return self.__s3_client.get_object(f'{OBJECT_INFO_FOLDER}/{OBJECT_INFO_FILENAME}') return self.__s3_resource.get_object(f'{OBJECT_INFO_FOLDER}/{OBJECT_INFO_FILENAME}')
def get_last_fetch_datetime_file(self, file_key: str) -> str: def get_last_fetch_datetime_file(self, file_key: str) -> str:
return self.__s3_client.get_object(f'{LAST_FETCH_DATE_FOLDER}/{file_key}') return self.__s3_resource.get_object(f'{LAST_FETCH_DATE_FOLDER}/{file_key}')
def put_last_fetch_datetime_file(self, file_key: str, local_file_path: str) -> None: def put_last_fetch_datetime_file(self, file_key: str, local_file_path: str) -> None:
self.__s3_client.put_object( self.__s3_resource.put_object(
f'{LAST_FETCH_DATE_FOLDER}/{file_key}', local_file_path) f'{LAST_FETCH_DATE_FOLDER}/{file_key}', local_file_path)
return return
class DataBucket: class DataBucket:
__s3_client: S3Client = None __s3_resource: S3Resource = None
def __init__(self) -> None: def __init__(self) -> None:
self.__s3_client = S3Client(IMPORT_DATA_BUCKET) self.__s3_resource = S3Resource(IMPORT_DATA_BUCKET)
def __str__(self) -> str: def __str__(self) -> str:
return IMPORT_DATA_BUCKET return IMPORT_DATA_BUCKET
def put_csv(self, file_key: str, local_file_path: str) -> None: def put_csv(self, file_key: str, local_file_path: str) -> None:
object_key = f'{CRM_IMPORT_DATA_FOLDER}/{file_key}' object_key = f'{CRM_IMPORT_DATA_FOLDER}/{file_key}'
self.__s3_client.put_object(object_key, local_file_path) self.__s3_resource.put_object(object_key, local_file_path)
return return
def put_csv_from(self, src_bucket: str, src_key: str): def put_csv_from(self, src_bucket: str, src_key: str):
dest_filename = src_key.split('/')[-1] dest_filename = src_key.split('/')[-1]
self.__s3_client.copy(src_bucket, src_key, str(self), f'{CRM_IMPORT_DATA_FOLDER}/{dest_filename}') self.__s3_resource.copy(src_bucket, src_key, str(self), f'{CRM_IMPORT_DATA_FOLDER}/{dest_filename}')
return return
class BackupBucket: class BackupBucket:
__s3_client: S3Client = None __s3_resource: S3Resource = None
def __init__(self) -> None: def __init__(self) -> None:
self.__s3_client = S3Client(CRM_BACKUP_BUCKET) self.__s3_resource = S3Resource(CRM_BACKUP_BUCKET)
def __str__(self) -> str: def __str__(self) -> str:
return CRM_BACKUP_BUCKET return CRM_BACKUP_BUCKET
def put_response_json(self, file_key: str, local_file_path: str) -> None: def put_response_json(self, file_key: str, local_file_path: str) -> None:
object_key = f'{RESPONSE_JSON_BACKUP_FOLDER}/{file_key}' object_key = f'{RESPONSE_JSON_BACKUP_FOLDER}/{file_key}'
self.__s3_client.put_object(object_key, local_file_path) self.__s3_resource.put_object(object_key, local_file_path)
return return
def put_csv(self, file_key: str, local_file_path: str) -> None: def put_csv(self, file_key: str, local_file_path: str) -> None:
object_key = f'{CRM_IMPORT_DATA_BACKUP_FOLDER}/{file_key}' object_key = f'{CRM_IMPORT_DATA_BACKUP_FOLDER}/{file_key}'
self.__s3_client.put_object(object_key, local_file_path) self.__s3_resource.put_object(object_key, local_file_path)
return return
def put_result_json(self, file_key: str, local_file_path: str) -> None: def put_result_json(self, file_key: str, local_file_path: str) -> None:
object_key = f'{PROCESS_RESULT_FOLDER}/{file_key}' object_key = f'{PROCESS_RESULT_FOLDER}/{file_key}'
self.__s3_client.put_object(object_key, local_file_path) self.__s3_resource.put_object(object_key, local_file_path)
return return

View File

@ -1,8 +1,7 @@
import os import os
import pytest import pytest
from src.aws.s3 import BackupBucket, ConfigBucket, DataBucket, S3Resource
from src.aws.s3 import BackupBucket, ConfigBucket, DataBucket, S3Client
@pytest.fixture @pytest.fixture
@ -16,7 +15,7 @@ def s3_test(s3_client, bucket_name):
yield yield
class TestS3Client: class TestS3Resource:
def test_get_object(self, s3_test, s3_client, bucket_name): def test_get_object(self, s3_test, s3_client, bucket_name):
""" """
@ -32,7 +31,7 @@ class TestS3Client:
s3_client.put_object(Bucket=bucket_name, Key='hogehoge/test.txt', Body=b'aaaaaaaaaaaaaaa') s3_client.put_object(Bucket=bucket_name, Key='hogehoge/test.txt', Body=b'aaaaaaaaaaaaaaa')
# Act # Act
sut = S3Client(bucket_name) sut = S3Resource(bucket_name)
actual = sut.get_object('hogehoge/test.txt') actual = sut.get_object('hogehoge/test.txt')
# Assert # Assert
@ -49,7 +48,7 @@ class TestS3Client:
""" """
# Arrange # Arrange
# Act # Act
sut = S3Client(bucket_name) sut = S3Resource(bucket_name)
with pytest.raises(Exception): with pytest.raises(Exception):
# Assert # Assert
sut.get_object('hogehoge/test.txt') sut.get_object('hogehoge/test.txt')
@ -69,7 +68,7 @@ class TestS3Client:
with open(file_path, mode='w') as f: with open(file_path, mode='w') as f:
f.write('aaaaaaaaaaaaaaa') f.write('aaaaaaaaaaaaaaa')
sut = S3Client(bucket_name) sut = S3Resource(bucket_name)
sut.put_object('hogehoge/test.txt', file_path) sut.put_object('hogehoge/test.txt', file_path)
actual = s3_client.get_object(Bucket=bucket_name, Key='hogehoge/test.txt') actual = s3_client.get_object(Bucket=bucket_name, Key='hogehoge/test.txt')
@ -88,7 +87,7 @@ class TestS3Client:
""" """
# Arrange # Arrange
# Act # Act
sut = S3Client(bucket_name) sut = S3Resource(bucket_name)
with pytest.raises(Exception): with pytest.raises(Exception):
# Assert # Assert
sut.put_object('hogehoge/test.txt', 'aaaaaaaaaaaaaaa') sut.put_object('hogehoge/test.txt', 'aaaaaaaaaaaaaaa')
@ -109,7 +108,7 @@ class TestS3Client:
s3_client.create_bucket(Bucket=for_copy_bucket) s3_client.create_bucket(Bucket=for_copy_bucket)
s3_client.put_object(Bucket=bucket_name, Key='hogehoge/test.txt', Body=b'aaaaaaaaaaaaaaa') s3_client.put_object(Bucket=bucket_name, Key='hogehoge/test.txt', Body=b'aaaaaaaaaaaaaaa')
sut = S3Client(bucket_name) sut = S3Resource(bucket_name)
sut.copy(bucket_name, 'hogehoge/test.txt', for_copy_bucket, 'test.txt') sut.copy(bucket_name, 'hogehoge/test.txt', for_copy_bucket, 'test.txt')
actual = s3_client.get_object(Bucket=for_copy_bucket, Key='test.txt') actual = s3_client.get_object(Bucket=for_copy_bucket, Key='test.txt')
@ -126,7 +125,7 @@ class TestS3Client:
""" """
# Arrange # Arrange
# Act # Act
sut = S3Client(bucket_name) sut = S3Resource(bucket_name)
with pytest.raises(Exception): with pytest.raises(Exception):
# Assert # Assert
sut.copy(bucket_name, 'hogehoge/test.txt', 'for_copy_bucket', 'test.txt') sut.copy(bucket_name, 'hogehoge/test.txt', 'for_copy_bucket', 'test.txt')
@ -141,8 +140,8 @@ class TestS3Client:
- インスタンス生成時に例外が発生すること - インスタンス生成時に例外が発生すること
""" """
with pytest.raises(Exception) as e: with pytest.raises(Exception) as e:
S3Client() S3Resource()
assert e.value.args[0] == "S3Client.__init__() missing 1 required positional argument: 'bucket_name'" assert e.value.args[0] == "__init__() missing 1 required positional argument: 'bucket_name'"
class TestConfigBucket: class TestConfigBucket:

View File

@ -4,7 +4,8 @@ from datetime import datetime
import boto3 import boto3
import pytest import pytest
from moto import mock_aws from moto import mock_s3
from py.xml import html # type: ignore
from . import docstring_parser from . import docstring_parser
@ -20,7 +21,7 @@ def aws_credentials():
@pytest.fixture @pytest.fixture
def s3_client(aws_credentials): def s3_client(aws_credentials):
with mock_aws(): with mock_s3():
conn = boto3.client("s3", region_name="us-east-1") conn = boto3.client("s3", region_name="us-east-1")
yield conn yield conn
@ -34,18 +35,18 @@ def pytest_html_report_title(report):
def pytest_html_results_table_header(cells): def pytest_html_results_table_header(cells):
del cells[2:] del cells[2:]
cells.insert(3, '<th>Cases</th>') cells.insert(3, html.th("Cases"))
cells.insert(4, '<th>Arranges</th>') cells.insert(4, html.th("Arranges"))
cells.insert(5, '<th>Expects</th>') cells.insert(5, html.th("Expects"))
cells.append('<th class="sortable time" col="time">Time</th>') cells.append(html.th("Time", class_="sortable time", col="time"))
def pytest_html_results_table_row(report, cells): def pytest_html_results_table_row(report, cells):
del cells[2:] del cells[2:]
cells.insert(3, f'<td><pre>{report.cases}</pre></td>') # 「テスト内容」をレポートに出力 cells.insert(3, html.td(html.pre(report.cases))) # 「テスト内容」をレポートに出力
cells.insert(4, f'<td><pre>{report.arranges}</pre></td>') # 「期待結果」をレポートに出力 cells.insert(4, html.td(html.pre(report.arranges))) # 「期待結果」をレポートに出力
cells.insert(5, f'<td><pre>{report.expects}</pre></td>') # 「期待結果」をレポートに出力 cells.insert(5, html.td(html.pre(report.expects))) # 「期待結果」をレポートに出力
cells.append(f'<td class="col-time">{datetime.now()}</td>') # ついでに「時間」もレポートに出力 cells.append(html.td(datetime.now(), class_="col-time")) # ついでに「時間」もレポートに出力
@pytest.hookimpl(hookwrapper=True) @pytest.hookimpl(hookwrapper=True)

View File

@ -652,8 +652,7 @@ class TestSalesforceApiClient:
actual = sut.fetch_sf_data(soql) actual = sut.fetch_sf_data(soql)
assert len(actual) > 0 assert len(actual) > 0
print(dict(actual[0])) assert dict(actual[0])["RelationshipTest__r"]["RecordType"]["DeveloperName"] == "RecordTypeSpecial"
assert dict(actual[0])["RelationshipTest__r"]["RecordType"]["DeveloperName"] == "RecordTypeNormal"
def test_raise_create_instance_cause_auth_failed(self, monkeypatch): def test_raise_create_instance_cause_auth_failed(self, monkeypatch):
""" """

View File

@ -99,9 +99,8 @@ class TestCounterObject:
sut = CounterObject() sut = CounterObject()
sut.describe(1) sut.describe(1)
print(str(e.value))
# Expects # Expects
assert str(e.value) == 'CounterObject.describe() takes 1 positional argument but 2 were given' assert str(e.value) == 'describe() takes 1 positional argument but 2 were given'
def test_increment(self) -> int: def test_increment(self) -> int:
""" """

View File

@ -1,19 +1,16 @@
FROM python:3.12-slim-bookworm FROM python:3.9
ENV TZ="Asia/Tokyo" ENV TZ="Asia/Tokyo"
# pythonの標準出力をバッファリングしないフラグ
ENV PYTHONUNBUFFERED=1
# pythonのバイトコードを生成しないフラグ
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY Pipfile Pipfile.lock ./ COPY requirements.txt ./
RUN \ RUN \
apt update -y && \ apt update -y && \
pip install pipenv --no-cache-dir && \ # パッケージのセキュリティアップデートのみを適用するコマンド
pipenv install --system --deploy && \ apt install -y unattended-upgrades && \
pip uninstall -y pipenv virtualenv-clone virtualenv unattended-upgrades && \
pip install --upgrade pip wheel setuptools && \
pip install --no-cache-dir -r requirements.txt
COPY dataimport ./ COPY dataimport ./
CMD [ "python", "./controller.py" ] CMD [ "python", "./controller.py" ]

View File

@ -1,13 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
boto3 = "*"
pymysql = "*"
[dev-packages]
[requires]
python_version = "3.12"

View File

@ -1,87 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "1738beec0de1a16f127d9bbeef1c9cb1ffb5b2377aa1aedbce9bfacae0fa1c67"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.12"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"boto3": {
"hashes": [
"sha256:3faa2c328a61745f3215a63039606a6fcf55d9afe1cc76e3a5e27b9db58cdbf6",
"sha256:b998edac72f6740bd5d9d585cf3880f2dfeb4842e626b34430fd0e9623378011"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==1.38.32"
},
"botocore": {
"hashes": [
"sha256:0899a090e352cb5eeaae2c7bb52a987b469d23912c7ece86664dfb5c2e074978",
"sha256:64ab919a5d8b74dd73eaac1f978d0e674d11ff3bbe8815c3d2982477be9a082c"
],
"markers": "python_version >= '3.9'",
"version": "==1.38.32"
},
"jmespath": {
"hashes": [
"sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980",
"sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"
],
"markers": "python_version >= '3.7'",
"version": "==1.0.1"
},
"pymysql": {
"hashes": [
"sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c",
"sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==1.1.1"
},
"python-dateutil": {
"hashes": [
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.9.0.post0"
},
"s3transfer": {
"hashes": [
"sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be",
"sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177"
],
"markers": "python_version >= '3.9'",
"version": "==0.13.0"
},
"six": {
"hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",
"sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==1.17.0"
},
"urllib3": {
"hashes": [
"sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466",
"sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"
],
"markers": "python_version >= '3.9'",
"version": "==2.4.0"
}
},
"develop": {}
}

View File

@ -4,6 +4,7 @@ import sys
from datetime import datetime from datetime import datetime
import boto3 import boto3
from common import convert_quotechar, debug_log from common import convert_quotechar, debug_log
from end import end from end import end
from error import error from error import error
@ -40,7 +41,7 @@ LINE_FEED_CODE = {
} }
# クラス変数 # クラス変数
s3_client = boto3.client('s3') s3_resource = boto3.resource('s3')
# チェック例外クラス # チェック例外クラス
@ -73,14 +74,16 @@ def check(bucket_name, target_data_source, target_file_name, settings_key, log_i
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-01 - チェック処理を開始します') print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-CHK-01 - チェック処理を開始します')
# データ読込 # データ読込
settings_obj_response = s3_client.get_object(Bucket=bucket_name, Key=settings_key) settings_obj = s3_resource.Object(bucket_name, settings_key)
settings_response = settings_obj.get()
settings_list = [] settings_list = []
for line in io.TextIOWrapper(io.BytesIO(settings_obj_response["Body"].read()), encoding='utf-8'): for line in io.TextIOWrapper(io.BytesIO(settings_response["Body"].read()), encoding='utf-8'):
settings_list.append(line.rstrip('\n')) settings_list.append(line.rstrip('\n'))
work_key = target_data_source + DIRECTORY_WORK + target_file_name work_key = target_data_source + DIRECTORY_WORK + target_file_name
work_obj_response = s3_client.get_object(Bucket=bucket_name, Key=work_key) work_obj = s3_resource.Object(bucket_name, work_key)
work_data = io.TextIOWrapper(io.BytesIO(work_obj_response["Body"].read()), encoding=settings_list[SETTINGS_ITEM["charCode"]], newline=LINE_FEED_CODE[settings_list[SETTINGS_ITEM["lineFeedCode"]]]) 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_csv_row = [] work_csv_row = []
for i, line in enumerate(csv.reader(work_data, quotechar=convert_quotechar(settings_list[SETTINGS_ITEM["quotechar"]]), delimiter=settings_list[SETTINGS_ITEM["delimiter"]])): for i, line in enumerate(csv.reader(work_data, quotechar=convert_quotechar(settings_list[SETTINGS_ITEM["quotechar"]]), delimiter=settings_list[SETTINGS_ITEM["delimiter"]])):
# ヘッダあり、かつ、1行目の場合 # ヘッダあり、かつ、1行目の場合
@ -145,16 +148,3 @@ def is_empty_file(work_csv_row: list, settings_list: list):
return len(work_csv_row[1:]) == 0 return len(work_csv_row[1:]) == 0
return len(work_csv_row) == 0 return len(work_csv_row) == 0
# ローカル実行用コード
# 値はよしなに変えてください
# if __name__ == '__main__':
# check(
# bucket_name='バケット名',
# target_data_source='データソース名',
# target_file_name='targetフォルダ内のファイル名',
# settings_key='個別設定ファイル名',
# log_info='Info',
# mode='i'
# )

View File

@ -1,8 +1,7 @@
from datetime import datetime from datetime import datetime
import boto3 import boto3
from common import debug_log
from error import error from error import error
from common import debug_log
# 定数 # 定数
LOG_LEVEL = {'i': 'Info', 'e': 'Error'} LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
@ -13,6 +12,7 @@ DIRECTORY_WARNING = '/warning/'
# クラス変数 # クラス変数
s3_client = boto3.client('s3') 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): def end(bucket_name, target_data_source, target_file_name, warning_info, log_info, mode):
@ -45,7 +45,8 @@ def end(bucket_name, target_data_source, target_file_name, warning_info, log_inf
} }
done_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}' 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_key = target_data_source + DIRECTORY_DONE + done_file_name
s3_client.copy(CopySource=copy_source, Bucket=bucket_name, Key=done_key) done_obj = s3_resource.Object(bucket_name, done_key)
done_obj.copy(copy_source)
s3_client.delete_object(Bucket=bucket_name, Key=work_key) 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}') 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}')
@ -63,20 +64,23 @@ def end(bucket_name, target_data_source, target_file_name, warning_info, log_inf
# warningファイルの作成 # warningファイルの作成
warning_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}_war.log' 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_key = target_data_source + DIRECTORY_WARNING + warning_file_name
s3_client.put_object(Bucket=bucket_name, Key=warning_key, Body=bytes(warning_info, 'utf-8')) 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} を作成しました') print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-06 - warningディレクトリに {warning_file_name} を作成しました')
# warning処理結果ファイルの作成 # warning処理結果ファイルの作成
result_warning_file_name = target_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_key = target_data_source + DIRECTORY_TARGET + result_warning_file_name
s3_client.put_object(Bucket=bucket_name, Key=result_warning_key, Body=b'') 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} を作成しました') print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-07 - targetディレクトリに {result_warning_file_name} を作成しました')
else: else:
# done処理結果ファイルの作成 # done処理結果ファイルの作成
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-END-08 - Warning情報は存在しませんでした') 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_file_name = target_file_name + '.done'
result_done_key = target_data_source + DIRECTORY_TARGET + result_done_file_name result_done_key = target_data_source + DIRECTORY_TARGET + result_done_file_name
s3_client.put_object(Bucket=bucket_name, Key=result_done_key, Body=b'') 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-09 - targetディレクトリに {result_done_file_name} を作成しました')
# ⑤ 終了処理終了ログを出力する # ⑤ 終了処理終了ログを出力する
@ -84,17 +88,3 @@ def end(bucket_name, target_data_source, target_file_name, warning_info, log_inf
except Exception as e: except Exception as e:
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-END-99 - エラー内容:{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) error(bucket_name, target_data_source, target_file_name, log_info)
# ローカル実行用コード
# 値はよしなに変えてください
# if __name__ == '__main__':
# end(
# bucket_name='バケット名',
# target_data_source='データソース名',
# target_file_name='targetフォルダ内のファイル',
# # warning_info='ワーニング内容', # ワーニングがある場合のテストはこちらを生かす
# warning_info='',
# log_info='Info',
# mode='i'
# )

View File

@ -1,7 +1,6 @@
import sys
from datetime import datetime from datetime import datetime
import boto3 import boto3
import sys
# 定数 # 定数
LOG_LEVEL = {'i': 'Info', 'e': 'Error'} LOG_LEVEL = {'i': 'Info', 'e': 'Error'}
@ -11,6 +10,7 @@ DIRECTORY_ERROR = '/error/'
# クラス変数 # クラス変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
def error(bucket_name, target_data_source, target_file_name, log_info): def error(bucket_name, target_data_source, target_file_name, log_info):
@ -34,7 +34,8 @@ def error(bucket_name, target_data_source, target_file_name, log_info):
} }
error_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}' 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_key = target_data_source + DIRECTORY_ERROR + error_file_name
s3_client.copy(CopySource=copy_source, Bucket=bucket_name, Key=error_key) error_obj = s3_resource.Object(bucket_name, error_key)
error_obj.copy(copy_source)
s3_client.delete_object(Bucket=bucket_name, Key=work_key) 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}') 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}')
@ -47,7 +48,8 @@ def error(bucket_name, target_data_source, target_file_name, log_info):
# ④ S3バケット内のtargetディレクトリに、「投入データファイル名.error」ファイルを作成する # ④ S3バケット内のtargetディレクトリに、「投入データファイル名.error」ファイルを作成する
result_error_file_name = target_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_key = target_data_source + DIRECTORY_TARGET + result_error_file_name
s3_client.put_object(Bucket=bucket_name, Key=result_error_key, Body=b'') 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} を作成しました') 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: except Exception as e:
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}') print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}')
@ -79,14 +81,16 @@ def error_doing_file_exists(bucket_name, target_key, target_data_source, target_
} }
error_file_name = f'{datetime.now():%Y%m%d%H%M%S}_{target_file_name}' 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_key = target_data_source + DIRECTORY_ERROR + error_file_name
s3_client.copy(CopySource=copy_source, Bucket=bucket_name, Key=error_key) error_obj = s3_resource.Object(bucket_name, error_key)
error_obj.copy(copy_source)
s3_client.delete_object(Bucket=bucket_name, Key=target_key) 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}') 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」ファイルを作成する # ③ S3バケット内のtargetディレクトリに、「投入データファイル名.exclusive_error」ファイルを作成する
result_error_file_name = target_file_name + '.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_key = target_data_source + DIRECTORY_TARGET + result_error_file_name
s3_client.put_object(Bucket=bucket_name, Key=result_error_key, Body=b'') 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} を作成しました') 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: except Exception as e:
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}') print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-ERR-99 - エラー内容:{e}')
@ -96,24 +100,3 @@ def error_doing_file_exists(bucket_name, target_key, target_data_source, target_
# ⑤ 処理を終了する # ⑤ 処理を終了する
sys.exit() sys.exit()
# ローカル実行用コード
# 値はよしなに変えてください
# if __name__ == '__main__':
# エラー処理
# error(
# bucket_name='バケット名',
# target_data_source='データソース名',
# target_file_name='データソース名/target/ファイル名',
# log_info='Info'
# )
# doingファイルの有無チェック関数
# error_doing_file_exists(
# bucket_name='バケット名',
# target_key='投入データのフルパス',
# target_data_source='投入データのディレクトリ名よりデータソースに該当する部分',
# target_file_name='投入データのファイル名',
# log_info='Info'
# )

View File

@ -1,12 +1,12 @@
import csv from datetime import datetime
import boto3
import io import io
import csv
import re import re
import sys import sys
from datetime import datetime from error import error
from error import error_doing_file_exists
import boto3
from common import debug_log from common import debug_log
from error import error, error_doing_file_exists
# 定数 # 定数
LOG_LEVEL = {"i": 'Info', "e": 'Error'} LOG_LEVEL = {"i": 'Info', "e": 'Error'}
@ -17,6 +17,7 @@ DIRECTORY_SETTINGS = '/settings/'
# クラス変数 # クラス変数
s3_client = boto3.client('s3') 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): def init(bucket_name, target_key, target_data_source, target_file_name, log_info, mode):
@ -59,7 +60,8 @@ def init(bucket_name, target_key, target_data_source, target_file_name, log_info
try: try:
# ③ S3バケット内のtargetディレクトリに、「投入データファイル名.doing」ファイルを作成する # ③ S3バケット内のtargetディレクトリに、「投入データファイル名.doing」ファイルを作成する
s3_client.put_object(Bucket=bucket_name, Key=doing_key, Body=b'') 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} を作成しました') 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ディレクトリに移動(コピー削除)する # ④ 投入データファイルをS3バケット内のtargetディレクトリから、workディレクトリに移動(コピー削除)する
@ -68,7 +70,8 @@ def init(bucket_name, target_key, target_data_source, target_file_name, log_info
'Key': target_key 'Key': target_key
} }
work_key = target_data_source + DIRECTORY_WORK + target_file_name work_key = target_data_source + DIRECTORY_WORK + target_file_name
s3_client.copy(CopySource=copy_source, Bucket=bucket_name, Key=work_key) work_obj = s3_resource.Object(bucket_name, work_key)
work_obj.copy(copy_source)
s3_client.delete_object(Bucket=bucket_name, Key=target_key) 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ディレクトリに移動しました') 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: except Exception as e:
@ -119,8 +122,9 @@ def init(bucket_name, target_key, target_data_source, target_file_name, log_info
try: try:
# ⑦ 個別設定ファイルを特定する # ⑦ 個別設定ファイルを特定する
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-17 - 個別設定ファイルを検索します') print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-INI-17 - 個別設定ファイルを検索します')
mapping_obj_response = s3_client.get_object(Bucket=bucket_name, Key=mapping_key) mapping_obj = s3_resource.Object(bucket_name, mapping_key)
mapping_body = io.TextIOWrapper(io.BytesIO(mapping_obj_response["Body"].read()), encoding='utf-8') mapping_response = mapping_obj.get()
mapping_body = io.TextIOWrapper(io.BytesIO(mapping_response["Body"].read()), encoding='utf-8')
settings_file_name = '' settings_file_name = ''
for row in csv.reader(mapping_body, delimiter='\t'): for row in csv.reader(mapping_body, delimiter='\t'):
if row: if row:
@ -155,15 +159,3 @@ def init(bucket_name, target_key, target_data_source, target_file_name, log_info
except Exception as e: except Exception as e:
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["e"]} E-INI-99 - エラー内容:{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) error(bucket_name, target_data_source, target_file_name, log_info)
# ローカル実行用コード
# 値はよしなに変えてください
# if __name__ == '__main__':
# init(
# bucket_name='バケット名',
# target_key='データソース名/target/ファイル名',
# target_data_source='データソース名',
# target_file_name='ファイル名',
# log_info='Info',
# mode='i'
# )

View File

@ -5,9 +5,10 @@ from datetime import datetime
import boto3 import boto3
import pymysql import pymysql
from pymysql.constants import CLIENT
from common import convert_quotechar, debug_log from common import convert_quotechar, debug_log
from error import error from error import error
from pymysql.constants import CLIENT
# 定数 # 定数
DIRECTORY_WORK = '/work/' DIRECTORY_WORK = '/work/'
@ -46,6 +47,7 @@ INVALID_CONFIG_EXCEPTION_MESSAGE = f'個別設定ファイルのインポート
# クラス変数 # クラス変数
s3_client = boto3.client('s3') 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): def main(bucket_name, target_data_source, target_file_name, settings_key, db_info, log_info, mode):
@ -89,7 +91,8 @@ def main(bucket_name, target_data_source, target_file_name, settings_key, db_inf
# ④ 個別設定ファイルのロードスキーマのテーブル名に記載されているテーブルをTRUNCATEする # ④ 個別設定ファイルのロードスキーマのテーブル名に記載されているテーブルをTRUNCATEする
# 個別設定ファイルの読み込み # 個別設定ファイルの読み込み
settings_response = s3_client.get_object(Bucket=bucket_name, Key=settings_key) settings_obj = s3_resource.Object(bucket_name, settings_key)
settings_response = settings_obj.get()
settings_list = [] settings_list = []
for line in io.TextIOWrapper(io.BytesIO(settings_response["Body"].read()), encoding='utf-8'): for line in io.TextIOWrapper(io.BytesIO(settings_response["Body"].read()), encoding='utf-8'):
settings_list.append(line.rstrip('\n')) settings_list.append(line.rstrip('\n'))
@ -107,7 +110,8 @@ def main(bucket_name, target_data_source, target_file_name, settings_key, db_inf
# ⑤ 投入データファイルを1行ごとにループする # ⑤ 投入データファイルを1行ごとにループする
print(f'{datetime.now():%Y-%m-%d %H:%M:%S} {log_info} {LOG_LEVEL["i"]} I-MAIN-05 - 投入データ {target_file_name} の読み込みを開始します') 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_key = target_data_source + DIRECTORY_WORK + target_file_name
work_response = s3_client.get_object(Bucket=bucket_name, Key=work_key) 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_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 # 処理件数カウンタ process_count = 0 # 処理件数カウンタ
@ -257,9 +261,10 @@ def main(bucket_name, target_data_source, target_file_name, settings_key, db_inf
try: try:
if ex_sql_file_exists: if ex_sql_file_exists:
# 拡張SQLファイルからSQL文生成 # 拡張SQLファイルからSQL文生成
ex_sql_obj_response = s3_client.get_object(Bucket=bucket_name, Key=ex_sql_key) ex_sqls_obj = s3_resource.Object(bucket_name, ex_sql_key)
ex_sql_response = ex_sqls_obj.get()
ex_sql = '' ex_sql = ''
for line in io.TextIOWrapper(io.BytesIO(ex_sql_obj_response["Body"].read()), encoding='utf-8'): for line in io.TextIOWrapper(io.BytesIO(ex_sql_response["Body"].read()), encoding='utf-8'):
ex_sql = f'{ex_sql} {line.rstrip()}' ex_sql = f'{ex_sql} {line.rstrip()}'
# トランザクション開始 # トランザクション開始
@ -353,18 +358,3 @@ def truncate_judge(settings_list):
class InvalidConfigException(Exception): class InvalidConfigException(Exception):
pass pass
# ローカル実行用コード
# 値はよしなに変えてください
# if __name__ == '__main__':
# DB_INFO = {"host": '127.0.0.1', "name": 'org02', "pass": 'user', "user": 'user'}
# main(
# bucket_name='バケット名',
# target_data_source='投入データのディレクトリ名よりデータソースに該当する部分',
# target_file_name='投入データのファイル名',
# settings_key='投入データに該当する個別設定ファイルのフルパス',
# db_info=DB_INFO,
# log_info='info',
# mode='i'
# )

View File

@ -0,0 +1,2 @@
boto3
PyMySQL

View File

@ -1,10 +1,6 @@
FROM python:3.12-slim-bookworm FROM python:3.9
ENV TZ="Asia/Tokyo" ENV TZ="Asia/Tokyo"
# pythonの標準出力をバッファリングしないフラグ
ENV PYTHONUNBUFFERED=1
# pythonのバイトコードを生成しないフラグ
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY Pipfile Pipfile.lock ./ COPY Pipfile Pipfile.lock ./
@ -16,7 +12,6 @@ RUN apt update && apt install -y less vim curl wget gzip unzip sudo lsb-release
# mysqlをインストール # mysqlをインストール
RUN \ RUN \
wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb && \ wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb && \
apt install -y gnupg && \
dpkg -i mysql-apt-config_0.8.29-1_all.deb < mysql_dpkg_selection.txt && \ dpkg -i mysql-apt-config_0.8.29-1_all.deb < mysql_dpkg_selection.txt && \
apt update && \ apt update && \
apt install -y mysql-client apt install -y mysql-client
@ -34,6 +29,11 @@ RUN \
pipenv install --system --deploy && \ pipenv install --system --deploy && \
pip uninstall -y pipenv virtualenv-clone virtualenv pip uninstall -y pipenv virtualenv-clone virtualenv
# パッケージのセキュリティアップデートのみを適用するコマンドを実行
RUN \
apt install -y unattended-upgrades && \
unattended-upgrades
COPY src ./src COPY src ./src
COPY entrypoint.py entrypoint.py COPY entrypoint.py entrypoint.py

View File

@ -10,7 +10,7 @@ autopep8 = "*"
flake8 = "*" flake8 = "*"
[requires] [requires]
python_version = "3.12" python_version = "3.9"
[pipenv] [pipenv]
allow_prereleases = true allow_prereleases = true

View File

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "2f7808325e11704ced6ad10c85e1d583663a03d7ccabaa9696ab1fe133a6b30c" "sha256": "cc5f54bfb2073051a26f113ceac64e12fdd0bf8faa36f1a42210cc9c921c134b"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.12" "python_version": "3.9"
}, },
"sources": [ "sources": [
{ {
@ -19,21 +19,19 @@
"develop": { "develop": {
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", "sha256:1fa8964e4618929488f4ec36795c7ff12924a68b8bf01366c094fc52f770b6e7",
"sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128" "sha256:2bb76888c5edbcafe6aabab3c47ba534f5a2c2d245c2eddced4a30c4b4946357"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==2.1.0"
"version": "==2.3.2"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:1cbc62e65536f65e6d754dfe6f1bada7f5cf392d6f5db3c2b85892466c3e7c1a", "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
"sha256:c586ffd0b41540951ae41af572e6790dbd49fc12b3aa2541685d253d9bd504bd" "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==7.0.0"
"version": "==7.1.2"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
@ -45,11 +43,11 @@
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.12.1" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@ -58,6 +56,14 @@
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==3.2.0" "version": "==3.2.0"
},
"tomli": {
"hashes": [
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
],
"markers": "python_version < '3.11'",
"version": "==2.0.1"
} }
} }
} }

View File

@ -18,20 +18,83 @@
"default": { "default": {
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:3faa2c328a61745f3215a63039606a6fcf55d9afe1cc76e3a5e27b9db58cdbf6", "sha256:7a02f44af32095946587d748ebeb39c3fa15b9d7275307ff612a6760ead47e04",
"sha256:b998edac72f6740bd5d9d585cf3880f2dfeb4842e626b34430fd0e9623378011" "sha256:91e6343474173e9b82f603076856e1d5b7b68f44247bdd556250857a3f16b37b"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==1.34.84"
"version": "==1.38.32"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:0899a090e352cb5eeaae2c7bb52a987b469d23912c7ece86664dfb5c2e074978", "sha256:a2b309bf5594f0eb6f63f355ade79ba575ce8bf672e52e91da1a7933caa245e6",
"sha256:64ab919a5d8b74dd73eaac1f978d0e674d11ff3bbe8815c3d2982477be9a082c" "sha256:da1ae0a912e69e10daee2a34dafd6c6c106450d20b8623665feceb2d96c173eb"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==1.38.32" "version": "==1.34.84"
},
"greenlet": {
"hashes": [
"sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67",
"sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6",
"sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257",
"sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4",
"sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676",
"sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61",
"sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc",
"sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca",
"sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7",
"sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728",
"sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305",
"sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6",
"sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379",
"sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414",
"sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04",
"sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a",
"sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf",
"sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491",
"sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559",
"sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e",
"sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274",
"sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb",
"sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b",
"sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9",
"sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b",
"sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be",
"sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506",
"sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405",
"sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113",
"sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f",
"sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5",
"sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230",
"sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d",
"sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f",
"sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a",
"sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e",
"sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61",
"sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6",
"sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d",
"sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71",
"sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22",
"sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2",
"sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3",
"sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067",
"sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc",
"sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881",
"sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3",
"sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e",
"sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac",
"sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53",
"sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0",
"sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b",
"sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83",
"sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41",
"sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c",
"sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf",
"sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
"sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
],
"markers": "platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
"version": "==3.0.3"
}, },
"jmespath": { "jmespath": {
"hashes": [ "hashes": [
@ -43,241 +106,217 @@
}, },
"pymysql": { "pymysql": {
"hashes": [ "hashes": [
"sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96",
"sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0" "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==1.1.0"
"version": "==1.1.1"
}, },
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.9.0.post0" "version": "==2.9.0.post0"
}, },
"s3transfer": { "s3transfer": {
"hashes": [ "hashes": [
"sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be", "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
"sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177" "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==0.13.0" "version": "==0.10.1"
}, },
"six": { "six": {
"hashes": [ "hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.17.0" "version": "==1.16.0"
}, },
"sqlalchemy": { "sqlalchemy": {
"hashes": [ "hashes": [
"sha256:023b3ee6169969beea3bb72312e44d8b7c27c75b347942d943cf49397b7edeb5", "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb",
"sha256:03968a349db483936c249f4d9cd14ff2c296adfa1290b660ba6516f973139582", "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c",
"sha256:05132c906066142103b83d9c250b60508af556982a385d96c4eaa9fb9720ac2b", "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d",
"sha256:087b6b52de812741c27231b5a3586384d60c353fbd0e2f81405a814b5591dc8b", "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a",
"sha256:0b3dbf1e7e9bc95f4bac5e2fb6d3fb2f083254c3fdd20a1789af965caf2d2348", "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003",
"sha256:118c16cd3f1b00c76d69343e38602006c9cfb9998fa4f798606d28d63f23beda", "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699",
"sha256:1936af879e3db023601196a1684d28e12f19ccf93af01bf3280a3262c4b6b4e5", "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e",
"sha256:1e3f196a0c59b0cae9a0cd332eb1a4bda4696e863f4f1cf84ab0347992c548c2", "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93",
"sha256:23a8825495d8b195c4aa9ff1c430c28f2c821e8c5e2d98089228af887e5d7e29", "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de",
"sha256:293cd444d82b18da48c9f71cd7005844dbbd06ca19be1ccf6779154439eec0b8", "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513",
"sha256:32f9dc8c44acdee06c8fc6440db9eae8b4af8b01e4b1aee7bdd7241c22edff4f", "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380",
"sha256:34ea30ab3ec98355235972dadc497bb659cc75f8292b760394824fab9cf39826", "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567",
"sha256:3d3549fc3e40667ec7199033a4e40a2f669898a00a7b18a931d3efb4c7900504", "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586",
"sha256:41836fe661cc98abfae476e14ba1906220f92c4e528771a8a3ae6a151242d2ae", "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b",
"sha256:4d44522480e0bf34c3d63167b8cfa7289c1c54264c2950cc5fc26e7850967e45", "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673",
"sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d",
"sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b",
"sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e",
"sha256:598d9ebc1e796431bbd068e41e4de4dc34312b7aa3292571bb3674a0cb415dd1", "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c",
"sha256:5b14e97886199c1f52c14629c11d90c11fbb09e9334fa7bb5f6d068d9ced0ce0", "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03",
"sha256:5e22575d169529ac3e0a120cf050ec9daa94b6a9597993d1702884f6954a7d71", "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e",
"sha256:60c578c45c949f909a4026b7807044e7e564adf793537fc762b2489d522f3d11", "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec",
"sha256:6145afea51ff0af7f2564a05fa95eb46f542919e6523729663a5d285ecb3cf5e", "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72",
"sha256:6375cd674fe82d7aa9816d1cb96ec592bac1726c11e0cafbf40eeee9a4516b5f", "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c",
"sha256:6854175807af57bdb6425e47adbce7d20a4d79bbfd6f6d6519cd10bb7109a7f8", "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41",
"sha256:6ab60a5089a8f02009f127806f777fca82581c49e127f08413a66056bd9166dd", "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0",
"sha256:725875a63abf7c399d4548e686debb65cdc2549e1825437096a0af1f7e374814", "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba",
"sha256:7492967c3386df69f80cf67efd665c0f667cee67032090fe01d7d74b0e19bb08", "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b",
"sha256:81965cc20848ab06583506ef54e37cf15c83c7e619df2ad16807c03100745dea", "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930",
"sha256:81c24e0c0fde47a9723c81d5806569cddef103aebbf79dbc9fcbb617153dea30", "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7",
"sha256:81eedafa609917040d39aa9332e25881a8e7a0862495fcdf2023a9667209deda", "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1",
"sha256:81f413674d85cfd0dfcd6512e10e0f33c19c21860342a4890c3a2b59479929f9", "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1",
"sha256:8280856dd7c6a68ab3a164b4a4b1c51f7691f6d04af4d4ca23d6ecf2261b7923", "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9",
"sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c",
"sha256:8b4af17bda11e907c51d10686eda89049f9ce5669b08fbe71a29747f1e876036", "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f",
"sha256:90144d3b0c8b139408da50196c5cad2a6909b51b23df1f0538411cd23ffa45d3", "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520",
"sha256:906e6b0d7d452e9a98e5ab8507c0da791856b2380fdee61b765632bb8698026f", "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b",
"sha256:90c11ceb9a1f482c752a71f203a81858625d8df5746d787a4786bca4ffdf71c6", "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0",
"sha256:911cc493ebd60de5f285bcae0491a60b4f2a9f0f5c270edd1c4dbaef7a38fc04", "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552",
"sha256:9a420a91913092d1e20c86a2f5f1fc85c1a8924dbcaf5e0586df8aceb09c9cc2", "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907",
"sha256:9f8c9fdd15a55d9465e590a402f42082705d66b05afc3ffd2d2eb3c6ba919560", "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e",
"sha256:a104c5694dfd2d864a6f91b0956eb5d5883234119cb40010115fd45a16da5e70", "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f",
"sha256:a373a400f3e9bac95ba2a06372c4fd1412a7cee53c37fc6c05f829bf672b8769", "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5",
"sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305",
"sha256:a8808d5cf866c781150d36a3c8eb3adccfa41a8105d031bf27e92c251e3969d6", "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01",
"sha256:b1f09b6821406ea1f94053f346f28f8215e293344209129a9c0fcc3578598d7b", "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44",
"sha256:b2ac41acfc8d965fb0c464eb8f44995770239668956dc4cdf502d1b1ffe0d747", "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd",
"sha256:b46fa6eae1cd1c20e6e6f44e19984d438b6b2d8616d21d783d150df714f44078", "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5",
"sha256:b50eab9994d64f4a823ff99a0ed28a6903224ddbe7fef56a6dd865eec9243440", "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"
"sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f",
"sha256:c0b0e5e1b5d9f3586601048dd68f392dc0cc99a59bb5faf18aab057ce00d00b2",
"sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d",
"sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc",
"sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a",
"sha256:dd5ec3aa6ae6e4d5b5de9357d2133c07be1aff6405b136dad753a16afb6717dd",
"sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9",
"sha256:ff8e80c4c4932c10493ff97028decfdb622de69cae87e0f127a7ebe32b4069c6"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==2.0.29"
"version": "==2.0.41"
}, },
"tenacity": { "tenacity": {
"hashes": [ "hashes": [
"sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a",
"sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138" "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==8.2.3"
"version": "==9.1.2"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
"sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af" "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==4.14.0" "version": "==4.11.0"
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07",
"sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32" "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "markers": "python_version < '3.10'",
"version": "==1.26.20" "version": "==1.26.18"
} }
}, },
"develop": { "develop": {
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda", "sha256:1fa8964e4618929488f4ec36795c7ff12924a68b8bf01366c094fc52f770b6e7",
"sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d" "sha256:2bb76888c5edbcafe6aabab3c47ba534f5a2c2d245c2eddced4a30c4b4946357"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "version": "==2.1.0"
"version": "==2.3.1"
}, },
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:9edf49640c79a05b0a72f4c2d1e24dfc164344b680535a645f455ac624dc3680", "sha256:7a02f44af32095946587d748ebeb39c3fa15b9d7275307ff612a6760ead47e04",
"sha256:db58348849a5af061f0f5ec9c3b699da5221ca83354059fdccb798e3ddb6b62a" "sha256:91e6343474173e9b82f603076856e1d5b7b68f44247bdd556250857a3f16b37b"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "version": "==1.34.84"
"version": "==1.35.57"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:92ddd02469213766872cb2399269dd20948f90348b42bf08379881d5e946cc34", "sha256:a2b309bf5594f0eb6f63f355ade79ba575ce8bf672e52e91da1a7933caa245e6",
"sha256:d96306558085baf0bcb3b022d7a8c39c93494f031edb376694d2b2dcd0e81327" "sha256:da1ae0a912e69e10daee2a34dafd6c6c106450d20b8623665feceb2d96c173eb"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==1.35.57" "version": "==1.34.84"
}, },
"coverage": { "coverage": {
"extras": [ "extras": [
"toml" "toml"
], ],
"hashes": [ "hashes": [
"sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c",
"sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63",
"sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7",
"sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f",
"sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8",
"sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf",
"sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0",
"sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384",
"sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76",
"sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7",
"sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d",
"sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70",
"sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f",
"sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818",
"sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b",
"sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d",
"sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec",
"sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083",
"sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2",
"sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9",
"sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd",
"sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade",
"sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e",
"sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a",
"sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227",
"sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87",
"sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c",
"sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e",
"sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c",
"sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e",
"sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd",
"sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec",
"sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562",
"sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8",
"sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677",
"sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357",
"sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c",
"sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd",
"sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49",
"sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286",
"sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1",
"sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf",
"sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51",
"sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409",
"sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384",
"sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e",
"sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978",
"sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57",
"sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e",
"sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2",
"sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48",
"sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4"
"sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a",
"sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef",
"sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b",
"sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b",
"sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f",
"sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806",
"sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b",
"sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1",
"sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c",
"sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==7.6.4" "version": "==7.4.4"
}, },
"exceptiongroup": { "exceptiongroup": {
"hashes": [ "hashes": [
"sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14",
"sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"
], ],
"markers": "python_version < '3.11'", "markers": "python_version < '3.11'",
"version": "==1.2.2" "version": "==1.2.0"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38", "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
"sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213" "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==7.0.0"
"version": "==7.1.1"
}, },
"iniconfig": { "iniconfig": {
"hashes": [ "hashes": [
@ -305,27 +344,27 @@
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
"sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.7'",
"version": "==24.2" "version": "==24.0"
}, },
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
"sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981",
"sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==1.5.0" "version": "==1.4.0"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.12.1" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@ -337,21 +376,19 @@
}, },
"pytest": { "pytest": {
"hashes": [ "hashes": [
"sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7",
"sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2" "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "version": "==8.1.1"
"version": "==8.3.3"
}, },
"pytest-cov": { "pytest-cov": {
"hashes": [ "hashes": [
"sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652",
"sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0" "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==5.0.0"
"version": "==6.0.0"
}, },
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
@ -363,11 +400,11 @@
}, },
"s3transfer": { "s3transfer": {
"hashes": [ "hashes": [
"sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d", "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
"sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c" "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==0.10.3" "version": "==0.10.1"
}, },
"six": { "six": {
"hashes": [ "hashes": [
@ -379,19 +416,19 @@
}, },
"tomli": { "tomli": {
"hashes": [ "hashes": [
"sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed" "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
], ],
"markers": "python_version < '3.11'", "markers": "python_version < '3.11'",
"version": "==2.0.2" "version": "==2.0.1"
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07",
"sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32" "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"
], ],
"markers": "python_version < '3.10'", "markers": "python_version < '3.10'",
"version": "==1.26.20" "version": "==1.26.18"
} }
} }
} }

View File

@ -20,8 +20,8 @@ def exec():
db = Database.get_instance() db = Database.get_instance()
try: try:
db.connect() db.connect()
db.begin()
db.to_jst() db.to_jst()
db.begin()
logger.debug('DCF施設統合マスタ作成処理開始') logger.debug('DCF施設統合マスタ作成処理開始')
# COM施設からDCF施設統合マスタに登録 # COM施設からDCF施設統合マスタに登録
(is_add_dcf_inst_merge, duplication_inst_records) = _insert_dcf_inst_merge_from_com_inst(db) (is_add_dcf_inst_merge, duplication_inst_records) = _insert_dcf_inst_merge_from_com_inst(db)

View File

@ -1,5 +1,4 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from src.batch.batch_functions import logging_sql from src.batch.batch_functions import logging_sql
from src.batch.common.batch_context import BatchContext from src.batch.common.batch_context import BatchContext
from src.db.database import Database from src.db.database import Database
@ -15,8 +14,8 @@ def exec():
db = Database.get_instance() db = Database.get_instance()
try: try:
db.connect() db.connect()
db.begin()
db.to_jst() db.to_jst()
db.begin()
logger.debug('DCF施設統合マスタ日次更新処理開始') logger.debug('DCF施設統合マスタ日次更新処理開始')
# DCF施設統合マスタ移行先コードのセット(無効フラグが『0(有効)』) # DCF施設統合マスタ移行先コードのセット(無効フラグが『0(有効)』)
enabled_dst_inst_merge_records = _set_enabled_dct_inst_merge(db) enabled_dst_inst_merge_records = _set_enabled_dct_inst_merge(db)
@ -121,13 +120,12 @@ def _add_ult_ident_presc(db: Database, enabled_dst_inst_merge_records: list[dict
logger.info('納入先処方元マスタの登録 終了') logger.info('納入先処方元マスタの登録 終了')
def _select_primary_key_from_emp_chg_inst(db: Database, dcf_inst_cd: str) -> list[dict]: def _select_emp_chg_inst_ta_cd(db: Database, dcf_inst_cd: str) -> list[dict]:
# 従業員担当施設マスタから、DCF施設コードに対応した領域コードと担当者種別コードの取得 # 従業員担当施設マスタから、DCF施設コードに対応した領域コードの取得
try: try:
sql = """ sql = """
SELECT SELECT
ta_cd, ta_cd
emp_chg_type_cd
FROM FROM
src05.emp_chg_inst src05.emp_chg_inst
WHERE WHERE
@ -136,14 +134,14 @@ def _select_primary_key_from_emp_chg_inst(db: Database, dcf_inst_cd: str) -> lis
AND (SELECT ht.syor_date FROM src05.hdke_tbl AS ht) < end_date AND (SELECT ht.syor_date FROM src05.hdke_tbl AS ht) < end_date
""" """
params = {'dcf_inst_cd': dcf_inst_cd} params = {'dcf_inst_cd': dcf_inst_cd}
emp_chg_inst_primary_key_records = db.execute_select(sql, params) emp_chg_inst_ta_cd_records = db.execute_select(sql, params)
logging_sql(logger, sql) logging_sql(logger, sql)
logger.info('従業員担当施設マスタから領域コード、担当者種別コードの取得に成功') logger.info('従業員担当施設マスタから領域コードの取得に成功')
except Exception as e: except Exception as e:
logger.debug('従業員担当施設マスタから領域コード、担当者種別コードの取得に失敗') logger.debug('従業員担当施設マスタから領域コードの取得に失敗')
raise e raise e
return emp_chg_inst_primary_key_records return emp_chg_inst_ta_cd_records
def _add_emp_chg_inst(db: Database, enabled_dst_inst_merge_records: list[dict]): def _add_emp_chg_inst(db: Database, enabled_dst_inst_merge_records: list[dict]):
@ -151,10 +149,10 @@ def _add_emp_chg_inst(db: Database, enabled_dst_inst_merge_records: list[dict]):
logger.info('従業員担当施設マスタの登録 開始') logger.info('従業員担当施設マスタの登録 開始')
for enabled_merge_record in enabled_dst_inst_merge_records: for enabled_merge_record in enabled_dst_inst_merge_records:
tekiyo_month_first_day = _get_first_day_of_month(enabled_merge_record['tekiyo_month']) tekiyo_month_first_day = _get_first_day_of_month(enabled_merge_record['tekiyo_month'])
emp_chg_inst_primary_key_records = _select_primary_key_from_emp_chg_inst(db, enabled_merge_record['dcf_inst_cd']) emp_chg_inst_ta_cd_records = _select_emp_chg_inst_ta_cd(db, enabled_merge_record['dcf_inst_cd'])
for emp_chg_inst_primary_key_record in emp_chg_inst_primary_key_records: for emp_chg_inst_ta_cd_record in emp_chg_inst_ta_cd_records:
emp_chg_inst_records = _select_emp_chg_inst(db, enabled_merge_record['dcf_inst_cd'], enabled_merge_record['dup_opp_cd'], emp_chg_inst_records = _select_emp_chg_inst(db, enabled_merge_record['dcf_inst_cd'], enabled_merge_record['dup_opp_cd'],
emp_chg_inst_primary_key_record['ta_cd'], emp_chg_inst_primary_key_record['emp_chg_type_cd']) emp_chg_inst_ta_cd_record['ta_cd'])
for emp_chg_inst_row in emp_chg_inst_records: for emp_chg_inst_row in emp_chg_inst_records:
# 重複時相手先コードが存在したかのチェック # 重複時相手先コードが存在したかのチェック
if emp_chg_inst_row['opp_count'] > 0: if emp_chg_inst_row['opp_count'] > 0:
@ -175,7 +173,7 @@ def _add_emp_chg_inst(db: Database, enabled_dst_inst_merge_records: list[dict]):
emp_chg_inst_row) emp_chg_inst_row)
continue continue
# 適用開始日 ≧ DCF施設統合マスタの適用月度の1日の場合、N(論理削除レコード)に設定する # 適用開始日 ≧ DCF施設統合マスタの適用月度の1日の場合、N(論理削除レコード)に設定する
_update_emp_chg_inst_disabled(db, enabled_merge_record['dcf_inst_cd'], emp_chg_inst_row['ta_cd'], emp_chg_inst_row['emp_chg_type_cd'], _update_emp_chg_inst_disabled(db, enabled_merge_record['dcf_inst_cd'], emp_chg_inst_row['ta_cd'],
emp_chg_inst_row['start_date']) emp_chg_inst_row['start_date'])
logger.info('従業員担当施設マスタの登録 終了') logger.info('従業員担当施設マスタの登録 終了')
@ -209,7 +207,7 @@ def _delete_ult_ident_presc(db: Database, start_date: str, ult_ident_presc_row:
raise e raise e
def _update_emp_chg_inst_disabled(db: Database, dcf_inst_cd: str, ta_cd: str, emp_chg_type_cd: str, start_date: str): def _update_emp_chg_inst_disabled(db: Database, dcf_inst_cd: str, ta_cd: str, start_date: str):
# emp_chg_instをUPDATE # emp_chg_instをUPDATE
try: try:
elapsed_time = ElapsedTime() elapsed_time = ElapsedTime()
@ -223,10 +221,9 @@ def _update_emp_chg_inst_disabled(db: Database, dcf_inst_cd: str, ta_cd: str, em
WHERE WHERE
inst_cd = :dcf_inst_cd inst_cd = :dcf_inst_cd
AND ta_cd = :ta_cd AND ta_cd = :ta_cd
AND emp_chg_type_cd = :emp_chg_type_cd
AND start_date = :start_date AND start_date = :start_date
""" """
params = {'dcf_inst_cd': dcf_inst_cd, 'ta_cd': ta_cd, 'emp_chg_type_cd': emp_chg_type_cd, 'start_date': start_date} params = {'dcf_inst_cd': dcf_inst_cd, 'ta_cd': ta_cd, 'start_date': start_date}
res = db.execute(sql, params) res = db.execute(sql, params)
logging_sql(logger, sql) logging_sql(logger, sql)
logger.info(f'従業員担当施設マスタのYorNフラグ更新に成功, {res.rowcount} 行更新 ({elapsed_time.of})') logger.info(f'従業員担当施設マスタのYorNフラグ更新に成功, {res.rowcount} 行更新 ({elapsed_time.of})')
@ -249,7 +246,6 @@ def _update_emp_chg_inst_end_date(db: Database, dcf_inst_cd: str, last_end_date:
WHERE WHERE
inst_cd = :dcf_inst_cd inst_cd = :dcf_inst_cd
AND ta_cd = :ta_cd AND ta_cd = :ta_cd
AND emp_chg_type_cd = :emp_chg_type_cd
AND emp_cd = :emp_cd AND emp_cd = :emp_cd
AND bu_cd = :bu_cd AND bu_cd = :bu_cd
AND start_date = :start_date AND start_date = :start_date
@ -258,7 +254,6 @@ def _update_emp_chg_inst_end_date(db: Database, dcf_inst_cd: str, last_end_date:
'end_date': last_end_date, 'end_date': last_end_date,
'dcf_inst_cd': dcf_inst_cd, 'dcf_inst_cd': dcf_inst_cd,
'ta_cd': emp_chg_inst_row['ta_cd'], 'ta_cd': emp_chg_inst_row['ta_cd'],
'emp_chg_type_cd': emp_chg_inst_row['emp_chg_type_cd'],
'emp_cd': emp_chg_inst_row['emp_cd'], 'emp_cd': emp_chg_inst_row['emp_cd'],
'bu_cd': emp_chg_inst_row['bu_cd'], 'bu_cd': emp_chg_inst_row['bu_cd'],
'start_date': emp_chg_inst_row['start_date'] 'start_date': emp_chg_inst_row['start_date']
@ -281,7 +276,6 @@ def _insert_emp_chg_inst(db: Database, dup_opp_cd: str, set_start_date: str,
src05.emp_chg_inst( src05.emp_chg_inst(
inst_cd, inst_cd,
ta_cd, ta_cd,
emp_chg_type_cd,
emp_cd, emp_cd,
bu_cd, bu_cd,
start_date, start_date,
@ -296,7 +290,6 @@ def _insert_emp_chg_inst(db: Database, dup_opp_cd: str, set_start_date: str,
VALUES( VALUES(
:dup_opp_cd, :dup_opp_cd,
:ta_cd, :ta_cd,
:emp_chg_type_cd,
:emp_cd, :emp_cd,
:bu_cd, :bu_cd,
:start_date, :start_date,
@ -312,7 +305,6 @@ def _insert_emp_chg_inst(db: Database, dup_opp_cd: str, set_start_date: str,
params = { params = {
'dup_opp_cd': dup_opp_cd, 'dup_opp_cd': dup_opp_cd,
'ta_cd': emp_chg_inst_row['ta_cd'], 'ta_cd': emp_chg_inst_row['ta_cd'],
'emp_chg_type_cd': emp_chg_inst_row['emp_chg_type_cd'],
'emp_cd': emp_chg_inst_row['emp_cd'], 'emp_cd': emp_chg_inst_row['emp_cd'],
'bu_cd': emp_chg_inst_row['bu_cd'], 'bu_cd': emp_chg_inst_row['bu_cd'],
'start_date': set_start_date, 'start_date': set_start_date,
@ -526,14 +518,13 @@ def _insert_ult_ident_presc(db: Database, set_Start_Date: str, dup_opp_cd: str,
raise e raise e
def _select_emp_chg_inst(db: Database, dcf_inst_cd: str, dup_opp_cd: str, ta_cd: str, emp_chg_type_cd: str) -> list[dict]: def _select_emp_chg_inst(db: Database, dcf_inst_cd: str, dup_opp_cd: str, ta_cd: str) -> list[dict]:
# emp_chg_instからSELECT # emp_chg_instからSELECT
try: try:
sql = """ sql = """
SELECT SELECT
eci.inst_cd, eci.inst_cd,
eci.ta_cd, eci.ta_cd,
eci.emp_chg_type_cd,
eci.emp_cd, eci.emp_cd,
eci.bu_cd, eci.bu_cd,
eci.start_date, eci.start_date,
@ -548,18 +539,16 @@ def _select_emp_chg_inst(db: Database, dcf_inst_cd: str, dup_opp_cd: str, ta_cd:
WHERE WHERE
eciopp.inst_cd = :dup_opp_cd eciopp.inst_cd = :dup_opp_cd
AND eciopp.ta_cd = :ta_cd AND eciopp.ta_cd = :ta_cd
AND eciopp.emp_chg_type_cd = :emp_chg_type_cd
) AS opp_count ) AS opp_count
FROM FROM
src05.emp_chg_inst AS eci src05.emp_chg_inst AS eci
WHERE WHERE
eci.inst_cd = :dcf_inst_cd eci.inst_cd = :dcf_inst_cd
AND eci.ta_cd = :ta_cd AND eci.ta_cd = :ta_cd
AND eci.emp_chg_type_cd = :emp_chg_type_cd
AND eci.enabled_flg = 'Y' AND eci.enabled_flg = 'Y'
AND (SELECT ht.syor_date FROM src05.hdke_tbl AS ht) < eci.end_date AND (SELECT ht.syor_date FROM src05.hdke_tbl AS ht) < eci.end_date
""" """
params = {'dcf_inst_cd': dcf_inst_cd, 'dup_opp_cd': dup_opp_cd, 'ta_cd': ta_cd, 'emp_chg_type_cd': emp_chg_type_cd} params = {'dcf_inst_cd': dcf_inst_cd, 'dup_opp_cd': dup_opp_cd, 'ta_cd': ta_cd}
emp_chg_inst_records = db.execute_select(sql, params) emp_chg_inst_records = db.execute_select(sql, params)
logging_sql(logger, sql) logging_sql(logger, sql)
logger.info('従業員担当施設マスタの取得 成功') logger.info('従業員担当施設マスタの取得 成功')

View File

@ -53,9 +53,7 @@ def _insert_into_emp_chg_inst_lau_from_emp_chg_inst(db: Database):
src05.emp_chg_inst_lau src05.emp_chg_inst_lau
SELECT SELECT
inst_cd, inst_cd,
ta_cd, ta_cd,emp_cd,
emp_chg_type_cd,
emp_cd,
bu_cd, bu_cd,
start_date, start_date,
end_date, end_date,

View File

@ -1,9 +1,8 @@
from src.batch.common.batch_context import BatchContext from src.batch.common.batch_context import BatchContext
from src.batch.laundering import (
create_inst_merge_for_laundering, emp_chg_inst_laundering,
ult_ident_presc_laundering, sales_results_laundering)
from src.batch.dcf_inst_merge import integrate_dcf_inst_merge from src.batch.dcf_inst_merge import integrate_dcf_inst_merge
from src.batch.laundering import (create_inst_merge_for_laundering,
emp_chg_inst_laundering,
sales_results_laundering,
ult_ident_presc_laundering)
from src.logging.get_logger import get_logger from src.logging.get_logger import get_logger
batch_context = BatchContext.get_instance() batch_context = BatchContext.get_instance()

View File

@ -16,115 +16,166 @@
] ]
}, },
"default": { "default": {
"greenlet": {
"hashes": [
"sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67",
"sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6",
"sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257",
"sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4",
"sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676",
"sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61",
"sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc",
"sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca",
"sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7",
"sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728",
"sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305",
"sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6",
"sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379",
"sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414",
"sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04",
"sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a",
"sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf",
"sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491",
"sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559",
"sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e",
"sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274",
"sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb",
"sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b",
"sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9",
"sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b",
"sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be",
"sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506",
"sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405",
"sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113",
"sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f",
"sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5",
"sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230",
"sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d",
"sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f",
"sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a",
"sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e",
"sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61",
"sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6",
"sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d",
"sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71",
"sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22",
"sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2",
"sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3",
"sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067",
"sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc",
"sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881",
"sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3",
"sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e",
"sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac",
"sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53",
"sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0",
"sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b",
"sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83",
"sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41",
"sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c",
"sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf",
"sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
"sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
],
"markers": "platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
"version": "==3.0.3"
},
"pymysql": { "pymysql": {
"hashes": [ "hashes": [
"sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96",
"sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0" "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==1.1.0"
"version": "==1.1.1"
}, },
"sqlalchemy": { "sqlalchemy": {
"hashes": [ "hashes": [
"sha256:023b3ee6169969beea3bb72312e44d8b7c27c75b347942d943cf49397b7edeb5", "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb",
"sha256:03968a349db483936c249f4d9cd14ff2c296adfa1290b660ba6516f973139582", "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c",
"sha256:05132c906066142103b83d9c250b60508af556982a385d96c4eaa9fb9720ac2b", "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d",
"sha256:087b6b52de812741c27231b5a3586384d60c353fbd0e2f81405a814b5591dc8b", "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a",
"sha256:0b3dbf1e7e9bc95f4bac5e2fb6d3fb2f083254c3fdd20a1789af965caf2d2348", "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003",
"sha256:118c16cd3f1b00c76d69343e38602006c9cfb9998fa4f798606d28d63f23beda", "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699",
"sha256:1936af879e3db023601196a1684d28e12f19ccf93af01bf3280a3262c4b6b4e5", "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e",
"sha256:1e3f196a0c59b0cae9a0cd332eb1a4bda4696e863f4f1cf84ab0347992c548c2", "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93",
"sha256:23a8825495d8b195c4aa9ff1c430c28f2c821e8c5e2d98089228af887e5d7e29", "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de",
"sha256:293cd444d82b18da48c9f71cd7005844dbbd06ca19be1ccf6779154439eec0b8", "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513",
"sha256:32f9dc8c44acdee06c8fc6440db9eae8b4af8b01e4b1aee7bdd7241c22edff4f", "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380",
"sha256:34ea30ab3ec98355235972dadc497bb659cc75f8292b760394824fab9cf39826", "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567",
"sha256:3d3549fc3e40667ec7199033a4e40a2f669898a00a7b18a931d3efb4c7900504", "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586",
"sha256:41836fe661cc98abfae476e14ba1906220f92c4e528771a8a3ae6a151242d2ae", "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b",
"sha256:4d44522480e0bf34c3d63167b8cfa7289c1c54264c2950cc5fc26e7850967e45", "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673",
"sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d",
"sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b",
"sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e",
"sha256:598d9ebc1e796431bbd068e41e4de4dc34312b7aa3292571bb3674a0cb415dd1", "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c",
"sha256:5b14e97886199c1f52c14629c11d90c11fbb09e9334fa7bb5f6d068d9ced0ce0", "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03",
"sha256:5e22575d169529ac3e0a120cf050ec9daa94b6a9597993d1702884f6954a7d71", "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e",
"sha256:60c578c45c949f909a4026b7807044e7e564adf793537fc762b2489d522f3d11", "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec",
"sha256:6145afea51ff0af7f2564a05fa95eb46f542919e6523729663a5d285ecb3cf5e", "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72",
"sha256:6375cd674fe82d7aa9816d1cb96ec592bac1726c11e0cafbf40eeee9a4516b5f", "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c",
"sha256:6854175807af57bdb6425e47adbce7d20a4d79bbfd6f6d6519cd10bb7109a7f8", "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41",
"sha256:6ab60a5089a8f02009f127806f777fca82581c49e127f08413a66056bd9166dd", "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0",
"sha256:725875a63abf7c399d4548e686debb65cdc2549e1825437096a0af1f7e374814", "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba",
"sha256:7492967c3386df69f80cf67efd665c0f667cee67032090fe01d7d74b0e19bb08", "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b",
"sha256:81965cc20848ab06583506ef54e37cf15c83c7e619df2ad16807c03100745dea", "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930",
"sha256:81c24e0c0fde47a9723c81d5806569cddef103aebbf79dbc9fcbb617153dea30", "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7",
"sha256:81eedafa609917040d39aa9332e25881a8e7a0862495fcdf2023a9667209deda", "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1",
"sha256:81f413674d85cfd0dfcd6512e10e0f33c19c21860342a4890c3a2b59479929f9", "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1",
"sha256:8280856dd7c6a68ab3a164b4a4b1c51f7691f6d04af4d4ca23d6ecf2261b7923", "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9",
"sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c",
"sha256:8b4af17bda11e907c51d10686eda89049f9ce5669b08fbe71a29747f1e876036", "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f",
"sha256:90144d3b0c8b139408da50196c5cad2a6909b51b23df1f0538411cd23ffa45d3", "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520",
"sha256:906e6b0d7d452e9a98e5ab8507c0da791856b2380fdee61b765632bb8698026f", "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b",
"sha256:90c11ceb9a1f482c752a71f203a81858625d8df5746d787a4786bca4ffdf71c6", "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0",
"sha256:911cc493ebd60de5f285bcae0491a60b4f2a9f0f5c270edd1c4dbaef7a38fc04", "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552",
"sha256:9a420a91913092d1e20c86a2f5f1fc85c1a8924dbcaf5e0586df8aceb09c9cc2", "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907",
"sha256:9f8c9fdd15a55d9465e590a402f42082705d66b05afc3ffd2d2eb3c6ba919560", "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e",
"sha256:a104c5694dfd2d864a6f91b0956eb5d5883234119cb40010115fd45a16da5e70", "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f",
"sha256:a373a400f3e9bac95ba2a06372c4fd1412a7cee53c37fc6c05f829bf672b8769", "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5",
"sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305",
"sha256:a8808d5cf866c781150d36a3c8eb3adccfa41a8105d031bf27e92c251e3969d6", "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01",
"sha256:b1f09b6821406ea1f94053f346f28f8215e293344209129a9c0fcc3578598d7b", "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44",
"sha256:b2ac41acfc8d965fb0c464eb8f44995770239668956dc4cdf502d1b1ffe0d747", "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd",
"sha256:b46fa6eae1cd1c20e6e6f44e19984d438b6b2d8616d21d783d150df714f44078", "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5",
"sha256:b50eab9994d64f4a823ff99a0ed28a6903224ddbe7fef56a6dd865eec9243440", "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"
"sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f",
"sha256:c0b0e5e1b5d9f3586601048dd68f392dc0cc99a59bb5faf18aab057ce00d00b2",
"sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d",
"sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc",
"sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a",
"sha256:dd5ec3aa6ae6e4d5b5de9357d2133c07be1aff6405b136dad753a16afb6717dd",
"sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9",
"sha256:ff8e80c4c4932c10493ff97028decfdb622de69cae87e0f127a7ebe32b4069c6"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==2.0.29"
"version": "==2.0.41"
}, },
"tenacity": { "tenacity": {
"hashes": [ "hashes": [
"sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a",
"sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138" "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==8.2.3"
"version": "==9.1.2"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
"sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af" "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==4.14.0" "version": "==4.11.0"
} }
}, },
"develop": { "develop": {
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda", "sha256:1fa8964e4618929488f4ec36795c7ff12924a68b8bf01366c094fc52f770b6e7",
"sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d" "sha256:2bb76888c5edbcafe6aabab3c47ba534f5a2c2d245c2eddced4a30c4b4946357"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "version": "==2.1.0"
"version": "==2.3.1"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38", "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
"sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213" "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==7.0.0"
"version": "==7.1.1"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
@ -136,11 +187,11 @@
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.12.1" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@ -152,11 +203,11 @@
}, },
"tomli": { "tomli": {
"hashes": [ "hashes": [
"sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed" "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
], ],
"markers": "python_version < '3.11'", "markers": "python_version < '3.11'",
"version": "==2.0.2" "version": "==2.0.1"
} }
} }
} }

View File

@ -16,115 +16,166 @@
] ]
}, },
"default": { "default": {
"greenlet": {
"hashes": [
"sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67",
"sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6",
"sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257",
"sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4",
"sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676",
"sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61",
"sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc",
"sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca",
"sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7",
"sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728",
"sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305",
"sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6",
"sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379",
"sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414",
"sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04",
"sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a",
"sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf",
"sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491",
"sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559",
"sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e",
"sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274",
"sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb",
"sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b",
"sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9",
"sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b",
"sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be",
"sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506",
"sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405",
"sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113",
"sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f",
"sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5",
"sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230",
"sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d",
"sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f",
"sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a",
"sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e",
"sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61",
"sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6",
"sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d",
"sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71",
"sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22",
"sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2",
"sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3",
"sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067",
"sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc",
"sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881",
"sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3",
"sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e",
"sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac",
"sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53",
"sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0",
"sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b",
"sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83",
"sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41",
"sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c",
"sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf",
"sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
"sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
],
"markers": "platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
"version": "==3.0.3"
},
"pymysql": { "pymysql": {
"hashes": [ "hashes": [
"sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96",
"sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0" "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==1.1.0"
"version": "==1.1.1"
}, },
"sqlalchemy": { "sqlalchemy": {
"hashes": [ "hashes": [
"sha256:023b3ee6169969beea3bb72312e44d8b7c27c75b347942d943cf49397b7edeb5", "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb",
"sha256:03968a349db483936c249f4d9cd14ff2c296adfa1290b660ba6516f973139582", "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c",
"sha256:05132c906066142103b83d9c250b60508af556982a385d96c4eaa9fb9720ac2b", "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d",
"sha256:087b6b52de812741c27231b5a3586384d60c353fbd0e2f81405a814b5591dc8b", "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a",
"sha256:0b3dbf1e7e9bc95f4bac5e2fb6d3fb2f083254c3fdd20a1789af965caf2d2348", "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003",
"sha256:118c16cd3f1b00c76d69343e38602006c9cfb9998fa4f798606d28d63f23beda", "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699",
"sha256:1936af879e3db023601196a1684d28e12f19ccf93af01bf3280a3262c4b6b4e5", "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e",
"sha256:1e3f196a0c59b0cae9a0cd332eb1a4bda4696e863f4f1cf84ab0347992c548c2", "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93",
"sha256:23a8825495d8b195c4aa9ff1c430c28f2c821e8c5e2d98089228af887e5d7e29", "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de",
"sha256:293cd444d82b18da48c9f71cd7005844dbbd06ca19be1ccf6779154439eec0b8", "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513",
"sha256:32f9dc8c44acdee06c8fc6440db9eae8b4af8b01e4b1aee7bdd7241c22edff4f", "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380",
"sha256:34ea30ab3ec98355235972dadc497bb659cc75f8292b760394824fab9cf39826", "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567",
"sha256:3d3549fc3e40667ec7199033a4e40a2f669898a00a7b18a931d3efb4c7900504", "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586",
"sha256:41836fe661cc98abfae476e14ba1906220f92c4e528771a8a3ae6a151242d2ae", "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b",
"sha256:4d44522480e0bf34c3d63167b8cfa7289c1c54264c2950cc5fc26e7850967e45", "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673",
"sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d",
"sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b",
"sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e",
"sha256:598d9ebc1e796431bbd068e41e4de4dc34312b7aa3292571bb3674a0cb415dd1", "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c",
"sha256:5b14e97886199c1f52c14629c11d90c11fbb09e9334fa7bb5f6d068d9ced0ce0", "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03",
"sha256:5e22575d169529ac3e0a120cf050ec9daa94b6a9597993d1702884f6954a7d71", "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e",
"sha256:60c578c45c949f909a4026b7807044e7e564adf793537fc762b2489d522f3d11", "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec",
"sha256:6145afea51ff0af7f2564a05fa95eb46f542919e6523729663a5d285ecb3cf5e", "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72",
"sha256:6375cd674fe82d7aa9816d1cb96ec592bac1726c11e0cafbf40eeee9a4516b5f", "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c",
"sha256:6854175807af57bdb6425e47adbce7d20a4d79bbfd6f6d6519cd10bb7109a7f8", "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41",
"sha256:6ab60a5089a8f02009f127806f777fca82581c49e127f08413a66056bd9166dd", "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0",
"sha256:725875a63abf7c399d4548e686debb65cdc2549e1825437096a0af1f7e374814", "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba",
"sha256:7492967c3386df69f80cf67efd665c0f667cee67032090fe01d7d74b0e19bb08", "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b",
"sha256:81965cc20848ab06583506ef54e37cf15c83c7e619df2ad16807c03100745dea", "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930",
"sha256:81c24e0c0fde47a9723c81d5806569cddef103aebbf79dbc9fcbb617153dea30", "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7",
"sha256:81eedafa609917040d39aa9332e25881a8e7a0862495fcdf2023a9667209deda", "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1",
"sha256:81f413674d85cfd0dfcd6512e10e0f33c19c21860342a4890c3a2b59479929f9", "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1",
"sha256:8280856dd7c6a68ab3a164b4a4b1c51f7691f6d04af4d4ca23d6ecf2261b7923", "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9",
"sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c",
"sha256:8b4af17bda11e907c51d10686eda89049f9ce5669b08fbe71a29747f1e876036", "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f",
"sha256:90144d3b0c8b139408da50196c5cad2a6909b51b23df1f0538411cd23ffa45d3", "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520",
"sha256:906e6b0d7d452e9a98e5ab8507c0da791856b2380fdee61b765632bb8698026f", "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b",
"sha256:90c11ceb9a1f482c752a71f203a81858625d8df5746d787a4786bca4ffdf71c6", "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0",
"sha256:911cc493ebd60de5f285bcae0491a60b4f2a9f0f5c270edd1c4dbaef7a38fc04", "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552",
"sha256:9a420a91913092d1e20c86a2f5f1fc85c1a8924dbcaf5e0586df8aceb09c9cc2", "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907",
"sha256:9f8c9fdd15a55d9465e590a402f42082705d66b05afc3ffd2d2eb3c6ba919560", "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e",
"sha256:a104c5694dfd2d864a6f91b0956eb5d5883234119cb40010115fd45a16da5e70", "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f",
"sha256:a373a400f3e9bac95ba2a06372c4fd1412a7cee53c37fc6c05f829bf672b8769", "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5",
"sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305",
"sha256:a8808d5cf866c781150d36a3c8eb3adccfa41a8105d031bf27e92c251e3969d6", "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01",
"sha256:b1f09b6821406ea1f94053f346f28f8215e293344209129a9c0fcc3578598d7b", "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44",
"sha256:b2ac41acfc8d965fb0c464eb8f44995770239668956dc4cdf502d1b1ffe0d747", "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd",
"sha256:b46fa6eae1cd1c20e6e6f44e19984d438b6b2d8616d21d783d150df714f44078", "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5",
"sha256:b50eab9994d64f4a823ff99a0ed28a6903224ddbe7fef56a6dd865eec9243440", "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"
"sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f",
"sha256:c0b0e5e1b5d9f3586601048dd68f392dc0cc99a59bb5faf18aab057ce00d00b2",
"sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d",
"sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc",
"sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a",
"sha256:dd5ec3aa6ae6e4d5b5de9357d2133c07be1aff6405b136dad753a16afb6717dd",
"sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9",
"sha256:ff8e80c4c4932c10493ff97028decfdb622de69cae87e0f127a7ebe32b4069c6"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==2.0.29"
"version": "==2.0.41"
}, },
"tenacity": { "tenacity": {
"hashes": [ "hashes": [
"sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a",
"sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138" "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==8.2.3"
"version": "==9.1.2"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
"sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af" "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==4.14.0" "version": "==4.11.0"
} }
}, },
"develop": { "develop": {
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda", "sha256:1fa8964e4618929488f4ec36795c7ff12924a68b8bf01366c094fc52f770b6e7",
"sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d" "sha256:2bb76888c5edbcafe6aabab3c47ba534f5a2c2d245c2eddced4a30c4b4946357"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "version": "==2.1.0"
"version": "==2.3.1"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38", "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
"sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213" "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==7.0.0"
"version": "==7.1.1"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
@ -136,11 +187,11 @@
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.12.1" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@ -152,11 +203,11 @@
}, },
"tomli": { "tomli": {
"hashes": [ "hashes": [
"sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed" "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
], ],
"markers": "python_version < '3.11'", "markers": "python_version < '3.11'",
"version": "==2.0.2" "version": "==2.0.1"
} }
} }
} }

View File

@ -26,7 +26,6 @@ openpyxl = "*"
xlrd = "*" xlrd = "*"
sqlalchemy = "==2.*" sqlalchemy = "==2.*"
mojimoji = "*" mojimoji = "*"
numpy = "==2.0.*"
[dev-packages] [dev-packages]
autopep8 = "*" autopep8 = "*"

File diff suppressed because it is too large Load Diff

View File

@ -70,22 +70,11 @@ def login(
jwt_token = login_service.login(request.username, request.password) jwt_token = login_service.login(request.username, request.password)
except NotAuthorizeException as e: except NotAuthorizeException as e:
logger.info(f'ログイン失敗:{e}') logger.info(f'ログイン失敗:{e}')
# ログイン失敗回数をカウント
login_service.increase_login_failed_count(request.username)
# ログイン失敗回数を超過した場合はメッセージを変える
if login_service.is_login_failed_limit_exceeded(request.username):
login_service.on_login_fail_limit_exceeded(request.username)
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED)
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_ERROR) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_ERROR)
except JWTTokenVerifyException as e: except JWTTokenVerifyException as e:
logger.info(f'ログイン失敗:{e}') logger.info(f'ログイン失敗:{e}')
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
# ログイン成功問わず、DBのログイン失敗回数が10回以上あれば、ログアウト画面にリダイレクトする
if login_service.is_login_failed_limit_exceeded(request.username):
logger.info(f'ログイン失敗回数が10回以上: {request.username}')
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=constants.LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED)
verified_token = jwt_token.verify_token() verified_token = jwt_token.verify_token()
# 普通の認証だと、`cognito:username`に入る。 # 普通の認証だと、`cognito:username`に入る。
user_id = verified_token.user_id user_id = verified_token.user_id

View File

@ -199,7 +199,7 @@ def new_inst_result_view(
return templates_response return templates_response
@router.get('/instEmpCsvDL', response_class=HTMLResponse) @ router.get('/instEmpCsvDL', response_class=HTMLResponse)
def inst_emp_csv_download_view( def inst_emp_csv_download_view(
request: Request, request: Request,
batch_status_service: BatchStatusService = Depends(get_service(BatchStatusService)) batch_status_service: BatchStatusService = Depends(get_service(BatchStatusService))
@ -270,7 +270,6 @@ def inst_emp_csv_download(
ta_cd=csv_download_form.ta_cd, ta_cd=csv_download_form.ta_cd,
inst_cd=csv_download_form.inst_cd, inst_cd=csv_download_form.inst_cd,
emp_cd=csv_download_form.emp_cd, emp_cd=csv_download_form.emp_cd,
emp_chg_type_cd=csv_download_form.emp_chg_type_cd,
apply_date_from=csv_download_form.apply_date_from, apply_date_from=csv_download_form.apply_date_from,
start_date_from=csv_download_form.start_date_from, start_date_from=csv_download_form.start_date_from,
start_date_to=csv_download_form.start_date_to, start_date_to=csv_download_form.start_date_to,

View File

@ -189,7 +189,7 @@ class DatabaseClient:
self.__session = None self.__session = None
def to_jst(self): def to_jst(self):
self.execute('SET SESSION time_zone = "Asia/Tokyo"') self.execute('SET time_zone = "+9:00"')
def __execute_with_transaction(self, query: str, parameters: dict): def __execute_with_transaction(self, query: str, parameters: dict):
# トランザクションを開始してクエリを実行する # トランザクションを開始してクエリを実行する

View File

@ -2,7 +2,7 @@ from datetime import datetime
from typing import Optional from typing import Optional
from src.model.db.base_db_model import BaseDBModel from src.model.db.base_db_model import BaseDBModel
from src.system_var import constants
class UserMasterModel(BaseDBModel): class UserMasterModel(BaseDBModel):
user_id: Optional[str] user_id: Optional[str]
@ -25,8 +25,6 @@ class UserMasterModel(BaseDBModel):
updater: Optional[str] updater: Optional[str]
update_date: Optional[datetime] update_date: Optional[datetime]
mntuser_flg: Optional[str] mntuser_flg: Optional[str]
mntuser_login_failed_cnt: Optional[int]
mntuser_last_login_failed_datetime: Optional[datetime]
def is_enable_user(self): def is_enable_user(self):
return self.enabled_flg == 'Y' return self.enabled_flg == 'Y'
@ -36,6 +34,3 @@ class UserMasterModel(BaseDBModel):
def is_groupware_user(self): def is_groupware_user(self):
return self.mntuser_flg == '0' or self.mntuser_flg is None return self.mntuser_flg == '0' or self.mntuser_flg is None
def is_login_failed_limit_exceeded(self):
return self.mntuser_login_failed_cnt >= constants.LOGIN_FAIL_LIMIT

View File

@ -1,17 +1,16 @@
import csv import csv
import json import json
from abc import ABCMeta, abstractmethod
from datetime import datetime
from io import TextIOWrapper
from src.logging.get_logger import get_logger from io import TextIOWrapper
from src.repositories.bu_master_cd_repository import BuMasterRepository from datetime import datetime
from src.repositories.emp_chg_inst_repository import EmpChgInstRepository from abc import ABCMeta, abstractmethod
from src.repositories.emp_master_repository import EmpMasterRepository
from src.repositories.generic_kbn_mst_repository import GenericKbnMstRepository
from src.repositories.mst_inst_repository import MstInstRepository
from src.system_var import constants from src.system_var import constants
from src.util.string_util import is_not_empty from src.util.string_util import is_not_empty
from src.repositories.mst_inst_repository import MstInstRepository
from src.repositories.bu_master_cd_repository import BuMasterRepository
from src.repositories.emp_master_repository import EmpMasterRepository
from src.repositories.emp_chg_inst_repository import EmpChgInstRepository
from src.logging.get_logger import get_logger
logger = get_logger('マスターメンテ') logger = get_logger('マスターメンテ')
@ -25,7 +24,6 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
emp_master_repository: EmpMasterRepository emp_master_repository: EmpMasterRepository
bu_master_repository: BuMasterRepository bu_master_repository: BuMasterRepository
emp_chginst_repository: EmpChgInstRepository emp_chginst_repository: EmpChgInstRepository
generic_kbn_mst_repository: GenericKbnMstRepository
def __init__( def __init__(
self, self,
@ -35,8 +33,7 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
mst_inst_repository: MstInstRepository, mst_inst_repository: MstInstRepository,
emp_master_repository: EmpMasterRepository, emp_master_repository: EmpMasterRepository,
bu_master_repository: BuMasterRepository, bu_master_repository: BuMasterRepository,
emp_chginst_repository: EmpChgInstRepository, emp_chginst_repository: EmpChgInstRepository
generic_kbn_mst_repository: GenericKbnMstRepository
): ):
self.csv_row = csv_row self.csv_row = csv_row
self.table_name = table_name self.table_name = table_name
@ -45,7 +42,6 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
self.emp_master_repository = emp_master_repository self.emp_master_repository = emp_master_repository
self.bu_master_repository = bu_master_repository self.bu_master_repository = bu_master_repository
self.emp_chginst_repository = emp_chginst_repository self.emp_chginst_repository = emp_chginst_repository
self.generic_kbn_mst_repository = generic_kbn_mst_repository
def validate(self) -> list[str]: def validate(self) -> list[str]:
""" """
@ -61,10 +57,6 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
error_list.extend(self.check_require()) error_list.extend(self.check_require())
# 施設コード存在チェック # 施設コード存在チェック
error_list.extend(self.check_inst_cd_exists()) error_list.extend(self.check_inst_cd_exists())
# 領域コード存在チェック
error_list.extend(self.check_ta_cd_exists())
# 担当者種別コード存在チェック
error_list.extend(self.check_emp_chg_type_cd_exists())
# MUID存在チェック # MUID存在チェック
error_list.extend(self.check_emp_cd_exists()) error_list.extend(self.check_emp_cd_exists())
# BuCd存在チェック # BuCd存在チェック
@ -87,7 +79,7 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
return error_list return error_list
def emp_chg_inst_count(self, start_date: str): def emp_chg_inst_count(self, start_date: str):
return self.emp_chginst_repository.fetch_count(self.inst_cd, self.ta_cd, self.emp_chg_type_cd, start_date, self.table_name) return self.emp_chginst_repository.fetch_count(self.inst_cd, self.ta_cd, start_date, self.table_name)
def is_exist_emp_cd(self, start_date: str) -> bool: def is_exist_emp_cd(self, start_date: str) -> bool:
if start_date is None or len(start_date) == 0: if start_date is None or len(start_date) == 0:
@ -99,36 +91,12 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
def is_exist_inst_cd(self) -> bool: def is_exist_inst_cd(self) -> bool:
return True if self.mst_inst_repository.fetch_count(self.inst_cd) > 0 else False return True if self.mst_inst_repository.fetch_count(self.inst_cd) > 0 else False
def is_exist_emp_chg_type_cd(self, start_date: str) -> bool:
if start_date is None or len(start_date) == 0:
return False
if self.generic_kbn_mst_repository.fetch_count('emp_chg_type_cd', self.emp_chg_type_cd, start_date) > 0:
return True
return False
def is_exist_ta_cd(self, start_date: str) -> bool:
if start_date is None or len(start_date) == 0:
return False
if self.generic_kbn_mst_repository.fetch_count('ta_cd', self.ta_cd, start_date) > 0:
return True
return False
def is_exist_bu_cd(self) -> bool: def is_exist_bu_cd(self) -> bool:
return True if self.bu_master_repository.fetch_count(self.bu_cd) > 0 else False return True if self.bu_master_repository.fetch_count(self.bu_cd) > 0 else False
def make_require_error_message(self, line_num: str, col_name: str) -> str: def make_require_error_message(self, line_num: str, col_name: str) -> str:
return f'{line_num}行目の{col_name}が入力されておりません。' return f'{line_num}行目の{col_name}が入力されておりません。'
def make_data_exist_error_message(self, line_num: str, primary_key_col_names: list[str]) -> str:
return self.__make_check_data_exists_error_message(line_num, primary_key_col_names, 'がすべて同一のデータが既に登録されています。')
def make_data_not_exist_error_message(self, line_num: str, primary_key_col_names: list[str]) -> str:
return self.__make_check_data_exists_error_message(line_num, primary_key_col_names, 'がすべて同一のデータが存在しないため更新できません。')
def __make_check_data_exists_error_message(self, line_num: str, primary_key_col_names: list[str], suffix_message: str) -> str:
primary_key_logical_names = ''.join(primary_key_col_names)
return f'{line_num}行目の{primary_key_logical_names}{suffix_message}'
def __parse_str_to_date(self, check_date: str) -> tuple[bool, datetime]: def __parse_str_to_date(self, check_date: str) -> tuple[bool, datetime]:
try: try:
check_date_time: datetime = datetime.strptime(check_date, '%Y%m%d') check_date_time: datetime = datetime.strptime(check_date, '%Y%m%d')
@ -192,18 +160,6 @@ class MasterMainteCSVItem(metaclass=ABCMeta):
pass pass
... ...
@abstractmethod
def check_emp_chg_type_cd_exists(self) -> list[str]:
"""担当者種別コード存在チェック"""
pass
...
@abstractmethod
def check_ta_cd_exists(self) -> list[str]:
"""領域コード存在チェック"""
pass
...
@abstractmethod @abstractmethod
def check_emp_cd_exists(self) -> list[str]: def check_emp_cd_exists(self) -> list[str]:
"""MUID存在チェック""" """MUID存在チェック"""
@ -249,8 +205,7 @@ class MasterMainteNewInstEmpCSVItem(MasterMainteCSVItem):
mst_inst_repository: MstInstRepository, mst_inst_repository: MstInstRepository,
emp_master_repository: EmpMasterRepository, emp_master_repository: EmpMasterRepository,
bu_master_repository: BuMasterRepository, bu_master_repository: BuMasterRepository,
emp_chginst_repository: EmpChgInstRepository, emp_chginst_repository: EmpChgInstRepository
generic_kbn_mst_repository: GenericKbnMstRepository
): ):
super().__init__( super().__init__(
csv_row, csv_row,
@ -259,13 +214,11 @@ class MasterMainteNewInstEmpCSVItem(MasterMainteCSVItem):
mst_inst_repository, mst_inst_repository,
emp_master_repository, emp_master_repository,
bu_master_repository, bu_master_repository,
emp_chginst_repository, emp_chginst_repository
generic_kbn_mst_repository
) )
self.inst_cd = super().get_csv_value(constants.CSV_NEW_INST_CD_COL_NO) self.inst_cd = super().get_csv_value(constants.CSV_NEW_INST_CD_COL_NO)
self.inst_name = super().get_csv_value(constants.CSV_NEW_INST_NAME_COL_NO) self.inst_name = super().get_csv_value(constants.CSV_NEW_INST_NAME_COL_NO)
self.ta_cd = super().get_csv_value(constants.CSV_NEW_TA_CD_COL_NO) self.ta_cd = super().get_csv_value(constants.CSV_NEW_TA_CD_COL_NO)
self.emp_chg_type_cd = super().get_csv_value(constants.CSV_NEW_EMP_CHG_TYPE_CD_COL_NO)
self.emp_cd = super().get_csv_value(constants.CSV_NEW_EMP_CD_COL_NO) self.emp_cd = super().get_csv_value(constants.CSV_NEW_EMP_CD_COL_NO)
self.emp_name_family = super().get_csv_value(constants.CSV_NEW_EMP_NAME_FAMILY_COL_NO) self.emp_name_family = super().get_csv_value(constants.CSV_NEW_EMP_NAME_FAMILY_COL_NO)
self.emp_name_first = super().get_csv_value(constants.CSV_NEW_EMP_NAME_FIRST_COL_NO) self.emp_name_first = super().get_csv_value(constants.CSV_NEW_EMP_NAME_FIRST_COL_NO)
@ -284,9 +237,6 @@ class MasterMainteNewInstEmpCSVItem(MasterMainteCSVItem):
if len(self.ta_cd) == 0: if len(self.ta_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_TA_CD_COL_NO])) self.line_num, constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_TA_CD_COL_NO]))
if len(self.emp_chg_type_cd) == 0:
error_list.append(self.make_require_error_message(
self.line_num, constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_EMP_CHG_TYPE_CD_COL_NO]))
if len(self.emp_cd) == 0: if len(self.emp_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_EMP_CD_COL_NO])) self.line_num, constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_EMP_CD_COL_NO]))
@ -321,26 +271,6 @@ class MasterMainteNewInstEmpCSVItem(MasterMainteCSVItem):
は従業員マスタに存在しない もしくは 適用期間外のIDです') は従業員マスタに存在しない もしくは 適用期間外のIDです')
return error_list return error_list
def check_emp_chg_type_cd_exists(self) -> list[str]:
error_list = []
if not self.start_date or not self.emp_chg_type_cd:
return error_list
if is_not_empty(self.emp_chg_type_cd) and super().is_exist_emp_chg_type_cd(self.start_date) is False:
error_list.append(f'{self.line_num}行目の{constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_EMP_CHG_TYPE_CD_COL_NO]}\
は汎用区分マスタに存在しない もしくは 適用期間外のコードです')
return error_list
def check_ta_cd_exists(self) -> list[str]:
error_list = []
if not self.start_date or not self.ta_cd:
return error_list
if is_not_empty(self.ta_cd) and super().is_exist_ta_cd(self.start_date) is False:
error_list.append(f'{self.line_num}行目の{constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_TA_CD_COL_NO]}\
は汎用区分マスタに存在しない もしくは 適用期間外のコードです')
return error_list
def check_bu_cd_exists(self) -> list[str]: def check_bu_cd_exists(self) -> list[str]:
error_list = [] error_list = []
@ -373,15 +303,7 @@ class MasterMainteNewInstEmpCSVItem(MasterMainteCSVItem):
def check_data_exists(self) -> list[str]: def check_data_exists(self) -> list[str]:
error_list = [] error_list = []
if super().emp_chg_inst_count(self.start_date) > 0: if super().emp_chg_inst_count(self.start_date) > 0:
error_list.append(super().make_data_exist_error_message( error_list.append(f'{self.line_num}行目の施設コード、領域コード、適用開始日がすべて同一のデータが既に登録されています。')
self.line_num,
primary_key_col_names=[
constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_INST_CD_COL_NO],
constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_TA_CD_COL_NO],
constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_EMP_CHG_TYPE_CD_COL_NO],
constants.NEW_INST_EMP_CSV_LOGICAL_NAMES[constants.CSV_NEW_START_DATE]
]
))
return error_list return error_list
@ -407,8 +329,7 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
mst_inst_repository: MstInstRepository, mst_inst_repository: MstInstRepository,
emp_master_repository: EmpMasterRepository, emp_master_repository: EmpMasterRepository,
bu_master_repository: BuMasterRepository, bu_master_repository: BuMasterRepository,
emp_chginst_repository: EmpChgInstRepository, emp_chginst_repository: EmpChgInstRepository
generic_kbn_mst_repository: GenericKbnMstRepository
): ):
super().__init__( super().__init__(
csv_row, csv_row,
@ -417,8 +338,7 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
mst_inst_repository, mst_inst_repository,
emp_master_repository, emp_master_repository,
bu_master_repository, bu_master_repository,
emp_chginst_repository, emp_chginst_repository
generic_kbn_mst_repository
) )
self.bu_cd = super().get_csv_value(constants.CSV_CHANGE_BU_CD_COL_NO) self.bu_cd = super().get_csv_value(constants.CSV_CHANGE_BU_CD_COL_NO)
self.bu_name = super().get_csv_value(constants.CSV_CHANGE_BU_NAME_COL_NO) self.bu_name = super().get_csv_value(constants.CSV_CHANGE_BU_NAME_COL_NO)
@ -428,7 +348,6 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
self.inst_name = super().get_csv_value(constants.CSV_CHANGE_INST_NAME_COL_NO) self.inst_name = super().get_csv_value(constants.CSV_CHANGE_INST_NAME_COL_NO)
self.ta_cd = super().get_csv_value(constants.CSV_CHANGE_TA_CD_COL_NO) self.ta_cd = super().get_csv_value(constants.CSV_CHANGE_TA_CD_COL_NO)
self.explain = super().get_csv_value(constants.CSV_CHANGE_EXPLAIN_COL_NO) self.explain = super().get_csv_value(constants.CSV_CHANGE_EXPLAIN_COL_NO)
self.emp_chg_type_cd = super().get_csv_value(constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO)
self.emp_cd = super().get_csv_value(constants.CSV_CHANGE_EMP_CD_COL_NO) self.emp_cd = super().get_csv_value(constants.CSV_CHANGE_EMP_CD_COL_NO)
self.emp_full_name = super().get_csv_value(constants.CSV_CHANGE_EMP_FULL_NAME_COL_NO) self.emp_full_name = super().get_csv_value(constants.CSV_CHANGE_EMP_FULL_NAME_COL_NO)
self.inst_emp_start_date = super().get_csv_value(constants.CSV_CHANGE_INST_EMP_START_DATE_COL_NO) self.inst_emp_start_date = super().get_csv_value(constants.CSV_CHANGE_INST_EMP_START_DATE_COL_NO)
@ -451,9 +370,6 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
if len(self.ta_cd) == 0: if len(self.ta_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO])) self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO]))
if len(self.emp_chg_type_cd) == 0:
error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO]))
if len(self.emp_cd) == 0: if len(self.emp_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CD_COL_NO])) self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CD_COL_NO]))
@ -472,9 +388,6 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
if len(self.ta_cd) == 0: if len(self.ta_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO])) self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO]))
if len(self.emp_chg_type_cd) == 0:
error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO]))
if len(self.inst_emp_start_date) == 0: if len(self.inst_emp_start_date) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, self.line_num,
@ -490,10 +403,6 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
if len(self.ta_cd) == 0: if len(self.ta_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO])) self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO]))
if len(self.emp_chg_type_cd) == 0:
error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO]))
if len(self.emp_cd) == 0: if len(self.emp_cd) == 0:
error_list.append(self.make_require_error_message( error_list.append(self.make_require_error_message(
self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CD_COL_NO])) self.line_num, constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CD_COL_NO]))
@ -526,28 +435,6 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
は従業員マスタに存在しない もしくは 適用期間外のIDです') は従業員マスタに存在しない もしくは 適用期間外のIDです')
return error_list return error_list
def check_emp_chg_type_cd_exists(self) -> list[str]:
error_list = []
if not self.inst_emp_start_date or not self.emp_chg_type_cd:
return error_list
if is_not_empty(self.emp_chg_type_cd) and super().is_exist_emp_chg_type_cd(self.inst_emp_start_date) is False:
error_list.append(f'{self.line_num}行目の{constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO]}\
は汎用区分マスタに存在しない もしくは 適用期間外のコードです')
return error_list
def check_ta_cd_exists(self) -> list[str]:
error_list = []
if not self.inst_emp_start_date or not self.ta_cd:
return error_list
if is_not_empty(self.ta_cd) and super().is_exist_ta_cd(self.inst_emp_start_date) is False:
error_list.append(f'{self.line_num}行目の{constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO]}\
は汎用区分マスタに存在しない もしくは 適用期間外のコードです')
return error_list
def check_bu_cd_exists(self) -> list[str]: def check_bu_cd_exists(self) -> list[str]:
error_list = [] error_list = []
@ -597,26 +484,10 @@ class MasterMainteChangeInstEmpCSVItem(MasterMainteCSVItem):
error_list = [] error_list = []
emp_chg_inst_count = super().emp_chg_inst_count(self.inst_emp_start_date) emp_chg_inst_count = super().emp_chg_inst_count(self.inst_emp_start_date)
if self.comment == '追加' and emp_chg_inst_count > 0: if self.comment == '追加' and emp_chg_inst_count > 0:
error_list.append(super().make_data_exist_error_message( error_list.append(f'{self.line_num}行目の施設コード、領域コード、施設担当_開始日がすべて同一のデータが既に登録されています。')
self.line_num,
primary_key_col_names=[
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_INST_CD_COL_NO],
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO],
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO],
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_INST_EMP_START_DATE_COL_NO]
]
))
elif (self.comment == '終了' or self.comment == '担当者修正') and emp_chg_inst_count == 0: elif (self.comment == '終了' or self.comment == '担当者修正') and emp_chg_inst_count == 0:
error_list.append(super().make_data_not_exist_error_message( error_list.append(f'{self.line_num}行目の施設コード、領域コード、施設担当_開始日がすべて同一のデータが存在しないため更新できません。')
self.line_num,
primary_key_col_names=[
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_INST_CD_COL_NO],
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_TA_CD_COL_NO],
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO],
constants.CHANGE_INST_CSV_LOGICAL_NAMES[constants.CSV_CHANGE_INST_EMP_START_DATE_COL_NO]
]
))
return error_list return error_list
@ -654,8 +525,7 @@ class MasterMainteCSVItems:
mst_inst_repository: MstInstRepository, mst_inst_repository: MstInstRepository,
emp_master_repository: EmpMasterRepository, emp_master_repository: EmpMasterRepository,
bu_master_repository: BuMasterRepository, bu_master_repository: BuMasterRepository,
emp_chginst_repository: EmpChgInstRepository, emp_chginst_repository: EmpChgInstRepository
generic_kbn_mst_repository: GenericKbnMstRepository
) -> None: ) -> None:
reader = csv.reader(file) reader = csv.reader(file)
csv_rows = [] csv_rows = []
@ -670,9 +540,7 @@ class MasterMainteCSVItems:
mst_inst_repository, mst_inst_repository,
emp_master_repository, emp_master_repository,
bu_master_repository, bu_master_repository,
emp_chginst_repository, emp_chginst_repository))
generic_kbn_mst_repository
))
self.lines = csv_rows self.lines = csv_rows
def __select_function(self, def __select_function(self,
@ -683,8 +551,7 @@ class MasterMainteCSVItems:
mst_inst_repository: MstInstRepository, mst_inst_repository: MstInstRepository,
emp_master_repository: EmpMasterRepository, emp_master_repository: EmpMasterRepository,
bu_master_repository: BuMasterRepository, bu_master_repository: BuMasterRepository,
emp_chginst_repository: EmpChgInstRepository, emp_chginst_repository: EmpChgInstRepository) -> MasterMainteCSVItem:
generic_kbn_mst_repository: GenericKbnMstRepository) -> MasterMainteCSVItem:
if function_type == 'new': if function_type == 'new':
return MasterMainteNewInstEmpCSVItem( return MasterMainteNewInstEmpCSVItem(
row, row,
@ -693,8 +560,7 @@ class MasterMainteCSVItems:
mst_inst_repository, mst_inst_repository,
emp_master_repository, emp_master_repository,
bu_master_repository, bu_master_repository,
emp_chginst_repository, emp_chginst_repository)
generic_kbn_mst_repository)
elif function_type == 'change': elif function_type == 'change':
return MasterMainteChangeInstEmpCSVItem( return MasterMainteChangeInstEmpCSVItem(
row, row,
@ -703,5 +569,4 @@ class MasterMainteCSVItems:
mst_inst_repository, mst_inst_repository,
emp_master_repository, emp_master_repository,
bu_master_repository, bu_master_repository,
emp_chginst_repository, emp_chginst_repository)
generic_kbn_mst_repository)

View File

@ -29,8 +29,8 @@ class MasterMainteEmpChgInstFunction(metaclass=ABCMeta):
def save(self): def save(self):
error_list = [] error_list = []
try: try:
self.emp_chginst_repository.begin()
self.emp_chginst_repository.to_jst() self.emp_chginst_repository.to_jst()
self.emp_chginst_repository.begin()
(result_message, error_list) = self.write_emp_chg_inst_table() (result_message, error_list) = self.write_emp_chg_inst_table()
if len(error_list) > 0: if len(error_list) > 0:
self.emp_chginst_repository.rollback() self.emp_chginst_repository.rollback()
@ -46,7 +46,6 @@ class MasterMainteEmpChgInstFunction(metaclass=ABCMeta):
self.emp_chginst_repository.insert_emp_chg_inst( self.emp_chginst_repository.insert_emp_chg_inst(
data['施設コード'], data['施設コード'],
data['領域コード'], data['領域コード'],
data['担当者種別コード'],
data['MUID'], data['MUID'],
data['ビジネスユニットコード'], data['ビジネスユニットコード'],
start_date, start_date,
@ -149,7 +148,6 @@ class ChangeEmpChgInstFunction(MasterMainteEmpChgInstFunction):
self.emp_chginst_repository.end_emp_chg_inst( self.emp_chginst_repository.end_emp_chg_inst(
data['施設コード'], data['施設コード'],
data['領域コード'], data['領域コード'],
data['担当者種別コード'],
data['施設担当_開始日'], data['施設担当_開始日'],
data['終了日の変更'], data['終了日の変更'],
self.user_name, self.user_name,
@ -160,7 +158,6 @@ class ChangeEmpChgInstFunction(MasterMainteEmpChgInstFunction):
data['施設コード'], data['施設コード'],
data['領域コード'], data['領域コード'],
data['施設担当_開始日'], data['施設担当_開始日'],
data['担当者種別コード'],
data['MUID'], data['MUID'],
self.user_name, self.user_name,
self.table_name) self.table_name)

View File

@ -2,22 +2,20 @@ from typing import Optional
from fastapi import Form from fastapi import Form
from src.model.request.request_base_model import RequestBaseModel
from src.util.sanitize import sanitize from src.util.sanitize import sanitize
from src.model.request.request_base_model import RequestBaseModel
from src.util.string_util import is_not_empty from src.util.string_util import is_not_empty
@sanitize @sanitize
class MasterMainteCsvDlModel(RequestBaseModel): class MasterMainteCsvDlModel(RequestBaseModel):
# adaptは検索に使用する値
ta_cd: Optional[str] ta_cd: Optional[str]
adapt_ta_cd: Optional[str] adapt_ta_cd: Optional[str]
inst_cd: Optional[str] inst_cd: Optional[str]
adapt_inst_cd: Optional[str] adapt_inst_cd: Optional[str]
emp_cd: Optional[str] emp_cd: Optional[str]
adapt_emp_cd: Optional[str] adapt_emp_cd: Optional[str]
emp_chg_type_cd: Optional[str]
adapt_emp_chg_type_cd: Optional[str]
apply_date_from: Optional[str] apply_date_from: Optional[str]
adapt_apply_date_from: Optional[str] adapt_apply_date_from: Optional[str]
start_date_from: Optional[str] start_date_from: Optional[str]
@ -44,7 +42,6 @@ class MasterMainteCsvDlModel(RequestBaseModel):
ctrl_ta_cd: Optional[str] = Form(None), ctrl_ta_cd: Optional[str] = Form(None),
ctrl_inst_cd: Optional[str] = Form(None), ctrl_inst_cd: Optional[str] = Form(None),
ctrl_emp_cd: Optional[str] = Form(None), ctrl_emp_cd: Optional[str] = Form(None),
ctrl_emp_chg_type_cd: Optional[str] = Form(None),
ctrl_apply_date_from: Optional[str] = Form(None), ctrl_apply_date_from: Optional[str] = Form(None),
ctrl_start_date_from: Optional[str] = Form(None), ctrl_start_date_from: Optional[str] = Form(None),
ctrl_start_date_to: Optional[str] = Form(None), ctrl_start_date_to: Optional[str] = Form(None),
@ -61,7 +58,6 @@ class MasterMainteCsvDlModel(RequestBaseModel):
ctrl_ta_cd, ctrl_ta_cd,
ctrl_inst_cd, ctrl_inst_cd,
ctrl_emp_cd, ctrl_emp_cd,
ctrl_emp_chg_type_cd,
ctrl_apply_date_from, ctrl_apply_date_from,
ctrl_start_date_from, ctrl_start_date_from,
ctrl_start_date_to, ctrl_start_date_to,
@ -79,7 +75,6 @@ class MasterMainteCsvDlModel(RequestBaseModel):
ctrl_ta_cd: str, ctrl_ta_cd: str,
ctrl_inst_cd: str, ctrl_inst_cd: str,
ctrl_emp_cd: str, ctrl_emp_cd: str,
ctrl_emp_chg_type_cd,
ctrl_apply_date_from: str, ctrl_apply_date_from: str,
ctrl_start_date_from: str, ctrl_start_date_from: str,
ctrl_start_date_to: str, ctrl_start_date_to: str,
@ -94,7 +89,6 @@ class MasterMainteCsvDlModel(RequestBaseModel):
ctrl_ta_cd = ctrl_ta_cd if is_not_empty(ctrl_ta_cd) else '' ctrl_ta_cd = ctrl_ta_cd if is_not_empty(ctrl_ta_cd) else ''
ctrl_inst_cd = ctrl_inst_cd if is_not_empty(ctrl_inst_cd) else '' ctrl_inst_cd = ctrl_inst_cd if is_not_empty(ctrl_inst_cd) else ''
ctrl_emp_cd = ctrl_emp_cd if is_not_empty(ctrl_emp_cd) else '' ctrl_emp_cd = ctrl_emp_cd if is_not_empty(ctrl_emp_cd) else ''
ctrl_emp_chg_type_cd = ctrl_emp_chg_type_cd if is_not_empty(ctrl_emp_chg_type_cd) else ''
adapt_apply_date_from = '' adapt_apply_date_from = ''
if is_not_empty(ctrl_apply_date_from): if is_not_empty(ctrl_apply_date_from):
@ -153,8 +147,6 @@ class MasterMainteCsvDlModel(RequestBaseModel):
adapt_inst_cd=ctrl_inst_cd, adapt_inst_cd=ctrl_inst_cd,
emp_cd=ctrl_emp_cd, emp_cd=ctrl_emp_cd,
adapt_emp_cd=ctrl_emp_cd, adapt_emp_cd=ctrl_emp_cd,
emp_chg_type_cd=ctrl_emp_chg_type_cd,
adapt_emp_chg_type_cd=ctrl_emp_chg_type_cd,
apply_date_from=ctrl_apply_date_from, apply_date_from=ctrl_apply_date_from,
adapt_apply_date_from=adapt_apply_date_from, adapt_apply_date_from=adapt_apply_date_from,
start_date_from=ctrl_start_date_from, start_date_from=ctrl_start_date_from,

View File

@ -9,7 +9,6 @@ class InstEmpCsvDownloadViewModel(BaseModel):
ta_cd: str = '' ta_cd: str = ''
inst_cd: str = '' inst_cd: str = ''
emp_cd: str = '' emp_cd: str = ''
emp_chg_type_cd: str = ''
apply_date_from: str = '' apply_date_from: str = ''
start_date_from: str = '' start_date_from: str = ''
start_date_to: str = '' start_date_to: str = ''

View File

@ -1,10 +1,10 @@
from src.db import sql_condition as condition from src.repositories.base_repository import BaseRepository
from src.db.sql_condition import SQLCondition from src.db.sql_condition import SQLCondition
from src.logging.get_logger import get_logger from src.db import sql_condition as condition
from src.model.db.master_mente_count import MasterMenteCountModel from src.model.db.master_mente_count import MasterMenteCountModel
from src.model.request.master_mainte_csvdl import MasterMainteCsvDlModel from src.model.request.master_mainte_csvdl import MasterMainteCsvDlModel
from src.repositories.base_repository import BaseRepository
from src.util.string_util import is_not_empty from src.util.string_util import is_not_empty
from src.logging.get_logger import get_logger
logger = get_logger('従業員担当施設マスタ') logger = get_logger('従業員担当施設マスタ')
@ -28,7 +28,6 @@ class EmpChgInstRepository(BaseRepository):
( (
inst_cd, inst_cd,
ta_cd, ta_cd,
emp_chg_type_cd,
emp_cd, emp_cd,
bu_cd, bu_cd,
start_date, start_date,
@ -43,7 +42,6 @@ class EmpChgInstRepository(BaseRepository):
VALUES ( VALUES (
:inst_cd, :inst_cd,
:ta_cd, :ta_cd,
:emp_chg_type_cd,
:emp_cd, :emp_cd,
:bu_cd, :bu_cd,
:start_date, :start_date,
@ -57,14 +55,13 @@ class EmpChgInstRepository(BaseRepository):
) )
""" """
def insert_emp_chg_inst(self, inst_cd, ta_cd, emp_chg_type_cd, emp_cd, bu_cd, start_date, def insert_emp_chg_inst(self, inst_cd, ta_cd, emp_cd, bu_cd, start_date,
end_date, create_user_name, table_name): end_date, create_user_name, table_name):
try: try:
query = self.INSERT_SQL.format(table_name=table_name) query = self.INSERT_SQL.format(table_name=table_name)
self._database.execute(query, { self._database.execute(query, {
'inst_cd': inst_cd, 'inst_cd': inst_cd,
'ta_cd': ta_cd, 'ta_cd': ta_cd,
'emp_chg_type_cd': emp_chg_type_cd,
'emp_cd': emp_cd, 'emp_cd': emp_cd,
'bu_cd': bu_cd, 'bu_cd': bu_cd,
'start_date': start_date, 'start_date': start_date,
@ -85,19 +82,17 @@ class EmpChgInstRepository(BaseRepository):
update_date = NOW() update_date = NOW()
WHERE WHERE
inst_cd = :inst_cd inst_cd = :inst_cd
AND ta_cd = :ta_cd and ta_cd = :ta_cd
AND emp_chg_type_cd = :emp_chg_type_cd and start_date = :start_date
AND start_date = :start_date
""" """
def end_emp_chg_inst(self, inst_cd, ta_cd, emp_chg_type_cd, start_date, def end_emp_chg_inst(self, inst_cd, ta_cd, start_date,
end_date, update_user_name, table_name): end_date, update_user_name, table_name):
try: try:
query = self.UPDATE_END_DATE_SQL.format(table_name=table_name) query = self.UPDATE_END_DATE_SQL.format(table_name=table_name)
self._database.execute(query, { self._database.execute(query, {
'inst_cd': inst_cd, 'inst_cd': inst_cd,
'ta_cd': ta_cd, 'ta_cd': ta_cd,
'emp_chg_type_cd': emp_chg_type_cd,
'start_date': start_date, 'start_date': start_date,
'end_date': end_date, 'end_date': end_date,
'update_user_name': update_user_name 'update_user_name': update_user_name
@ -115,18 +110,16 @@ class EmpChgInstRepository(BaseRepository):
update_date = NOW() update_date = NOW()
where where
inst_cd = :inst_cd inst_cd = :inst_cd
AND ta_cd = :ta_cd and ta_cd = :ta_cd
AND emp_chg_type_cd = :emp_chg_type_cd and start_date = :start_date
AND start_date = :start_date
""" """
def modify_emp_chg_inst(self, inst_cd, ta_cd, start_date, emp_chg_type_cd, emp_cd, update_user_name, table_name): def modify_emp_chg_inst(self, inst_cd, ta_cd, start_date, emp_cd, update_user_name, table_name):
try: try:
query = self.UPDATE_EMP_CD_SQL.format(table_name=table_name) query = self.UPDATE_EMP_CD_SQL.format(table_name=table_name)
self._database.execute(query, { self._database.execute(query, {
'inst_cd': inst_cd, 'inst_cd': inst_cd,
'ta_cd': ta_cd, 'ta_cd': ta_cd,
'emp_chg_type_cd': emp_chg_type_cd,
'start_date': start_date, 'start_date': start_date,
'emp_cd': emp_cd, 'emp_cd': emp_cd,
'update_user_name': update_user_name 'update_user_name': update_user_name
@ -143,15 +136,14 @@ class EmpChgInstRepository(BaseRepository):
WHERE WHERE
inst_cd = :inst_cd inst_cd = :inst_cd
AND ta_cd = :ta_cd AND ta_cd = :ta_cd
AND emp_chg_type_cd = :emp_chg_type_cd
AND start_date = :start_date AND start_date = :start_date
""" """
def fetch_count(self, inst_cd, ta_cd, emp_chg_type_cd, start_date, table_name) -> MasterMenteCountModel: def fetch_count(self, inst_cd, ta_cd, start_date, table_name) -> MasterMenteCountModel:
try: try:
query = self.FETCH_COUNT_SQL.format(table_name=table_name) query = self.FETCH_COUNT_SQL.format(table_name=table_name)
result = self._database.execute_select(query, {'inst_cd': inst_cd, 'ta_cd': ta_cd, result = self._database.execute_select(query, {'inst_cd': inst_cd, 'ta_cd': ta_cd,
'emp_chg_type_cd': emp_chg_type_cd, 'start_date': start_date}) 'start_date': start_date})
models = [MasterMenteCountModel(**r) for r in result] models = [MasterMenteCountModel(**r) for r in result]
if len(models) == 0: if len(models) == 0:
return 0 return 0
@ -165,7 +157,6 @@ class EmpChgInstRepository(BaseRepository):
eci.inst_cd AS inst_cd, eci.inst_cd AS inst_cd,
mi.inst_name AS inst_name, mi.inst_name AS inst_name,
eci.ta_cd AS ta_cd, eci.ta_cd AS ta_cd,
eci.emp_chg_type_cd AS emp_chg_type_cd,
eci.emp_cd AS emp_cd, eci.emp_cd AS emp_cd,
CONCAT(emp.emp_name_family, " ", emp.emp_name_first) AS emp_name_full, CONCAT(emp.emp_name_family, " ", emp.emp_name_first) AS emp_name_full,
eci.bu_cd AS bu_cd, eci.bu_cd AS bu_cd,
@ -221,11 +212,6 @@ class EmpChgInstRepository(BaseRepository):
parameter.adapt_emp_cd = f'%{parameter.emp_cd}%' parameter.adapt_emp_cd = f'%{parameter.emp_cd}%'
where_clauses.append(SQLCondition('eci.emp_cd', condition.LIKE, 'adapt_emp_cd')) where_clauses.append(SQLCondition('eci.emp_cd', condition.LIKE, 'adapt_emp_cd'))
# 担当者種別コードが入力されていた場合
if is_not_empty(parameter.emp_chg_type_cd):
parameter.adapt_emp_chg_type_cd = f'%{parameter.emp_chg_type_cd}%'
where_clauses.append(SQLCondition('eci.emp_chg_type_cd', condition.LIKE, 'adapt_emp_chg_type_cd'))
# 適用期間内が入力されていた場合 # 適用期間内が入力されていた場合
if is_not_empty(parameter.adapt_apply_date_from): if is_not_empty(parameter.adapt_apply_date_from):
where_clauses.append(SQLCondition('eci.start_date', condition.LE, 'adapt_apply_date_from')) where_clauses.append(SQLCondition('eci.start_date', condition.LE, 'adapt_apply_date_from'))

View File

@ -1,33 +0,0 @@
from src.repositories.base_repository import BaseRepository
from src.model.db.master_mente_count import MasterMenteCountModel
from src.logging.get_logger import get_logger
logger = get_logger('汎用区分マスタ')
class GenericKbnMstRepository(BaseRepository):
FETCH_SQL = """\
SELECT
COUNT(*) AS count
FROM
src05.generic_kbn_mst
WHERE
generic_kbn_mst.generic_kbn_cd = :generic_kbn_cd
AND
generic_kbn_mst.kbn_cd = :kbn_cd
AND
STR_TO_DATE( :start_date , '%Y%m%d') BETWEEN generic_kbn_mst.start_date AND generic_kbn_mst.end_date\
"""
def fetch_count(self, generic_kbn_cd: str, kbn_cd: str, start_date: str) -> MasterMenteCountModel:
try:
query = self.FETCH_SQL
result = self._database.execute_select(query, {'generic_kbn_cd': generic_kbn_cd, 'kbn_cd': kbn_cd, 'start_date' : start_date})
models = [MasterMenteCountModel(**r) for r in result]
if len(models) == 0:
return 0
return models[0].count
except Exception as e:
logger.error(f"DB Error : Exception={e.args}")
raise e

View File

@ -6,19 +6,6 @@ logger = get_logger('ユーザー取得')
class UserMasterRepository(BaseRepository): class UserMasterRepository(BaseRepository):
def to_jst(self):
self._database.to_jst()
def begin(self):
self._database.begin()
def commit(self):
self._database.commit()
def rollback(self):
self._database.rollback()
FETCH_SQL = """\ FETCH_SQL = """\
SELECT SELECT
* *
@ -39,46 +26,3 @@ class UserMasterRepository(BaseRepository):
except Exception as e: except Exception as e:
logger.exception(f"DB Error : Exception={e}") logger.exception(f"DB Error : Exception={e}")
raise e raise e
def increase_login_failed_count(self, parameter: dict) -> UserMasterModel:
try:
query = """\
UPDATE
src05.user_mst
SET
mntuser_login_failed_cnt =
CASE
WHEN
DATE(mntuser_last_login_failed_datetime) = DATE(CURRENT_TIMESTAMP())
THEN
mntuser_login_failed_cnt + 1
ELSE
1
END,
mntuser_last_login_failed_datetime = CURRENT_TIMESTAMP()
WHERE
user_id = :user_id
AND
mntuser_flg = 1;\
"""
self._database.execute(query, parameter)
except Exception as e:
logger.exception(f"DB Error : Exception={e}")
raise e
def disable_mnt_user(self, parameter: dict) -> UserMasterModel:
try:
query = """\
UPDATE
src05.user_mst
SET
enabled_flg = 'N'
WHERE
user_id = :user_id
AND
mntuser_flg = 1\
"""
self._database.execute(query, parameter)
except Exception as e:
logger.exception(f"DB Error : Exception={e}")
raise e

View File

@ -49,27 +49,6 @@ class LoginService(BaseService):
user_record: UserMasterModel = self.user_repository.fetch_one({'user_id': user_id}) user_record: UserMasterModel = self.user_repository.fetch_one({'user_id': user_id})
return user_record return user_record
def increase_login_failed_count(self, user_id: str):
try:
# セッション内のタイムゾーン変更のため、明示的にトランザクションを開始する
self.user_repository.begin()
self.user_repository.to_jst()
self.user_repository.increase_login_failed_count({'user_id': user_id})
self.user_repository.commit()
except Exception as e:
self.user_repository.rollback()
raise e
def on_login_fail_limit_exceeded(self, user_id: str):
self.user_repository.disable_mnt_user({'user_id': user_id})
def is_login_failed_limit_exceeded(self, user_id: str):
user_record: UserMasterModel = self.user_repository.fetch_one({'user_id': user_id})
if user_record is None:
return False
return user_record.is_login_failed_limit_exceeded()
def __secret_hash(self, username: str): def __secret_hash(self, username: str):
# see - https://aws.amazon.com/jp/premiumsupport/knowledge-center/cognito-unable-to-verify-secret-hash/ # noqa # see - https://aws.amazon.com/jp/premiumsupport/knowledge-center/cognito-unable-to-verify-secret-hash/ # noqa
message = bytes(username + environment.COGNITO_CLIENT_ID, 'utf-8') message = bytes(username + environment.COGNITO_CLIENT_ID, 'utf-8')

View File

@ -19,7 +19,6 @@ from src.repositories.mst_inst_repository import MstInstRepository
from src.repositories.bu_master_cd_repository import BuMasterRepository from src.repositories.bu_master_cd_repository import BuMasterRepository
from src.repositories.emp_master_repository import EmpMasterRepository from src.repositories.emp_master_repository import EmpMasterRepository
from src.repositories.emp_chg_inst_repository import EmpChgInstRepository from src.repositories.emp_chg_inst_repository import EmpChgInstRepository
from src.repositories.generic_kbn_mst_repository import GenericKbnMstRepository
from src.model.internal.master_mainte_csv import MasterMainteCSVItems from src.model.internal.master_mainte_csv import MasterMainteCSVItems
from src.model.internal.master_mainte_emp_chg_inst_function import NewEmpChgInstFunction from src.model.internal.master_mainte_emp_chg_inst_function import NewEmpChgInstFunction
from src.model.internal.master_mainte_emp_chg_inst_function import ChangeEmpChgInstFunction from src.model.internal.master_mainte_emp_chg_inst_function import ChangeEmpChgInstFunction
@ -39,7 +38,6 @@ class MasterMainteService(BaseService):
'emp_master_repository': EmpMasterRepository, 'emp_master_repository': EmpMasterRepository,
'bu_master_repository': BuMasterRepository, 'bu_master_repository': BuMasterRepository,
'emp_chginst_repository': EmpChgInstRepository, 'emp_chginst_repository': EmpChgInstRepository,
'generic_kbn_mst_repository': GenericKbnMstRepository,
} }
CLIENTS = { CLIENTS = {
@ -50,7 +48,6 @@ class MasterMainteService(BaseService):
emp_master_repository: EmpMasterRepository emp_master_repository: EmpMasterRepository
bu_master_repository: BuMasterRepository bu_master_repository: BuMasterRepository
emp_chginst_repository: EmpChgInstRepository emp_chginst_repository: EmpChgInstRepository
generic_kbn_mst_repository: GenericKbnMstRepository
s3_client: S3Client s3_client: S3Client
def __init__(self, repositories: dict[str, BaseRepository], clients: dict[str, AWSAPIClient]) -> None: def __init__(self, repositories: dict[str, BaseRepository], clients: dict[str, AWSAPIClient]) -> None:
@ -59,7 +56,6 @@ class MasterMainteService(BaseService):
self.emp_master_repository = repositories['emp_master_repository'] self.emp_master_repository = repositories['emp_master_repository']
self.bu_master_repository = repositories['bu_master_repository'] self.bu_master_repository = repositories['bu_master_repository']
self.emp_chginst_repository = repositories['emp_chginst_repository'] self.emp_chginst_repository = repositories['emp_chginst_repository']
self.generic_kbn_mst_repository = repositories['generic_kbn_mst_repository']
self.s3_client = clients['s3_client'] self.s3_client = clients['s3_client']
def prepare_mainte_csv_up_view(self, def prepare_mainte_csv_up_view(self,
@ -81,8 +77,7 @@ class MasterMainteService(BaseService):
self.mst_inst_repository, self.mst_inst_repository,
self.emp_master_repository, self.emp_master_repository,
self.bu_master_repository, self.bu_master_repository,
self.emp_chginst_repository, self.emp_chginst_repository
self.generic_kbn_mst_repository
) )
error_message_list = [] error_message_list = []
@ -153,8 +148,8 @@ class MasterMainteService(BaseService):
def copy_data_real_to_dummy(self) -> TableOverrideViewModel: def copy_data_real_to_dummy(self) -> TableOverrideViewModel:
try: try:
self.emp_chginst_repository.begin()
self.emp_chginst_repository.to_jst() self.emp_chginst_repository.to_jst()
self.emp_chginst_repository.begin()
self.emp_chginst_repository.delete_dummy_table() self.emp_chginst_repository.delete_dummy_table()
self.emp_chginst_repository.copy_real_to_dummy() self.emp_chginst_repository.copy_real_to_dummy()
self.emp_chginst_repository.commit() self.emp_chginst_repository.commit()

View File

@ -63,7 +63,6 @@ LOGOUT_REASON_BACKUP_PROCESSING = 'dump_processing'
LOGOUT_REASON_NOT_LOGIN = 'not_login' LOGOUT_REASON_NOT_LOGIN = 'not_login'
LOGOUT_REASON_DB_ERROR = 'db_error' LOGOUT_REASON_DB_ERROR = 'db_error'
LOGOUT_REASON_UNEXPECTED = 'unexpected' LOGOUT_REASON_UNEXPECTED = 'unexpected'
LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED = 'login_failed_limit_exceeded'
LOGOUT_REASON_MESSAGE_MAP = { LOGOUT_REASON_MESSAGE_MAP = {
LOGOUT_REASON_DO_LOGOUT: 'Logoutしました。', LOGOUT_REASON_DO_LOGOUT: 'Logoutしました。',
@ -73,8 +72,7 @@ LOGOUT_REASON_MESSAGE_MAP = {
LOGOUT_REASON_BACKUP_PROCESSING: 'バックアップ取得を開始しました。<br>日次バッチ更新が終了するまでマスターメンテは使用できません', LOGOUT_REASON_BACKUP_PROCESSING: 'バックアップ取得を開始しました。<br>日次バッチ更新が終了するまでマスターメンテは使用できません',
LOGOUT_REASON_NOT_LOGIN: 'Loginしてからページにアクセスしてください。', LOGOUT_REASON_NOT_LOGIN: 'Loginしてからページにアクセスしてください。',
LOGOUT_REASON_DB_ERROR: 'DB接続に失敗しました。<br>再度Loginするか、<br>管理者にお問い合わせください。', LOGOUT_REASON_DB_ERROR: 'DB接続に失敗しました。<br>再度Loginするか、<br>管理者にお問い合わせください。',
LOGOUT_REASON_UNEXPECTED: '予期しないエラーが発生しました。<br>再度Loginするか、<br>管理者に問い合わせてください。', LOGOUT_REASON_UNEXPECTED: '予期しないエラーが発生しました。<br>再度Loginするか、<br>管理者に問い合わせてください。'
LOGOUT_REASON_LOGIN_FAILED_LIMIT_EXCEEDED: 'ログイン失敗回数の上限を超えましたので<br>アカウントをロックしました。<br>管理者に連絡してください'
} }
# 新規施設担当者登録CSV(マスターメンテ) # 新規施設担当者登録CSV(マスターメンテ)
@ -82,7 +80,6 @@ NEW_INST_EMP_CSV_LOGICAL_NAMES = [
'施設コード', '施設コード',
'施設名', '施設名',
'領域コード', '領域コード',
'担当者種別コード',
'MUID', 'MUID',
'担当者名(姓)', '担当者名(姓)',
'担当者名(名)', '担当者名(名)',
@ -96,20 +93,18 @@ CSV_NEW_INST_CD_COL_NO = 0
CSV_NEW_INST_NAME_COL_NO = 1 CSV_NEW_INST_NAME_COL_NO = 1
# 領域コードの列No # 領域コードの列No
CSV_NEW_TA_CD_COL_NO = 2 CSV_NEW_TA_CD_COL_NO = 2
# 担当者種別コードの列No
CSV_NEW_EMP_CHG_TYPE_CD_COL_NO = 3
# MUIDの列No # MUIDの列No
CSV_NEW_EMP_CD_COL_NO = 4 CSV_NEW_EMP_CD_COL_NO = 3
# 担当者名の列No # 担当者名の列No
CSV_NEW_EMP_NAME_FAMILY_COL_NO = 5 CSV_NEW_EMP_NAME_FAMILY_COL_NO = 4
# 担当者名の列No # 担当者名の列No
CSV_NEW_EMP_NAME_FIRST_COL_NO = 6 CSV_NEW_EMP_NAME_FIRST_COL_NO = 5
# ビジネスユニットコードの列No # ビジネスユニットコードの列No
CSV_NEW_BU_CD_COL_NO = 7 CSV_NEW_BU_CD_COL_NO = 6
# 適用開始日の列No # 適用開始日の列No
CSV_NEW_START_DATE = 8 CSV_NEW_START_DATE = 7
# 適用終了日の列No # 適用終了日の列No
CSV_NEW_END_DATE = 9 CSV_NEW_END_DATE = 8
# 施設担当者変更登録CSV(マスターメンテ) # 施設担当者変更登録CSV(マスターメンテ)
CHANGE_INST_CSV_LOGICAL_NAMES = [ CHANGE_INST_CSV_LOGICAL_NAMES = [
@ -121,7 +116,6 @@ CHANGE_INST_CSV_LOGICAL_NAMES = [
'施設名', '施設名',
'領域コード', '領域コード',
'説明', '説明',
'担当者種別コード',
'MUID', 'MUID',
'担当者名', '担当者名',
'施設担当_開始日', '施設担当_開始日',
@ -145,20 +139,18 @@ CSV_CHANGE_INST_NAME_COL_NO = 5
CSV_CHANGE_TA_CD_COL_NO = 6 CSV_CHANGE_TA_CD_COL_NO = 6
# 説明の列No # 説明の列No
CSV_CHANGE_EXPLAIN_COL_NO = 7 CSV_CHANGE_EXPLAIN_COL_NO = 7
# 担当者種別コード
CSV_CHANGE_EMP_CHG_TYPE_CD_COL_NO = 8
# MUIDの列No # MUIDの列No
CSV_CHANGE_EMP_CD_COL_NO = 9 CSV_CHANGE_EMP_CD_COL_NO = 8
# 担当者名の列No # 担当者名の列No
CSV_CHANGE_EMP_FULL_NAME_COL_NO = 10 CSV_CHANGE_EMP_FULL_NAME_COL_NO = 9
# 施設担当_開始日の列No # 施設担当_開始日の列No
CSV_CHANGE_INST_EMP_START_DATE_COL_NO = 11 CSV_CHANGE_INST_EMP_START_DATE_COL_NO = 10
# 施設担当_終了日の列No # 施設担当_終了日の列No
CSV_CHANGE_INST_EMP_END_DATE_COL_NO = 12 CSV_CHANGE_INST_EMP_END_DATE_COL_NO = 11
# 終了日の変更の列No # 終了日の変更の列No
CSV_CHANGE_CHANGE_END_DATE_COL_NO = 13 CSV_CHANGE_CHANGE_END_DATE_COL_NO = 12
# コメントの列No # コメントの列No
CSV_CHANGE_COMMENT = 14 CSV_CHANGE_COMMENT = 13
# CSVアップロードテーブル名(マスターメンテ) # CSVアップロードテーブル名(マスターメンテ)
CSV_REAL_TABLE_NAME = '本番テーブル' CSV_REAL_TABLE_NAME = '本番テーブル'
@ -170,7 +162,6 @@ MENTE_CSV_DOWNLOAD_EXTRACT_COLUMNS = [
'inst_cd', 'inst_cd',
'inst_name', 'inst_name',
'ta_cd', 'ta_cd',
'emp_chg_type_cd',
'emp_cd', 'emp_cd',
'emp_name_full', 'emp_name_full',
'bu_cd', 'bu_cd',
@ -187,7 +178,6 @@ MENTE_CSV_DOWNLOAD_HEADER = [
'施設コード', '施設コード',
'施設名', '施設名',
'領域コード', '領域コード',
'担当者種別コード',
'MUID', 'MUID',
'担当者名', '担当者名',
'ビジネスユニットコード', 'ビジネスユニットコード',
@ -217,6 +207,3 @@ DISPLAY_USER_STOP_DIV_SHORT = {
'03': '特定項目停止', '03': '特定項目停止',
'04': '全DM停止' '04': '全DM停止'
} }
# ログイン失敗回数上限(保守ユーザー)
LOGIN_FAIL_LIMIT = 10

View File

@ -81,17 +81,6 @@
</td> </td>
</tr> </tr>
<!-- 検索フォーム2行目 --> <!-- 検索フォーム2行目 -->
<tr>
<!-- 担当者種別コード -->
<td class="searchLabelTd">担当者種別コード:</td>
<td class="searchInputTd">
<input class="searchTextbox" type="text" name="ctrl_emp_chg_type_cd" value="{{mainte_csv_dl.emp_chg_type_cd | safe}}" maxlength='10'
onchange="formBtDisabled()"
oninput="formBtDisabled()"
>
</td>
</tr>
<!-- 検索フォーム3行目 -->
<tr> <tr>
<!-- 適用期間内 --> <!-- 適用期間内 -->
<td class="searchLabelTd">適用期間内:</td> <td class="searchLabelTd">適用期間内:</td>
@ -128,7 +117,7 @@
> >
</td> </td>
</tr> </tr>
<!-- 検索フォーム4行目 --> <!-- 検索フォーム3行目 -->
<tr> <tr>
<!-- 対象テーブル --> <!-- 対象テーブル -->
<td class="searchLabelTd">対象テーブル:</td> <td class="searchLabelTd">対象テーブル:</td>
@ -171,7 +160,7 @@
> >
</td> </td>
</tr> </tr>
<!-- 検索フォーム5行目 --> <!-- 検索フォーム4行目 -->
<tr> <tr>
<!-- 検索、クリアボタン --> <!-- 検索、クリアボタン -->
<td class="searchButtonTd" colspan="6"> <td class="searchButtonTd" colspan="6">

View File

@ -1,10 +1,6 @@
FROM python:3.12-slim-bookworm FROM python:3.9
ENV TZ="Asia/Tokyo" ENV TZ="Asia/Tokyo"
# pythonの標準出力をバッファリングしないフラグ
ENV PYTHONUNBUFFERED=1
# pythonのバイトコードを生成しないフラグ
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY Pipfile Pipfile.lock ./ COPY Pipfile Pipfile.lock ./
@ -16,7 +12,6 @@ RUN apt update && apt install -y less vim curl wget gzip unzip sudo lsb-release
# mysqlをインストール # mysqlをインストール
RUN \ RUN \
wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb && \ wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb && \
apt install -y gnupg && \
dpkg -i mysql-apt-config_0.8.29-1_all.deb < mysql_dpkg_selection.txt && \ dpkg -i mysql-apt-config_0.8.29-1_all.deb < mysql_dpkg_selection.txt && \
apt update && \ apt update && \
apt install -y mysql-client apt install -y mysql-client

View File

@ -10,7 +10,7 @@ autopep8 = "*"
flake8 = "*" flake8 = "*"
[requires] [requires]
python_version = "3.12" python_version = "3.9"
[pipenv] [pipenv]
allow_prereleases = true allow_prereleases = true

View File

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "2f7808325e11704ced6ad10c85e1d583663a03d7ccabaa9696ab1fe133a6b30c" "sha256": "cc5f54bfb2073051a26f113ceac64e12fdd0bf8faa36f1a42210cc9c921c134b"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.12" "python_version": "3.9"
}, },
"sources": [ "sources": [
{ {
@ -19,21 +19,19 @@
"develop": { "develop": {
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", "sha256:1fa8964e4618929488f4ec36795c7ff12924a68b8bf01366c094fc52f770b6e7",
"sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128" "sha256:2bb76888c5edbcafe6aabab3c47ba534f5a2c2d245c2eddced4a30c4b4946357"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==2.1.0"
"version": "==2.3.2"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:1cbc62e65536f65e6d754dfe6f1bada7f5cf392d6f5db3c2b85892466c3e7c1a", "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
"sha256:c586ffd0b41540951ae41af572e6790dbd49fc12b3aa2541685d253d9bd504bd" "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==7.0.0"
"version": "==7.1.2"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
@ -45,11 +43,11 @@
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.12.1" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@ -58,6 +56,14 @@
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==3.2.0" "version": "==3.2.0"
},
"tomli": {
"hashes": [
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
],
"markers": "python_version < '3.11'",
"version": "==2.0.1"
} }
} }
} }

View 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}.`
});
})
};

View 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"
}
}

View 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);
}
});
}
});
};

View 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"
}
}

View File

@ -1,21 +1,20 @@
# AWS公式のDockerイメージを利用 FROM python:3.9
FROM public.ecr.aws/lambda/python:3.12
ENV WORKDIR /function/
ENV TZ="Asia/Tokyo" ENV TZ="Asia/Tokyo"
WORKDIR ${WORKDIR}
# pythonの標準出力をバッファリングしないフラグ COPY Pipfile Pipfile.lock ${WORKDIR}
ENV PYTHONUNBUFFERED=1 RUN \
# pythonのバイトコードを生成しないフラグ apt update -y && \
ENV PYTHONDONTWRITEBYTECODE=1 # パッケージのセキュリティアップデートのみを適用するコマンド
apt install -y unattended-upgrades && \
# 必要なファイルをイメージにコピー unattended-upgrades && \
COPY Pipfile Pipfile.lock ./ pip install --upgrade pip wheel setuptools && \
pip install pipenv --no-cache-dir && \
# ライブラリインストール
RUN pip install pipenv --no-cache-dir && \
pipenv install --system --deploy && \ pipenv install --system --deploy && \
pip uninstall -y pipenv virtualenv-clone virtualenv pip uninstall -y pipenv virtualenv-clone virtualenv
COPY check-view-option ./ COPY check-view-option ./
# lambdaハンドラを起動 ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
CMD [ "main.handler" ] CMD [ "main.handler" ]

View File

@ -4,6 +4,7 @@ verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
awslambdaric = "*"
boto3 = "*" boto3 = "*"
pymysql = "*" pymysql = "*"
cryptography = "*" cryptography = "*"
@ -13,4 +14,4 @@ autopep8 = "*"
flake8 = "*" flake8 = "*"
[requires] [requires]
python_version = "3.12" python_version = "3.9"

View File

@ -1,11 +1,11 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "8a7a2fa969a29f51ceb9f9370d834d1f06d1bd604f719c2280bf4cdf06be3943" "sha256": "0bf055eba7a510de27e990db23f5203946ebbc02a6c678b89051dc0d1437444f"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
"python_version": "3.12" "python_version": "3.9"
}, },
"sources": [ "sources": [
{ {
@ -16,139 +16,146 @@
] ]
}, },
"default": { "default": {
"boto3": { "awslambdaric": {
"hashes": [ "hashes": [
"sha256:3faa2c328a61745f3215a63039606a6fcf55d9afe1cc76e3a5e27b9db58cdbf6", "sha256:04d4d4b63cef0e9aad3adea95a5cf3f81634bccde625f104ff025f764a3e8874",
"sha256:b998edac72f6740bd5d9d585cf3880f2dfeb4842e626b34430fd0e9623378011" "sha256:0a9922690eb7722417cbac55b913ab070c88444ab83290293debf29d5d9ca371",
"sha256:0e55a815caef1258ed7a9b0adad54e5f1b2ca63966d21342dc5da5b55dd471ef",
"sha256:2566a9db2c613fddddc22aedb45e74dbcd5c1a044da6992424680be719db80c9",
"sha256:34a3e8d27b84ccc9535086487eed50425c0db7a016bf91cf24d8d6cc853faec3",
"sha256:403109390f1a9856f8f6d5f0d5e7f2f83bdec99a62d024e433bff50eda2ed373",
"sha256:4dbd3e2262d080327a90e1ac9d087d7616e8b5be6da83be9fd3ca1b5ae575173",
"sha256:506f004ca08a2f43a898b65dad9d6dd2b2a4910ebe43dcc6682dc5ca0267c24a",
"sha256:662b95b6079b563d3e2ef4fda7bcb20e360901eae7a646425612ef2f4e5d6bdf",
"sha256:6de8d5ea0fc8cb780e060fc06a84328fda3ed329faf97606db59287814490ade",
"sha256:6f298068e2791b0ec5c420ef27cdf8aaba23486dfa5917b6c3067e30c97dde4f",
"sha256:7699c822197f98cc22c262af2368c99d69b43a73113099be52545b195c5e0064",
"sha256:7b75376d62a294e37d96507a68290dd94ce83f5b1a597c42d29242545e1ee126",
"sha256:98b16b4752f16b6a0562cfc1db2e6ce63b2a41ffa97c27e784c3ae5e8c2dc91d",
"sha256:bf57203ebeb4d718b34cd168f6b5ef497bfd2481adf848c5252faf38dccd7bf1",
"sha256:bf824aeff2cde789db1167c377573f1dbf2bf01e75eeb31651de00786ef09ed0",
"sha256:d3438bf0be646d61f8a60fb668c0c3b103963611462f35bf2db11ef50242f54f",
"sha256:d530ab882984188436f3869a2fc172086ab6b43a5f7502a86b241347a5441de3",
"sha256:e4be962e90035f362511eac65ad5c0242da15f73cfae27716de42b47f9d0a2a8",
"sha256:e5145fa63560901d7dbe26c5ee0dd5977f3783ab799fa04f50c50c207be78305",
"sha256:eb1a13c130a8a2ffc1c127a2bd581f45b9f10ec32a3892e41b5b1bdc9788b92d",
"sha256:ed798ab90f5230fe11079b269c3748bd875bc218c2ad4528ae2b4a04a0cd92b5",
"sha256:f55cf42cea67661ccea604b7774ba8cb1e467dadaf3d4c4b7f4e029faf43a46b"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==2.0.11"
"version": "==1.38.32" },
"boto3": {
"hashes": [
"sha256:7a02f44af32095946587d748ebeb39c3fa15b9d7275307ff612a6760ead47e04",
"sha256:91e6343474173e9b82f603076856e1d5b7b68f44247bdd556250857a3f16b37b"
],
"index": "pypi",
"version": "==1.34.84"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:0899a090e352cb5eeaae2c7bb52a987b469d23912c7ece86664dfb5c2e074978", "sha256:a2b309bf5594f0eb6f63f355ade79ba575ce8bf672e52e91da1a7933caa245e6",
"sha256:64ab919a5d8b74dd73eaac1f978d0e674d11ff3bbe8815c3d2982477be9a082c" "sha256:da1ae0a912e69e10daee2a34dafd6c6c106450d20b8623665feceb2d96c173eb"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==1.38.32" "version": "==1.34.84"
}, },
"cffi": { "cffi": {
"hashes": [ "hashes": [
"sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc",
"sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a",
"sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1", "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417",
"sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab",
"sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520",
"sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36",
"sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743",
"sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8",
"sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed",
"sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684",
"sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc", "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56",
"sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324",
"sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d",
"sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235",
"sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e",
"sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088",
"sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000",
"sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7",
"sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e",
"sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b", "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673",
"sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c",
"sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe",
"sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c", "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2",
"sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098",
"sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8",
"sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a",
"sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8", "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0",
"sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1", "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b",
"sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896",
"sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e",
"sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9",
"sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2",
"sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b",
"sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6",
"sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404",
"sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f",
"sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0",
"sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4",
"sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc",
"sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936",
"sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba",
"sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872",
"sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb",
"sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964", "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614",
"sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1",
"sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d",
"sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969",
"sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b",
"sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4",
"sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627",
"sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956",
"sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"
"sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd",
"sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f",
"sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5",
"sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14",
"sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d",
"sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9",
"sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7",
"sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382",
"sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a",
"sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e",
"sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a",
"sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4",
"sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99",
"sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87",
"sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"
], ],
"markers": "python_version >= '3.8'", "markers": "platform_python_implementation != 'PyPy'",
"version": "==1.17.1" "version": "==1.16.0"
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:00094838ecc7c6594171e8c8a9166124c1197b074cfca23645cee573910d76bc", "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee",
"sha256:050ce5209d5072472971e6efbfc8ec5a8f9a841de5a4db0ebd9c2e392cb81972", "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576",
"sha256:232954730c362638544758a8160c4ee1b832dc011d2c41a306ad8f7cccc5bb0b", "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d",
"sha256:25286aacb947286620a31f78f2ed1a32cded7be5d8b729ba3fb2c988457639e4", "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30",
"sha256:2f8f8f0b73b885ddd7f3d8c2b2234a7d3ba49002b0223f58cfde1bedd9563c56", "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413",
"sha256:38deed72285c7ed699864f964a3f4cf11ab3fb38e8d39cfcd96710cd2b5bb716", "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb",
"sha256:3ad69eeb92a9de9421e1f6685e85a10fbcfb75c833b42cc9bc2ba9fb00da4710", "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da",
"sha256:5555365a50efe1f486eed6ac7062c33b97ccef409f5970a0b6f205a7cfab59c8", "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4",
"sha256:555e5e2d3a53b4fabeca32835878b2818b3f23966a4efb0d566689777c5a12c8", "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd",
"sha256:57a6500d459e8035e813bd8b51b671977fb149a8c95ed814989da682314d0782", "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc",
"sha256:5833bb4355cb377ebd880457663a972cd044e7f49585aee39245c0d592904578", "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8",
"sha256:71320fbefd05454ef2d457c481ba9a5b0e540f3753354fff6f780927c25d19b0", "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1",
"sha256:7573d9eebaeceeb55285205dbbb8753ac1e962af3d9640791d12b36864065e71", "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc",
"sha256:92d5f428c1a0439b2040435a1d6bc1b26ebf0af88b093c3628913dd464d13fa1", "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e",
"sha256:97787952246a77d77934d41b62fb1b6f3581d83f71b44796a4158d93b8f5c490", "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8",
"sha256:9bb5bf55dcb69f7067d80354d0a348368da907345a2c448b0babc4215ccd3497", "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940",
"sha256:9cc80ce69032ffa528b5e16d217fa4d8d4bb7d6ba8659c1b4d74a1b0f4235fca", "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400",
"sha256:9e4253ed8f5948a3589b3caee7ad9a5bf218ffd16869c516535325fece163dcc", "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7",
"sha256:9eda14f049d7f09c2e8fb411dda17dd6b16a3c76a1de5e249188a32aeb92de19", "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16",
"sha256:a2b56de3417fd5f48773ad8e91abaa700b678dc7fe1e0c757e1ae340779acf7b", "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278",
"sha256:af3f92b1dc25621f5fad065288a44ac790c5798e986a34d393ab27d2b27fcff9", "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74",
"sha256:c5edcb90da1843df85292ef3a313513766a78fbbb83f584a5a58fb001a5a9d57", "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec",
"sha256:c824c9281cb628015bfc3c59335163d4ca0540d49de4582d6c2637312907e4b1", "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1",
"sha256:c92519d242703b675ccefd0f0562eb45e74d438e001f8ab52d628e885751fb06", "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2",
"sha256:ca932e11218bcc9ef812aa497cdf669484870ecbcf2d99b765d6c27a86000942", "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c",
"sha256:cb6ab89421bc90e0422aca911c69044c2912fc3debb19bb3c1bfe28ee3dff6ab", "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922",
"sha256:cfd84777b4b6684955ce86156cfb5e08d75e80dc2585e10d69e47f014f0a5342", "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a",
"sha256:d377dde61c5d67eb4311eace661c3efda46c62113ff56bf05e2d679e02aebb5b", "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6",
"sha256:d54ae41e6bd70ea23707843021c778f151ca258081586f0cfa31d936ae43d1b2", "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1",
"sha256:dc10ec1e9f21f33420cc05214989544727e776286c1c16697178978327b95c9c", "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e",
"sha256:ec21313dd335c51d7877baf2972569f40a4291b76a0ce51391523ae358d05899", "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac",
"sha256:ec64ee375b5aaa354b2b273c921144a660a511f9df8785e6d1c942967106438e", "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"
"sha256:ed43d396f42028c1f47b5fec012e9e12631266e3825e95c00e3cf94d472dac49",
"sha256:edd6d51869beb7f0d472e902ef231a9b7689508e83880ea16ca3311a00bf5ce7",
"sha256:f22af3c78abfbc7cbcdf2c55d23c3e022e1a462ee2481011d518c7fb9c9f3d65",
"sha256:fae1e637f527750811588e4582988932c222f8251f7b7ea93739acb624e1487f",
"sha256:fed5aaca1750e46db870874c9c273cd5182a9e9deb16f06f7bdffdb5c2bde4b9"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", "version": "==42.0.5"
"version": "==45.0.3"
}, },
"jmespath": { "jmespath": {
"hashes": [ "hashes": [
@ -168,64 +175,152 @@
}, },
"pymysql": { "pymysql": {
"hashes": [ "hashes": [
"sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96",
"sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0" "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.7'", "version": "==1.1.0"
"version": "==1.1.1"
}, },
"python-dateutil": { "python-dateutil": {
"hashes": [ "hashes": [
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.9.0.post0" "version": "==2.9.0.post0"
}, },
"s3transfer": { "s3transfer": {
"hashes": [ "hashes": [
"sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be", "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
"sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177" "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.8'",
"version": "==0.13.0" "version": "==0.10.1"
},
"simplejson": {
"hashes": [
"sha256:01f426ee9e3a2d205aa4c22c3da996b51f2de75c4199ef703258a28b304dea8c",
"sha256:03de1ec4ad734f28ca49b0a758b997d752be0d089ed30360157c4e8811999c8f",
"sha256:041dd69026284d10f035cefb4a75026d2cfcef31f31e62585eeb2b7776e7e047",
"sha256:05a668d4a93816fb8a644e90e7987aa3beeb9d2112ca50a474d41e6acb5bb88a",
"sha256:094275b1b8f003afce1167c8a674cd1ee2fd48c566632dac5d149901d5012ff8",
"sha256:097e48686e49026836ef384c7c10ca670acc023cb16a976a689c2eb6c1852df4",
"sha256:0cc9a47bf8cde85c99db5f4a919bb756e62427ade0f2e875a6ec89ae8492d486",
"sha256:0cdb5069870f7d26a34e5adc30672d0a7b26e652720530a023bb3a8d8a42e37f",
"sha256:0dcc54e7cfbd9674ec4ca181e26eaa5b038446601faeaa6c83d146ddef2f2652",
"sha256:16fbebfc38ad4285c256d2430797fd669b0437d090e985c6d443521d4303b133",
"sha256:1844d7782652f859d9648531778582d4842d80cfff8d334eb23bb8da0d22a1b0",
"sha256:2362c66d2c633925d90f2f177f05e0570d320d986130d34dff9ad6edbf7be8ac",
"sha256:29a86bc9c8a913a4e0ffab85c563a7505cdf4bd13fba05342f8314facc0b7586",
"sha256:2a6e5c0e0817fb20dbb880c83caebbd4ef39f1901f6f8e53b73a3c74de4e5172",
"sha256:2d1b47f768e1f4c1c8a9457effabed735939401e85c0ddcdf68444c88a9242e6",
"sha256:30e381471158290ccb79bd31e7bbda4c8f2cf7e1a5f6b557c1b97d6036ccd05b",
"sha256:313dfd911723dc3022fed7050a7b315d5d0681cd56eee08e44e2cbd39fd9ad81",
"sha256:32de1672f91a789cc9e1c36c406b2d75457a242d64e9e73a70b9b814ef00095e",
"sha256:340b7d085b4a5063aacb8664b1250e4a7426c16e1cc80705c548a229153af147",
"sha256:34d95ad8e27754f0d91917600d6ea273e05c82a71021f168c45be48637d9502f",
"sha256:3d549efc7e8f9a180c59462b124991b690ff25c235d5cf495c3246c66a7679cd",
"sha256:3dbfaa79b1c0efdb768392a19110f1aff793f3e8d43f57e292f46734b8affb45",
"sha256:44058bea97429cfa0d6fb1d8eb0736a77022f34a326d5bc64fd6fed8d9304571",
"sha256:46b8cc86204b51eddcf157cbaf3c44a20f24393030442af0909eeb961186cb67",
"sha256:47509775a5c41ec2a6cd17c9c00fc14965cad8e6670059663872ba5e39332f57",
"sha256:4b5df4ee48403885046c6f4fd8adc84c4ac0adec69482f22a17bd4ba52876341",
"sha256:544e5607142d66a469ecf78a3154ec0f915834dc3b8cfdb2677a78ca58319ad6",
"sha256:56d36f47bc7c7684504f0f18feb161a0b1162546b3622e45aa6155f8285180ac",
"sha256:5b217201efc007166e24e9a282007cc208a2d059350a7c5bd0b0303460ad3019",
"sha256:5c4f59dd358c3a99efa46d62dc1583be3a1c37171f5240c4cbdc2d5838870902",
"sha256:5d45ed9452a42064805143480397b586ea2ea322f4b8b69034c51181e7f38342",
"sha256:6197cfebe659ac802a686b5408494115a7062b45cdf37679c4d6a9d4f39649b7",
"sha256:65de5876e34780b43f92d9d2539de16ecc56d16f56e56e59b34adfa1cebe064f",
"sha256:676e8c182f8079851f12ae1cee2fcebe04def2da2a5703a9d747ab125af47732",
"sha256:682b202f56d9d9e1bb22eaca3e37321002223fd5ddef7189b9233e3c14079917",
"sha256:695da62e494e4689ab78fae173a78390a175b6a5ccc4292277ce0f8dba3945d5",
"sha256:6d65ea4582b47d77e9094c22eb0aeded0ebd96c1df86e988870b40c6514c6e21",
"sha256:706a7fc81ceeb321a1040d008b134056012188f95a5c31ad94fb03153b35cc84",
"sha256:7339bd6203351555c1e728acd601ba95ebce0f6041ebdb386e025f00af3f1769",
"sha256:7701a289d45fdfeb37f1d15cf638801cea439df667a613379443772a86e82936",
"sha256:7f27a079cb009ba569983061a50a9270b7e1d35f81e4eeaf0e26f8924027e550",
"sha256:827ddc3b3603f7d0421b054388da6face7871d800c4b3bbedeedc8778e4085ea",
"sha256:8ccc982197982cdda19e3e5ba4ef7f6ad6bed3eb39bb423bfbf7fa2cd29488ab",
"sha256:8f381747c2edebe3c750a571e55103bfcc33b2707a9b91ae033ab9ba718d976a",
"sha256:93ba80fbf959b5852554f23201a5f4b30885930c303546ffa883859a435ea3cf",
"sha256:9a50a9da1cf93e35f26c4ddee162abf3184a340339ec2d4001c34607b87e71b4",
"sha256:a1163bfe5d043c20adeb5c4c8e89dd1dd39b375c8ca6f1c1e35ec537ad7a12e7",
"sha256:a2285609b4edbf9957440642493788ebef6583042b3fb96217c2e71f29bc6d80",
"sha256:a255d30cda6334ba780eb40a56e8134efd3453948b995d3966e45212e34bf018",
"sha256:a3bba99178f1b25878752a8bc6da2f93fbae754ebd4914d2ac4b869b9fb24102",
"sha256:a56005332d70b8d02d476d4a85818b27b01e51dac1a21d5c1a1d8a5df2efb4a6",
"sha256:a89d7fe994b115f0a792e6673f387af3db812a1760d594abad51e0ea11d3e470",
"sha256:a8ac155e3fd3b54a63040df024e57e62c130b15a2fc66eff3c2a946f42beed52",
"sha256:ab5941e1fd509fc151258477ef4b663fe14c94f8faf3581827bf4b02080fd4ba",
"sha256:ab64f087c5863ac621b42e227e5a43bd9b28de581afe7be12ad96562b9be8203",
"sha256:ad37f25fd8dfbed80815c3281b82a165be2a74e663856b9a50099d18789987bc",
"sha256:b17026f3f349a6e87818cd3531e3bbb5cc78a6f4b2b6718f574a8e0512d71e08",
"sha256:b43d3c2e204d709af955bdb904ae127fe137363ace87fbf7dc8fe6017f7f8449",
"sha256:b482d1fdd8f860e743c7de8cd6dfe54fb9fe8cd6ccba29e2966912ac89e17b2f",
"sha256:b6c6cfc492710d8f0303705fa1ff7bb3d6a145f523384e45a6f3b13ada37021f",
"sha256:b9893852c559998f667e6434d2c2474518d4cdfd1b9cec8e57b3c9d577ba55c1",
"sha256:bd694c465cc61fa8e599355e535b6eb561279834d9883aeef08d0e86c44c300c",
"sha256:c0444423129df448788edc66a129bc7560ad7d6a661d74f0900959c0b44349a1",
"sha256:c37b092d29741096c4723f48924a80b1d3de62ca1de254ce88178fa083dd520c",
"sha256:ced906b172bfad62736a27cfafcb6e24bc9938533b0529ff8150f7926fe35b54",
"sha256:d0d3b9f7cee233368d92c89746dde74313abafaa3ec1f0c06a3f4f164dc27bcc",
"sha256:d5f67bffa6fc68e391b2250e1feb43d534ded64a7b918eb89cf7e3e679759d94",
"sha256:d9f0dfde448611f4f818da05f9b544a78f29355dc39151b0dad8e7c65c513e4f",
"sha256:da6dc0cb00ef1e1a8daf285074ca8b2bb89591170c42ceab0c37bcdb9adc802c",
"sha256:dc74a9ef4d61e18ee6f1886b6ef1fe285b1f432885288afacfb7402f7d469448",
"sha256:deb71e6166e4f1264174d78b5b88abd52b14c6649e6eabaf9cf93cb1c7362850",
"sha256:e042ae053e05fe193514d51d6b0f0243729961901e9a75f8b596bfaf69522c52",
"sha256:e2f87a483c4ab0bb2a9adc9ca09173e7f7cf3696e4fa67bd45a6b33181e57921",
"sha256:e2fa1ee5ca34ab2ecfbe3f7a7e952a1ecaebb5b4818f002b5b146324912ac3d5",
"sha256:e7d3f7cd57ce0c6a5bb8133f8ed5c3d1be0473a88b7d91a300626298f12d0999",
"sha256:edb334cab35dcd90eb563fdacb085f10e5dd0b1acb57fa43f8933308b42a8f88",
"sha256:efae49d0148ec68b6e012f1b9e19bd530f4dced378ba919e3e906ae2b829cc31",
"sha256:f1085cadec0f7e76377951d7a87744628c90ac6cc634fc97eecce0c4d41ec563",
"sha256:f15f56b3119fb71fa57eb4613bcd87eb7df6c2f3547de7d341853d3e50cef97e",
"sha256:f1b425a857ce52e651739314e4118fc68bd702ef983148b8fd5cb6f68bb6a020",
"sha256:f31e126204ec38f92dee119af87cf881044ef7dea6f7477ef774ed3d84199c24",
"sha256:f5e0a03e533313eee9437ccc6c4eab47369f17bc919b57df4a20ccd8bc85d8fd",
"sha256:f85d87986ca375b8305b5c4f166783b8db383a6469e8b99b8dba22878388f234",
"sha256:fa6fe8fa94a831886ee164ac03514f361e1387a62a1b9da32fde5c0c1f27fa8d",
"sha256:fb0f8b35c11fd8e4b924f974d331b20fa54555282451db7f2a3b24bd2d33cc11"
],
"markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==3.18.4"
}, },
"six": { "six": {
"hashes": [ "hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.17.0" "version": "==1.16.0"
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07",
"sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32" "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "markers": "python_version < '3.10'",
"version": "==1.26.20" "version": "==1.26.18"
} }
}, },
"develop": { "develop": {
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", "sha256:1fa8964e4618929488f4ec36795c7ff12924a68b8bf01366c094fc52f770b6e7",
"sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128" "sha256:2bb76888c5edbcafe6aabab3c47ba534f5a2c2d245c2eddced4a30c4b4946357"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "version": "==2.1.0"
"version": "==2.3.2"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:1cbc62e65536f65e6d754dfe6f1bada7f5cf392d6f5db3c2b85892466c3e7c1a", "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
"sha256:c586ffd0b41540951ae41af572e6790dbd49fc12b3aa2541685d253d9bd504bd" "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "version": "==7.0.0"
"version": "==7.1.2"
}, },
"mccabe": { "mccabe": {
"hashes": [ "hashes": [
@ -237,11 +332,11 @@
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521" "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.12.1" "version": "==2.11.1"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@ -250,6 +345,14 @@
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==3.2.0" "version": "==3.2.0"
},
"tomli": {
"hashes": [
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
],
"markers": "python_version < '3.11'",
"version": "==2.0.1"
} }
} }
} }

View File

@ -6,11 +6,12 @@ from constants import AWS_RESOURCE_S3, S3_RESPONSE_BODY, UTF8
class S3Resource: class S3Resource:
def __init__(self, bucket_name: str) -> None: def __init__(self, bucket_name: str) -> None:
self.__s3_client = boto3.client(AWS_RESOURCE_S3) self.__s3_resource = boto3.resource(AWS_RESOURCE_S3)
self.__s3_bucket = bucket_name self.__s3_bucket = self.__s3_resource.Bucket(bucket_name)
def get_object(self, object_key: str): def get_object(self, object_key: str):
response = self.__s3_client.get_object(Bucket=self.__s3_bucket, Key=object_key) s3_object = self.__s3_bucket.Object(object_key)
response = s3_object.get()
return response[S3_RESPONSE_BODY].read().decode(UTF8) return response[S3_RESPONSE_BODY].read().decode(UTF8)

View File

@ -1,329 +0,0 @@
import csv
import datetime
import io
import json
import logging
import os
import re
from zoneinfo import ZoneInfo
import boto3
from dateutil.relativedelta import relativedelta
# 環境変数
CONFIG_BUCKET_NAME = os.environ["CONFIG_BUCKET_NAME"]
MBJ_NOTICE_TOPIC = os.environ["MBJ_NOTICE_TOPIC"]
PROCESSED_MESSAGE_DYNAMODB_TABLE_NAME = os.environ["PROCESSED_MESSAGE_DYNAMODB_TABLE_NAME"]
PROCESSED_MESSAGE_EXPIRES_PERIOD = int(os.environ["PROCESSED_MESSAGE_EXPIRES_PERIOD"])
LOG_LEVEL = os.environ["LOG_LEVEL"]
TZ = os.environ["TZ"]
# 定数
ROW_COMMENT_SYMBOL = '#'
INDEX_REGEX = 0
INDEX_DATA_NAME = 1
INDEX_ROW_COMMENT_SYMBOL = 0
INDEX_SPLIT_NUM = 1
INDEX_LAST = -1
# メール本文に出力する不足ファイル名一覧のインデント
MAIL_INDENT = '  '
# AWS操作クライアント
s3_client = boto3.client('s3')
sns_client = boto3.client('sns')
dynamodb_client = boto3.client('dynamodb')
# logger設定
def log_datetime_convert_tz(*arg):
"""ログに出力するタイムスタンプのロケールを変更するJST指定"""
return datetime.datetime.now(ZoneInfo(TZ)).timetuple()
logger = logging.getLogger()
formatter = logging.Formatter(
'[%(levelname)s]\t%(asctime)s\t%(message)s\n',
'%Y-%m-%d %H:%M:%S'
)
formatter.converter = log_datetime_convert_tz
for handler in logger.handlers:
handler.setFormatter(formatter)
level = logging.getLevelName(LOG_LEVEL)
if not isinstance(level, int):
level = logging.INFO
logger.setLevel(level)
def is_duplicate_message(message_id: str) -> bool:
"""DynamoDBテーブルに処理済みのSQSメッセージIdが存在するかどうかを調査する
Args:
message_id (str): SQSメッセージId
Returns:
bool: 存在する場合はTrue
"""
return dynamodb_client.query(
TableName=PROCESSED_MESSAGE_DYNAMODB_TABLE_NAME,
Select='COUNT',
KeyConditionExpression='message_id = :message_id',
ExpressionAttributeValues={
':message_id': {'S': message_id}
}
)["Count"] != 0
def put_success_messages_to_dynamo_db(batch_success_items: list[str]) -> bool:
"""処理済みのSQSメッセージIdをDynamoDBにPushする
Args:
batch_success_items (list[str]): SQSメッセージIdのリスト
Returns:
bool: 登録成功の場合True
"""
# レコードの有効期限を算出
now = datetime.datetime.now(ZoneInfo(TZ))
record_expiration_datetime = now + \
datetime.timedelta(minutes=PROCESSED_MESSAGE_EXPIRES_PERIOD)
record_expiration_time = record_expiration_datetime.timestamp()
for message_id in batch_success_items:
dynamodb_client.put_item(
TableName=PROCESSED_MESSAGE_DYNAMODB_TABLE_NAME,
Item={
'message_id': {'S': message_id},
'record_expiration_time': {'N': f'{record_expiration_time}'}
}
)
return True
def substitute_mail_template(mail_template: str, mail_msg: str) -> str:
"""メールテンプレートのプレースホルダーを置き換える
Args:
mail_template (str): 置き換え前のメールテンプレート
mail_msg (str): メールテンプレートのプレースホルダーを置き換える文言(ファイル一覧)
Returns:
str: 置き換え後のメール本文
"""
substitute_dict = {
"notice_file_names": mail_msg
}
mail_str = mail_template.format_map(substitute_dict)
return mail_str
def make_failure_item_on_error(message_id: str) -> dict[str, str]:
"""Report batch item failuresによる処理に失敗したメッセージの判別のためのレスポンスを作成する
@see <https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting>
Args:
message_id (str): SQSメッセージId
Returns:
dict[str, str]: Report batch item failuresで失敗したSQSメッセージを判別するための辞書オブジェクト
"""
return {"itemIdentifier": message_id}
def daily_data_unreceive_check(records: list, execute_date: str) -> tuple[list[dict[str, str]], list[str]]:
"""日次データ未受領チェック
Args:
records (list): SQS Eventのレコードリスト
execute_date (str): 処理稼働年月日
Returns:
tuple[list[dict[str, str]], list[str]]: 失敗メッセージIdのリスト, 成功メッセージIdのリスト
"""
batch_failed_items = []
batch_success_items = []
for record in records:
# メール挿入用文言を格納するためのメモリを保持する
mail_message = ''
try:
# SQSパラメータをJSONシリアライズし、Pythonの辞書オブジェクト(イベントパラメータ)を取得する。
event_parameter = json.loads(record['body'])
receive_date = execute_date.strftime('%Y/%m/%d')
try:
# 1.SQSメッセージIDを取得する
message_id = record["messageId"]
# 2.DynamoDBテーブルからレコードを取得し、処理済みメッセージかどうかを判別する
if is_duplicate_message(message_id):
logger.info(f'I-02-02 受信したメッセージは既に処理済みのため、処理をスキップします。メッセージID: {message_id} データソース バケットディレクトリ: {event_parameter["check_bucket_name"]}/{event_parameter["check_folder_prefix"]}/')
continue
except Exception as e:
logger.exception(f"E-02-01 メッセージ重複チェック処理に失敗しました エラー内容:{e}")
batch_failed_items.append(make_failure_item_on_error(message_id))
continue
# ③ 設定ファイル[受領チェック対象ファイルリスト]を読み込む
try:
logger.info('I-03-01 ' +'受領チェック対象ファイルリスト読込 読込元:' + f'{CONFIG_BUCKET_NAME}/{event_parameter["check_target_file_list"]}')
check_target_file_list_response = s3_client.get_object(
Bucket=CONFIG_BUCKET_NAME,
Key=f'{event_parameter["check_target_file_list"]}'
)
logger.info('I-03-02 受領チェック対象ファイルリストを読み込みました')
except Exception as e:
logger.exception(f"E-03-01 受領チェック対象ファイルリストの読み込みに失敗しました エラー内容:{e} 読込元:{CONFIG_BUCKET_NAME}/{event_parameter["check_target_file_list"]}")
batch_failed_items.append(make_failure_item_on_error(message_id))
continue
# ④ 受領チェック処理を行う
logger.info(f'I-04-01 日次データ受領チェック ({event_parameter['data_source_name']}) 処理開始')
object_prefix = f'{event_parameter["check_folder_prefix"]}/{receive_date}/'
# 1.日次データバックアップ保管バケットの処理稼働月に該当するサブフォルダにあるファイル一覧を取得する
logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{event_parameter['check_bucket_name']}/{object_prefix}')
receive_file_list_response = s3_client.list_objects_v2(Bucket=event_parameter['check_bucket_name'], Prefix=object_prefix)
receive_file_list = []
for content in receive_file_list_response.get('Contents', []):
# オブジェクトのキーからファイル名を切り出してリストに追加
obj_key = content['Key'].rsplit('/', INDEX_SPLIT_NUM)
receive_file_list.append(obj_key[INDEX_LAST])
# 2.I/Fファイルチェック処理
logger.info(f'I-04-03 日次受信データ({event_parameter['data_source_name']}) 未受領チェック処理開始')
check_target_file_name_body = io.TextIOWrapper(io.BytesIO(
check_target_file_list_response["Body"].read()), encoding='utf-8')
match_count = 0
row_count = 0
for tsv_row in csv.reader(check_target_file_name_body, delimiter='\t'):
# 「④1.」で取得したリストが「③」で読み込んだファイル内に存在するか確認する
is_file_not_exists = True
for file_name in receive_file_list:
match_result = re.fullmatch(tsv_row[INDEX_REGEX], file_name)
# 「③」で読み込んだファイルに記載されている全てが「④1.」で取得したリストに存在した場合
if match_result is not None:
is_file_not_exists = False
logger.info(f'I-04-04 I/Fファイルの受領を確認しました ファイル名{file_name}')
match_count += 1
if is_file_not_exists:
logger.info(f'I-04-06 I/Fファイルに不足があります ファイル名{tsv_row[INDEX_DATA_NAME]}')
mail_message += f'{MAIL_INDENT}{tsv_row[INDEX_DATA_NAME]}\n'
row_count += 1
if row_count == match_count:
logger.info('I-04-05 I/Fファイルは全て受領していることを確認しました')
# ⑤ 「①」でメモリ保持しているメール挿入用文言に出力内容が存在するか確認する
logger.info('I-05-01 メール送信処理開始')
if len(mail_message) == 0:
logger.info(
f'I-05-09 {execute_date} {event_parameter["data_source_name"]}データI/Fファイルに不足が無いため、メール送信処理をスキップします')
batch_success_items.append(message_id)
continue
# 1.存在した場合
logger.info(f'I-05-02 {execute_date} {event_parameter["data_source_name"]} データI/Fファイルに不足があるため、メール送信処理を開始します')
try:
logger.info('I-05-03 ' +f'通知メール(タイトル)テンプレートファイル読込 読込元:{CONFIG_BUCKET_NAME}/{event_parameter["notice_mail_title_template"]}')
mail_title_response = s3_client.get_object(
Bucket=CONFIG_BUCKET_NAME,
Key=f'{event_parameter["notice_mail_title_template"]}'
)
mail_title_template = (mail_title_response['Body'].read().decode('utf-8'))
# 改行を取り除く
mail_title_without_line_break = mail_title_template.splitlines()[0]
logger.info('I-05-04 通知メール(タイトル)テンプレートファイルを読み込みました')
except Exception as e:
logger.exception(
f'E-05-01 通知メール(タイトル)テンプレートファイルの読み込みに失敗しました エラー内容:{e} 読込元:{CONFIG_BUCKET_NAME}/{event_parameter["notice_mail_title_template"]}')
batch_failed_items.append(
make_failure_item_on_error(message_id))
continue
try:
logger.info('I-05-05 ' +f'通知メール(本文)テンプレートファイル読込 読込元:{CONFIG_BUCKET_NAME}/{event_parameter["notice_mail_body_template"]}')
mail_body_template_response = s3_client.get_object(
Bucket=CONFIG_BUCKET_NAME,
Key=f'{event_parameter["notice_mail_body_template"]}'
)
mail_body_template = (mail_body_template_response['Body'].read().decode('utf-8'))
# メール本文内のプレースホルダーを置き換える
mail_body = substitute_mail_template(mail_body_template, mail_message)
logger.info('I-05-06 通知メール(本文)テンプレートファイルを読み込みました')
except Exception as e:
logger.exception(f'E-05-02 通知メール(本文)テンプレートファイルの読み込みに失敗しました エラー内容:{e} 読込元:{CONFIG_BUCKET_NAME}/{event_parameter["notice_mail_body_template"]}')
batch_failed_items.append(make_failure_item_on_error(message_id))
continue
logger.info(f'I-05-07 メール送信指示をします 送信先トピック:{MBJ_NOTICE_TOPIC}')
params = {
'TopicArn': MBJ_NOTICE_TOPIC,
'Subject': mail_title_without_line_break,
'Message': mail_body
}
sns_client.publish(**params)
logger.info('I-05-08 メール送信指示をしました')
batch_success_items.append(message_id)
except Exception as e:
logger.exception(f'E-99 想定外のエラーが発生しました エラー内容:{e}')
batch_failed_items.append(make_failure_item_on_error(message_id))
continue
return batch_failed_items, batch_success_items
def lambda_handler(event, context):
try:
# ① 処理開始ログを出力する
logger.info('I-01-01 処理開始 日次データ受領チェック処理')
# 処理稼働年月を取得しメモリに保持する
execute_date = datetime.date.today()
# 処理成功メッセージIDリストをメモリに保持する初期値空のリスト
batch_success_items = []
# 処理失敗メッセージIDリストをメモリに保持する初期値空のリスト
batch_failed_items = []
# ② SQSメッセージ重複排除処理を行う
logger.info('I-02-01 メッセージ処理開始')
batch_failed_items, batch_success_items = daily_data_unreceive_check(event["Records"], execute_date)
logger.info('I-06-01 すべてのメッセージの処理完了')
# ⑦ メッセージを処理済として、以下のDynamoDBテーブルに記録する
put_success_messages_to_dynamo_db(batch_success_items)
logger.info('I-07-01 処理済みメッセージIDの記録完了')
logger.info('I-07-02 処理終了 日次データ受領チェック処理')
except Exception as e:
logger.exception(f'E-99 想定外のエラーが発生しました エラー内容:{e}')
raise e
return batch_failed_items
# 動作確認用のコード
# if __name__ == '__main__':
# lambda_handler({
# "Records": [
# {
# "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
# "receiptHandle": "MessageReceiptHandle",
# "body": "{\"data_source_name\":\"data_source_name\",\"check_bucket_name\":\"check_bucket_name\",\"check_folder_prefix\":\"check_folder_prefix\",\"check_target_file_list\":\"check_target_file_list\",\"notice_mail_title_template\":\"notice_mail_title_template\",\"notice_mail_body_template\":\"notice_mail_body_template\"\r\n}",
# "attributes": {
# "ApproximateReceiveCount": "1",
# "SentTimestamp": "1523232000000",
# "SenderId": "123456789012",
# "ApproximateFirstReceiveTimestamp": "1523232000001"
# },
# "messageAttributes": {},
# "md5OfBody": "{{{md5_of_body}}}",
# "eventSource": "aws:sqs",
# "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue",
# "awsRegion": "us-east-1"
# }
# ]
# }, {})

View File

@ -8,7 +8,6 @@ import boto3
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
def lambda_handler(event, context): def lambda_handler(event, context):
awslogs_dict = event.get('awslogs') awslogs_dict = event.get('awslogs')
base64_data = awslogs_dict.get('data') base64_data = awslogs_dict.get('data')
@ -19,12 +18,8 @@ def lambda_handler(event, context):
log_event_str = gzip.GzipFile(fileobj=BytesIO(decoded_gzip_data)).read() log_event_str = gzip.GzipFile(fileobj=BytesIO(decoded_gzip_data)).read()
log_event = json.loads(log_event_str) log_event = json.loads(log_event_str)
# SNSのSubjectパラメータは100文字までという制限があるため、100文字に切り出す(切り捨てた分は「...」に変換)
subject = f'Detect Error(or Warning) in {log_event.get("logGroup")}'
subject = subject[:97] + '...' if len(subject) > 100 else subject
publish_message = { publish_message = {
'Subject': subject, 'Subject': f'Detect Error(or Warning) in {log_event.get("logGroup")}',
'Message': '\n'.join([log.get('message') for log in log_event.get('logEvents')]), 'Message': '\n'.join([log.get('message') for log in log_event.get('logEvents')]),
'TopicArn': os.environ.get('SNS_TOPIC_ARN') 'TopicArn': os.environ.get('SNS_TOPIC_ARN')
} }

View File

@ -1,26 +1,17 @@
FROM python:3.12-slim-bookworm FROM python:3.9
ENV TZ="Asia/Tokyo" ENV TZ="Asia/Tokyo"
# pythonの標準出力をバッファリングしないフラグ
ENV PYTHONUNBUFFERED=1
# pythonのバイトコードを生成しないフラグ
ENV PYTHONDONTWRITEBYTECODE=1
# 必要なファイルをイメージにコピー
WORKDIR /function WORKDIR /function
COPY Pipfile Pipfile.lock ./ COPY requirements.txt ./
RUN \
# ライブラリインストール apt update -y && \
RUN apt update -y && \ # パッケージのセキュリティアップデートのみを適用するコマンド
apt-get -y install gnupg2 && \ apt install -y unattended-upgrades && \
pip install pipenv --no-cache-dir && \ unattended-upgrades && \
pipenv install --system --deploy && \ pip install --upgrade pip wheel setuptools && \
pip uninstall -y pipenv virtualenv-clone virtualenv pip install --no-cache-dir -r requirements.txt
COPY datadecrypt ./ COPY datadecrypt ./
# エントリーポイントの設定
ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ] ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
# lambdaハンドラを起動
CMD [ "main.handler" ] CMD [ "main.handler" ]

View File

@ -1,16 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
boto3 = "*"
python-gnupg = "*"
awslambdaric = "*"
[dev-packages]
autopep8 = "*"
flake8 = "*"
[requires]
python_version = "3.12"

View File

@ -1,281 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "1a02067c1f004e5d31364e9631ef0cefbe083f9c667e82317ebda4bda9b2133e"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.12"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"awslambdaric": {
"hashes": [
"sha256:09ba762169869c576f8842d2b08fa6e30254494eabe533eb77efef0e38af33fa",
"sha256:0b30fd0b2e62c46c268eaf316c3bc77ba6d3900caea3c81cdf211952062e118f",
"sha256:134b5132803094ce0488f2b3e071745f09779c583371e84bc5979c21a5bac46a",
"sha256:1c1fd30570b9a2c5cc4ccd2151c883312c5eef2dbf759c8e9d29c18cec6de2e8",
"sha256:2cd110915f17967bfc39079c37efd7f9ca65eedb049c79f5203f02dcb3a514fc",
"sha256:329bd2e09d6a8257b9a7ff386d9956783ec905bba4c00ea2f841fbc89246910e",
"sha256:37159c9f67d5cced4dcf72963d29dcac48b214f601931d15b78f58a1336c9dc5",
"sha256:4972127ef34729c44c9567148e68a4eacc283d685400f9d08bf51138ac4ee3d5",
"sha256:537e4986f723cb981af01d031743c9ae09b9ddc497d2582a548da0d696c81809",
"sha256:6c8ecbcf05cf02f1bd263a0831b1acf3c29cd9296cb72e74067de71185f6c118",
"sha256:755db7118d1ed900a675a2608ea9c48c463949ede5cc91648c542a5ec89df4ed",
"sha256:7b7e44922dc4f22cdc9462d5eb41b43f8edfd4ec091f26b91bcbd9eec9c0e368",
"sha256:84855b22f2dfb68f1180ea9acbd18e5b636aed02d45e88d7bdfbf10551ba5658",
"sha256:889b4bb6e9d88aab26d67cce7f9212aafa1f53c64eca2dc83cdf42a79eb3e6ec",
"sha256:9bb003f14f3754a3d6912e3a478cf3a306b84febdc26b612fe23c1143a89f0fd",
"sha256:a5860d96e08cc4bab5bd4d7a2cd5eeb10ea17d0269fe4c1b7c57ac8d06abbf70",
"sha256:a7066867f704675c65da522ee28174d674b847f7df9479eb7f60cbba2ab85e09",
"sha256:a9d0d3de5a3fd9b2d8496b07e30b471b74d6a7839c878bef89419db0dae8795e",
"sha256:ad2ff7352517b590ca5748f75b9b9df906b111139753f35bcb069f25c14d3c94",
"sha256:dc30e9b674828b4d00f703f7774e1bc6e78f8cc1b7fd577e583d66e1c62734ea",
"sha256:fbe854813e5a1bac7d68cc05827dbcf5eb7fd2158ec2e6972d5643d00c3f3f61"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==3.1.1"
},
"boto3": {
"hashes": [
"sha256:3faa2c328a61745f3215a63039606a6fcf55d9afe1cc76e3a5e27b9db58cdbf6",
"sha256:b998edac72f6740bd5d9d585cf3880f2dfeb4842e626b34430fd0e9623378011"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==1.38.32"
},
"botocore": {
"hashes": [
"sha256:0899a090e352cb5eeaae2c7bb52a987b469d23912c7ece86664dfb5c2e074978",
"sha256:64ab919a5d8b74dd73eaac1f978d0e674d11ff3bbe8815c3d2982477be9a082c"
],
"markers": "python_version >= '3.9'",
"version": "==1.38.32"
},
"jmespath": {
"hashes": [
"sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980",
"sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"
],
"markers": "python_version >= '3.7'",
"version": "==1.0.1"
},
"python-dateutil": {
"hashes": [
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.9.0.post0"
},
"python-gnupg": {
"hashes": [
"sha256:40ce25cde9df29af91fe931ce9df3ce544e14a37f62b13ca878c897217b2de6c",
"sha256:f2fdb5fb29615c77c2743e1cb3d9314353a6e87b10c37d238d91ae1c6feae086"
],
"index": "pypi",
"version": "==0.5.4"
},
"s3transfer": {
"hashes": [
"sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be",
"sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177"
],
"markers": "python_version >= '3.9'",
"version": "==0.13.0"
},
"simplejson": {
"hashes": [
"sha256:000602141d0bddfcff60ea6a6e97d5e10c9db6b17fd2d6c66199fa481b6214bb",
"sha256:03d7a426e416fe0d3337115f04164cd9427eb4256e843a6b8751cacf70abc832",
"sha256:03db8cb64154189a92a7786209f24e391644f3a3fa335658be2df2af1960b8d8",
"sha256:03ec618ed65caab48e81e3ed29586236a8e57daef792f1f3bb59504a7e98cd10",
"sha256:0821871404a537fd0e22eba240c74c0467c28af6cc435903eca394cfc74a0497",
"sha256:1190f9a3ce644fd50ec277ac4a98c0517f532cfebdcc4bd975c0979a9f05e1fb",
"sha256:15c7de4c88ab2fbcb8781a3b982ef883696736134e20b1210bca43fb42ff1acf",
"sha256:1b9fd15853b90aec3b1739f4471efbf1ac05066a2c7041bf8db821bb73cd2ddc",
"sha256:1bd6bfe5678d73fbd5328eea6a35216503796428fc47f1237432522febaf3a0c",
"sha256:272cc767826e924a6bd369ea3dbf18e166ded29059c7a4d64d21a9a22424b5b5",
"sha256:299b1007b8101d50d95bc0db1bf5c38dc372e85b504cf77f596462083ee77e3f",
"sha256:2b6436c48e64378fa844d8c9e58a5ed0352bbcfd4028369a9b46679b7ab79d2d",
"sha256:2e671dd62051129185d3a9a92c60101f56cbc174854a1a3dfb69114ebd9e1699",
"sha256:325b8c107253d3217e89d7b50c71015b5b31e2433e6c5bf38967b2f80630a8ca",
"sha256:339f407373325a36b7fd744b688ba5bae0666b5d340ec6d98aebc3014bf3d8ea",
"sha256:3466d2839fdc83e1af42e07b90bc8ff361c4e8796cd66722a40ba14e458faddd",
"sha256:391345b4157cc4e120027e013bd35c45e2c191e2bf48b8913af488cdc3b9243c",
"sha256:3c4f0a61cdc05550782ca4a2cdb311ea196c2e6be6b24a09bf71360ca8c3ca9b",
"sha256:3d7310172d5340febd258cb147f46aae30ad57c445f4d7e1ae8461c10aaf43b0",
"sha256:3e7963197d958fcf9e98b212b80977d56c022384621ff463d98afc3b6b1ce7e8",
"sha256:455a882ff3f97d810709f7b620007d4e0aca8da71d06fc5c18ba11daf1c4df49",
"sha256:463f1fca8fbf23d088e5850fdd0dd4d5faea8900a9f9680270bd98fd649814ca",
"sha256:4762e05577955312a4c6802f58dd02e040cc79ae59cda510aa1564d84449c102",
"sha256:489c3a43116082bad56795215786313832ba3991cca1f55838e52a553f451ab6",
"sha256:49d059b8363327eee3c94799dd96782314b2dbd7bcc293b4ad48db69d6f4d362",
"sha256:4a586ce4f78cec11f22fe55c5bee0f067e803aab9bad3441afe2181693b5ebb5",
"sha256:4a8e197e4cf6d42c2c57e7c52cd7c1e7b3e37c5911df1314fb393320131e2101",
"sha256:4a92e948bad8df7fa900ba2ba0667a98303f3db206cbaac574935c332838208e",
"sha256:51b41f284d603c4380732d7d619f8b34bd04bc4aa0ed0ed5f4ffd0539b14da44",
"sha256:5c0de368f3052a59a1acf21f8b2dd28686a9e4eba2da7efae7ed9554cb31e7bc",
"sha256:627d4486a1ea7edf1f66bb044ace1ce6b4c1698acd1b05353c97ba4864ea2e17",
"sha256:652d8eecbb9a3b6461b21ec7cf11fd0acbab144e45e600c817ecf18e4580b99e",
"sha256:69dd28d4ce38390ea4aaf212902712c0fd1093dc4c1ff67e09687c3c3e15a749",
"sha256:6a6dd11ee282937ad749da6f3b8d87952ad585b26e5edfa10da3ae2536c73078",
"sha256:6bd09c8c75666e7f62a33d2f1fb57f81da1fcbb19a9fe7d7910b5756e1dd6048",
"sha256:6c21f5c026ca633cfffcb6bc1fac2e99f65cb2b24657d3bef21aed9916cc3bbf",
"sha256:6d4f320c33277a5b715db5bf5b10dae10c19076bd6d66c2843e04bd12d1f1ea5",
"sha256:6dd3a1d5aca87bf947f3339b0f8e8e329f1badf548bdbff37fac63c17936da8e",
"sha256:6e18345c8dda5d699be8166b61f9d80aaee4545b709f1363f60813dc032dac53",
"sha256:6e6697a3067d281f01de0fe96fc7cba4ea870d96d7deb7bfcf85186d74456503",
"sha256:71b75d448fd0ceb2e7c90e72bb82c41f8462550d48529980bc0bab1d2495bfbb",
"sha256:71e849e7ceb2178344998cbe5ade101f1b329460243c79c27fbfc51c0447a7c3",
"sha256:74a1608f9e6e8c27a4008d70a54270868306d80ed48c9df7872f9f4b8ac87808",
"sha256:7551682b60bba3a9e2780742e101cf0a64250e76de7d09b1c4b0c8a7c7cc6834",
"sha256:76461ec929282dde4a08061071a47281ad939d0202dc4e63cdd135844e162fbc",
"sha256:78520f04b7548a5e476b5396c0847e066f1e0a4c0c5e920da1ad65e95f410b11",
"sha256:7ceed598e4bacbf5133fe7a418f7991bb2df0683f3ac11fbf9e36a2bc7aa4b85",
"sha256:7e9d73f46119240e4f4f07868241749d67d09873f40cb968d639aa9ccc488b86",
"sha256:7eaae2b88eb5da53caaffdfa50e2e12022553949b88c0df4f9a9663609373f72",
"sha256:87fc623d457173a0213bc9ca4e346b83c9d443f63ed5cca847fb0cacea3cfc95",
"sha256:884e6183d16b725e113b83a6fc0230152ab6627d4d36cb05c89c2c5bccfa7bc6",
"sha256:88a7baa8211089b9e58d78fbc1b0b322103f3f3d459ff16f03a36cece0d0fcf0",
"sha256:896a6c04d7861d507d800da7642479c3547060bf97419d9ef73d98ced8258766",
"sha256:8a6c1bbac39fa4a79f83cbf1df6ccd8ff7069582a9fd8db1e52cea073bc2c697",
"sha256:8bb98fdf318c05aefd08a92583bd6ee148e93c6756fb1befb7b2d5f27824be78",
"sha256:8c09948f1a486a89251ee3a67c9f8c969b379f6ffff1a6064b41fea3bce0a112",
"sha256:8d23b7f8d6b72319d6d55a0261089ff621ce87e54731c2d3de6a9bf7be5c028c",
"sha256:90b573693d1526bed576f6817e2a492eaaef68f088b57d7a9e83d122bbb49e51",
"sha256:9a74e70818818981294b8e6956ce3496c5e1bd4726ac864fae473197671f7b85",
"sha256:9c079606f461a6e950099167e21e13985147c8a24be8eea66c9ad68f73fad744",
"sha256:9daf8cdc7ee8a9e9f7a3b313ba0a003391857e90d0e82fbcd4d614aa05cb7c3b",
"sha256:9e8eacf6a3491bf76ea91a8d46726368a6be0eb94993f60b8583550baae9439e",
"sha256:9faceb68fba27ef17eda306e4cd97a7b4b14fdadca5fbb15790ba8b26ebeec0c",
"sha256:a2cc4f6486f9f515b62f5831ff1888886619b84fc837de68f26d919ba7bbdcbc",
"sha256:a3c2df555ee4016148fa192e2b9cd9e60bc1d40769366134882685e90aee2a1e",
"sha256:a7e15b716d09f318c8cda3e20f82fae81684ce3d3acd1d7770fa3007df1769de",
"sha256:a8011f1dd1d676befcd4d675ebdbfdbbefd3bf350052b956ba8c699fca7d8cef",
"sha256:ab19c2da8c043607bde4d4ef3a6b633e668a7d2e3d56f40a476a74c5ea71949f",
"sha256:ab980fcc446ab87ea0879edad41a5c28f2d86020014eb035cf5161e8de4474c6",
"sha256:ae6e637dc24f8fee332ed23dd070e81394138e42cd4fd9d0923e5045ba122e27",
"sha256:ae81e482476eaa088ef9d0120ae5345de924f23962c0c1e20abbdff597631f87",
"sha256:af8377a8af78226e82e3a4349efdde59ffa421ae88be67e18cef915e4023a595",
"sha256:b122a19b552b212fc3b5b96fc5ce92333d4a9ac0a800803e1f17ebb16dac4be5",
"sha256:b2578bedaedf6294415197b267d4ef678fea336dd78ee2a6d2f4b028e9d07be3",
"sha256:b63fdbab29dc3868d6f009a59797cefaba315fd43cd32ddd998ee1da28e50e29",
"sha256:bd9577ec1c8c3a43040e3787711e4c257c70035b7551a21854b5dec88dad09e1",
"sha256:c02f4868a3a46ffe284a51a88d134dc96feff6079a7115164885331a1ba8ed9f",
"sha256:c1336ba7bcb722ad487cd265701ff0583c0bb6de638364ca947bb84ecc0015d1",
"sha256:c6fdcc9debb711ddd2ad6d69f9386a3d9e8e253234bbb30513e0a7caa9510c51",
"sha256:c7edf279c1376f28bf41e916c015a2a08896597869d57d621f55b6a30c7e1e6d",
"sha256:c939a1e576bded47d7d03aa2afc2ae90b928b2cf1d9dc2070ceec51fd463f430",
"sha256:cbbd7b215ad4fc6f058b5dd4c26ee5c59f72e031dfda3ac183d7968a99e4ca3a",
"sha256:cd2cdead1d3197f0ff43373cf4730213420523ba48697743e135e26f3d179f38",
"sha256:cda5c32a98f392909088111ecec23f2b0d39346ceae1a0fea23ab2d1f84ec21d",
"sha256:ceab2ce2acdc7fbaa433a93006758db6ba9a659e80c4faa13b80b9d2318e9b17",
"sha256:d34d04bf90b4cea7c22d8b19091633908f14a096caa301b24c2f3d85b5068fb8",
"sha256:d492ed8e92f3a9f9be829205f44b1d0a89af6582f0cf43e0d129fa477b93fe0c",
"sha256:d8853c269a4c5146ddca4aa7c70e631795e9d11239d5fedb1c6bbc91ffdebcac",
"sha256:d9202b9de38f12e99a40addd1a8d508a13c77f46d87ab1f9095f154667f4fe81",
"sha256:dfe7a9da5fd2a3499436cd350f31539e0a6ded5da6b5b3d422df016444d65e43",
"sha256:e041add470e8f8535cc05509485eb7205729a84441f03b25cde80ad48823792e",
"sha256:e25b2a0c396f3b84fb89573d07b0e1846ed563eb364f2ea8230ca92b8a8cb786",
"sha256:e39eaa57c7757daa25bcd21f976c46be443b73dd6c3da47fe5ce7b7048ccefe2",
"sha256:e580aa65d5f6c3bf41b9b4afe74be5d5ddba9576701c107c772d936ea2b5043a",
"sha256:e64139b4ec4f1f24c142ff7dcafe55a22b811a74d86d66560c8815687143037d",
"sha256:e66712b17d8425bb7ff8968d4c7c7fd5a2dd7bd63728b28356223c000dd2f91f",
"sha256:e836fb88902799eac8debc2b642300748f4860a197fa3d9ea502112b6bb8e142",
"sha256:e91703a4c5fec53e36875ae426ad785f4120bd1d93b65bed4752eeccd1789e0c",
"sha256:e975aac6a5acd8b510eba58d5591e10a03e3d16c1cf8a8624ca177491f7230f0",
"sha256:ec6a1e0a7aff76f0e008bebfa950188b9c50b58c1885d898145f48fc8e189a56",
"sha256:ed6a17fd397f0e2b3ad668fc9e19253ed2e3875ad9086bd7f795c29a3223f4a1",
"sha256:ede69c765e9901861ad7c6139023b7b7d5807c48a2539d817b4ab40018002d5f",
"sha256:eea7e2b7d858f6fdfbf0fe3cb846d6bd8a45446865bc09960e51f3d473c2271b",
"sha256:efd3bc6c6b17e3d4620eb6be5196f0d1c08b6ce7c3101fa8e292b79e0908944b",
"sha256:f31c4a3a7ab18467ee73a27f3e59158255d1520f3aad74315edde7a940f1be23",
"sha256:f4bd49ecde87b0fe9f55cc971449a32832bca9910821f7072bbfae1155eaa007",
"sha256:f5272b5866b259fe6c33c4a8c5073bf8b359c3c97b70c298a2f09a69b52c7c41",
"sha256:f5aee2a4cb6b146bd17333ac623610f069f34e8f31d2f4f0c1a2186e50c594f0",
"sha256:f924b485537b640dc69434565463fd6fc0c68c65a8c6e01a823dd26c9983cf79",
"sha256:fc0f523ce923e7f38eb67804bc80e0a028c76d7868500aa3f59225574b5d0453"
],
"markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2'",
"version": "==3.20.1"
},
"six": {
"hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",
"sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==1.17.0"
},
"snapshot-restore-py": {
"hashes": [
"sha256:38f99e696793790f54658e71c68c7a8a40cea877c81232b5052383b1301aceba",
"sha256:4d27f82fb6f09968f422501e9c3c2dea48a46cd19dc798eb7d6cbc57523c8004"
],
"markers": "python_version >= '3.9'",
"version": "==1.0.0"
},
"urllib3": {
"hashes": [
"sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466",
"sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"
],
"markers": "python_version >= '3.9'",
"version": "==2.4.0"
}
},
"develop": {
"autopep8": {
"hashes": [
"sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758",
"sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==2.3.2"
},
"flake8": {
"hashes": [
"sha256:93b92ba5bdb60754a6da14fa3b93a9361fd00a59632ada61fd7b130436c40343",
"sha256:fa558ae3f6f7dbf2b4f22663e5343b6b6023620461f8d4ff2019ef4b5ee70426"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==7.2.0"
},
"mccabe": {
"hashes": [
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
],
"markers": "python_version >= '3.6'",
"version": "==0.7.0"
},
"pycodestyle": {
"hashes": [
"sha256:35863c5974a271c7a726ed228a14a4f6daf49df369d8c50cd9a6f58a5e143ba9",
"sha256:c8415bf09abe81d9c7f872502a6eee881fbe85d8763dd5b9924bb0a01d67efae"
],
"markers": "python_version >= '3.9'",
"version": "==2.13.0"
},
"pyflakes": {
"hashes": [
"sha256:5039c8339cbb1944045f4ee5466908906180f13cc99cc9949348d10f82a5c32a",
"sha256:6dfd61d87b97fba5dcfaaf781171ac16be16453be6d816147989e7f6e6a9576b"
],
"markers": "python_version >= '3.9'",
"version": "==3.3.2"
}
}
}

View File

@ -37,6 +37,7 @@ TARGET_BUCKET_BY_DATA_SOURCE = {
# 変数 # 変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
# logger設定 # logger設定
@ -124,8 +125,9 @@ def handler(event, context):
decrypt_file_key = f'{execute_date}/{decrypt_file_name}' decrypt_file_key = f'{execute_date}/{decrypt_file_name}'
decrypt_bucket_name = TARGET_BUCKET_BY_DATA_SOURCE[s3_event.data_source_name] decrypt_bucket_name = TARGET_BUCKET_BY_DATA_SOURCE[s3_event.data_source_name]
logger.info(f'I-07-02 復号化ファイル出力 ファイル名:{decrypt_file_name} 出力先:{decrypt_bucket_name}/{decrypt_file_key}') logger.info(f'I-07-02 復号化ファイル出力 ファイル名:{decrypt_file_name} 出力先:{decrypt_bucket_name}/{decrypt_file_key}')
s3_client.put_object(Bucket=decrypt_bucket_name, Key=decrypt_file_key, Body=decrypt_file) decrypt_file_obj = s3_resource.Object(decrypt_bucket_name, decrypt_file_key)
decrypt_file.close() decrypt_file_obj.put(Body=decrypt_file)
decrypt_file.close
logger.info('I-07-03 復号化ファイルをS3に出力しました') logger.info('I-07-03 復号化ファイルをS3に出力しました')
except Exception as e: except Exception as e:
logger.exception(f'E-07-01 復号化ファイルのS3出力に失敗しました エラー内容{e}') logger.exception(f'E-07-01 復号化ファイルのS3出力に失敗しました エラー内容{e}')
@ -140,7 +142,8 @@ def handler(event, context):
backup_file_key = f'{s3_event.data_source_name}/{execute_date}/{s3_event.file_name}' backup_file_key = f'{s3_event.data_source_name}/{execute_date}/{s3_event.file_name}'
logger.info( logger.info(
f'I-07-04 PGP暗号化ファイル移動 移動元{s3_event.bucket_name}/{s3_event.file_path} 移動先:{SAP_DATA_BACKUP_BUCKET_NAME}/{backup_file_key}') f'I-07-04 PGP暗号化ファイル移動 移動元{s3_event.bucket_name}/{s3_event.file_path} 移動先:{SAP_DATA_BACKUP_BUCKET_NAME}/{backup_file_key}')
s3_client.copy_object(Bucket=SAP_DATA_BACKUP_BUCKET_NAME, Key=backup_file_key, CopySource=copy_source) backup_file_obj = s3_resource.Object(SAP_DATA_BACKUP_BUCKET_NAME, backup_file_key)
backup_file_obj.copy(copy_source)
s3_client.delete_object(Bucket=s3_event.bucket_name, Key=s3_event.file_path) s3_client.delete_object(Bucket=s3_event.bucket_name, Key=s3_event.file_path)
logger.info('I-07-05 PGP暗号化ファイルをバックアップ用バケットに移動しました') logger.info('I-07-05 PGP暗号化ファイルをバックアップ用バケットに移動しました')
except Exception as e: except Exception as e:
@ -155,7 +158,8 @@ def handler(event, context):
import_file_folder = f'{s3_event.data_source_name}{DIRECTORY_TARGET}' import_file_folder = f'{s3_event.data_source_name}{DIRECTORY_TARGET}'
import_file_key = f'{import_file_folder}{decrypt_file_name}' import_file_key = f'{import_file_folder}{decrypt_file_name}'
logger.info(f'I-07-06 復号化ファイル出力 ファイル名:{decrypt_file_name} 出力先:{s3_event.bucket_name}/{import_file_folder}') logger.info(f'I-07-06 復号化ファイル出力 ファイル名:{decrypt_file_name} 出力先:{s3_event.bucket_name}/{import_file_folder}')
s3_client.copy_object(Bucket=s3_event.bucket_name, Key=import_file_key, CopySource=copy_source) import_file_obj = s3_resource.Object(s3_event.bucket_name, import_file_key)
import_file_obj.copy(copy_source)
logger.info(f'I-07-07 復号化ファイルをS3に出力しました') logger.info(f'I-07-07 復号化ファイルをS3に出力しました')
except Exception as e: except Exception as e:
logger.exception(f'E-07-03 復号化ファイルのS3出力に失敗しました エラー内容{e}') logger.exception(f'E-07-03 復号化ファイルのS3出力に失敗しました エラー内容{e}')
@ -182,7 +186,8 @@ def create_status_file(s3_event, extension) -> None:
try: try:
result_error_file_name = s3_event.file_name + extension result_error_file_name = s3_event.file_name + extension
result_error_key = s3_event.data_source_name + DIRECTORY_RECV + result_error_file_name result_error_key = s3_event.data_source_name + DIRECTORY_RECV + result_error_file_name
s3_client.put_object(Bucket=s3_event.bucket_name, Key=result_error_key, Body='') result_error_obj = s3_resource.Object(s3_event.bucket_name, result_error_key)
result_error_obj.put(Body='')
logger.error( logger.error(
f'E-ERR-01 recvディレクトリにエラーファイルを作成しました ファイル名{result_error_file_name} 出力先:{s3_event.bucket_name}/{result_error_key}') f'E-ERR-01 recvディレクトリにエラーファイルを作成しました ファイル名{result_error_file_name} 出力先:{s3_event.bucket_name}/{result_error_key}')
except Exception as e: except Exception as e:
@ -199,7 +204,8 @@ def move_encrypt_file(s3_event) -> None:
} }
error_file_name = f'{datetime.datetime.now():%Y%m%d%H%M%S}_{s3_event.file_name}' error_file_name = f'{datetime.datetime.now():%Y%m%d%H%M%S}_{s3_event.file_name}'
error_key = s3_event.data_source_name + DIRECTORY_RECV_ERROR + error_file_name error_key = s3_event.data_source_name + DIRECTORY_RECV_ERROR + error_file_name
s3_client.copy_object(Bucket=s3_event.bucket_name, Key=error_key, CopySource=copy_source) error_obj = s3_resource.Object(s3_event.bucket_name, error_key)
error_obj.copy(copy_source)
s3_client.delete_object(Bucket=s3_event.bucket_name, Key=s3_event.file_path) s3_client.delete_object(Bucket=s3_event.bucket_name, Key=s3_event.file_path)
logger.error( logger.error(
f'E-ERR-02 recv_errorディレクトリにファイルを移動しました 移動元{s3_event.bucket_name}/{s3_event.file_path} 移動先:{s3_event.bucket_name}/{error_key}') f'E-ERR-02 recv_errorディレクトリにファイルを移動しました 移動元{s3_event.bucket_name}/{s3_event.file_path} 移動先:{s3_event.bucket_name}/{error_key}')

View File

@ -0,0 +1,3 @@
awslambdaric
boto3
python-gnupg

View File

@ -28,6 +28,7 @@ MAIL_INDENT = '  '
# 変数 # 変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
# logger設定 # logger設定
@ -68,7 +69,8 @@ def lambda_handler(event, context):
# ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル月次]を読み込む # ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル月次]を読み込む
try: try:
logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}') logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}')
receive_monthly_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_MONTHLY_FILE_NAME_LIST_PATH) receive_monthly_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_MONTHLY_FILE_NAME_LIST_PATH)
receive_monthly_file_name_response = receive_monthly_file_name_obj.get()
logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました') logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}') logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}')

View File

@ -34,6 +34,7 @@ MAIL_INDENT = '  '
# 変数 # 変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
# logger設定 # logger設定
@ -68,7 +69,8 @@ def lambda_handler(event, context):
# 1.設定ファイル[メルク社非営業日設定ファイル]を読み込む # 1.設定ファイル[メルク社非営業日設定ファイル]を読み込む
try: try:
logger.info(f'I-02-02 非営業日設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NON_BUSINESS_DAY_LIST_PATH}') logger.info(f'I-02-02 非営業日設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NON_BUSINESS_DAY_LIST_PATH}')
non_business_day_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=NON_BUSINESS_DAY_LIST_PATH) non_business_day_obj = s3_resource.Object(CONFIG_BUCKET_NAME, NON_BUSINESS_DAY_LIST_PATH)
non_business_day_response = non_business_day_obj.get()
logger.info('I-02-03 非営業日設定ファイルを読み込みました') logger.info('I-02-03 非営業日設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-02-01 非営業日設定ファイルの読み込みに失敗しました エラー内容:{e}') logger.error(f'E-02-01 非営業日設定ファイルの読み込みに失敗しました エラー内容:{e}')
@ -100,7 +102,8 @@ def lambda_handler(event, context):
# ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル日次]を読み込む # ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル日次]を読み込む
try: try:
logger.info(f'I-03-01 日次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_DAILY_FILE_NAME_LIST_PATH}') logger.info(f'I-03-01 日次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_DAILY_FILE_NAME_LIST_PATH}')
receive_daily_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_DAILY_FILE_NAME_LIST_PATH) receive_daily_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_DAILY_FILE_NAME_LIST_PATH)
receive_daily_file_name_response = receive_daily_file_name_obj.get()
logger.info('I-03-02 日次I/Fファイルネーム設定ファイルを読み込みました') logger.info('I-03-02 日次I/Fファイルネーム設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-03-01 日次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}') logger.error(f'E-03-01 日次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}')
@ -112,10 +115,10 @@ def lambda_handler(event, context):
# 1.SAP保管用バケットの処理稼働日に該当するサブフォルダにあるファイル一覧を取得する # 1.SAP保管用バケットの処理稼働日に該当するサブフォルダにあるファイル一覧を取得する
logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_date}/') logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_date}/')
object_prefix = f'{execute_date}/' object_prefix = f'{execute_date}/'
object_list = s3_client.list_objects_v2(Bucket=CHECK_BUCKET_NAME, Prefix=object_prefix) object_list = s3_resource.Bucket(CHECK_BUCKET_NAME).objects.filter(Prefix=object_prefix)
file_list = [] file_list = []
for obj in object_list.get('Contents', []): for obj in object_list:
obj_key = obj['Key'].rsplit('/', INDEX_SPLIT_NUM) obj_key = obj.key.rsplit('/', INDEX_SPLIT_NUM)
file_list.append(obj_key[INDEX_LAST]) file_list.append(obj_key[INDEX_LAST])
# 2.日次I/Fファイルチェック処理 # 2.日次I/Fファイルチェック処理
@ -123,8 +126,7 @@ def lambda_handler(event, context):
logger.info('I-04-04 取得したオブジェクトリストと日次I/Fファイルネーム設定ファイルの突き合わせを開始します') logger.info('I-04-04 取得したオブジェクトリストと日次I/Fファイルネーム設定ファイルの突き合わせを開始します')
receive_daily_file_name_body = io.TextIOWrapper(io.BytesIO(receive_daily_file_name_response["Body"].read()), encoding='utf-8') receive_daily_file_name_body = io.TextIOWrapper(io.BytesIO(receive_daily_file_name_response["Body"].read()), encoding='utf-8')
match_count = 0 match_count = 0
receive_daily_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_DAILY_FILE_NAME_LIST_PATH) row_count = sum(1 for line in io.BytesIO(receive_daily_file_name_obj.get()["Body"].read()))
row_count = sum(1 for line in io.BytesIO(receive_daily_file_name_response["Body"].read()))
for row in csv.reader(receive_daily_file_name_body, delimiter='\t'): for row in csv.reader(receive_daily_file_name_body, delimiter='\t'):
file_exists = False file_exists = False
for file_name in file_list: for file_name in file_list:

View File

@ -34,6 +34,7 @@ MAIL_INDENT = '  '
# 変数 # 変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
# logger設定 # logger設定
@ -70,8 +71,8 @@ def lambda_handler(event, context):
# 1.設定ファイル[チェック処理実施指定日ファイル]を読み込む # 1.設定ファイル[チェック処理実施指定日ファイル]を読み込む
try: try:
logger.info(f'I-02-02 チェック処理実施指定日ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{MONTHLY_CEHCK_DAY_LIST_PATH}') logger.info(f'I-02-02 チェック処理実施指定日ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{MONTHLY_CEHCK_DAY_LIST_PATH}')
monthly_day_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=MONTHLY_CEHCK_DAY_LIST_PATH) monthly_day_obj = s3_resource.Object(CONFIG_BUCKET_NAME, MONTHLY_CEHCK_DAY_LIST_PATH)
monthly_day_response = monthly_day_obj.get()
logger.info('I-02-03 チェック処理実施指定日ファイルを読み込みました') logger.info('I-02-03 チェック処理実施指定日ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-02-01 チェック処理実施指定日設定ファイルの読み込みに失敗しました エラー内容:{e}') logger.error(f'E-02-01 チェック処理実施指定日設定ファイルの読み込みに失敗しました エラー内容:{e}')
@ -103,8 +104,8 @@ def lambda_handler(event, context):
# ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル月次]を読み込む # ③ 設定ファイル[SAP_finI/Fファイルネーム設定ファイル月次]を読み込む
try: try:
logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}') logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}')
receive_monthly_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_MONTHLY_FILE_NAME_LIST_PATH) receive_monthly_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_MONTHLY_FILE_NAME_LIST_PATH)
receive_monthly_file_name_response = receive_monthly_file_name_obj.get()
logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました') logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}') logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}')
@ -116,10 +117,10 @@ def lambda_handler(event, context):
# 1.SAP保管用バケットの処理稼働月に該当するサブフォルダにあるファイル一覧を取得する # 1.SAP保管用バケットの処理稼働月に該当するサブフォルダにあるファイル一覧を取得する
logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_month}/') logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_month}/')
object_prefix = f'{execute_month}/' object_prefix = f'{execute_month}/'
object_list = s3_client.list_objects_v2(Bucket=CHECK_BUCKET_NAME, Prefix=object_prefix) object_list = s3_resource.Bucket(CHECK_BUCKET_NAME).objects.filter(Prefix=object_prefix)
file_list = [] file_list = []
for obj in object_list.get('Contents', []): for obj in object_list:
obj_key = obj['Key'].rsplit('/', INDEX_SPLIT_NUM) obj_key = obj.key.rsplit('/', INDEX_SPLIT_NUM)
file_list.append(obj_key[INDEX_LAST]) file_list.append(obj_key[INDEX_LAST])
# 2.月次I/Fファイルチェック処理 # 2.月次I/Fファイルチェック処理
@ -127,8 +128,7 @@ def lambda_handler(event, context):
logger.info('I-04-04 取得したオブジェクトリストと月次I/Fファイルネーム設定ファイルの突き合わせを開始します') logger.info('I-04-04 取得したオブジェクトリストと月次I/Fファイルネーム設定ファイルの突き合わせを開始します')
receive_monthly_file_name_body = io.TextIOWrapper(io.BytesIO(receive_monthly_file_name_response["Body"].read()), encoding='utf-8') receive_monthly_file_name_body = io.TextIOWrapper(io.BytesIO(receive_monthly_file_name_response["Body"].read()), encoding='utf-8')
match_count = 0 match_count = 0
receive_monthly_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_MONTHLY_FILE_NAME_LIST_PATH) row_count = sum(1 for line in io.BytesIO(receive_monthly_file_name_obj.get()["Body"].read()))
row_count = sum(1 for line in io.BytesIO(receive_monthly_file_name_response["Body"].read()))
for row in csv.reader(receive_monthly_file_name_body, delimiter='\t'): for row in csv.reader(receive_monthly_file_name_body, delimiter='\t'):
file_exists = False file_exists = False
for file_name in file_list: for file_name in file_list:

View File

@ -28,6 +28,7 @@ MAIL_INDENT = '  '
# 変数 # 変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
# logger設定 # logger設定
@ -68,7 +69,8 @@ def lambda_handler(event, context):
# ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル月次]を読み込む # ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル月次]を読み込む
try: try:
logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}') logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}')
receive_monthly_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_MONTHLY_FILE_NAME_LIST_PATH) receive_monthly_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_MONTHLY_FILE_NAME_LIST_PATH)
receive_monthly_file_name_response = receive_monthly_file_name_obj.get()
logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました') logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}') logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}')

View File

@ -34,6 +34,7 @@ MAIL_INDENT = '  '
# 変数 # 変数
s3_client = boto3.client('s3') s3_client = boto3.client('s3')
s3_resource = boto3.resource('s3')
sns_client = boto3.client('sns') sns_client = boto3.client('sns')
# logger設定 # logger設定
@ -68,7 +69,8 @@ def lambda_handler(event, context):
# 1.設定ファイル[メルク社非営業日設定ファイル]を読み込む # 1.設定ファイル[メルク社非営業日設定ファイル]を読み込む
try: try:
logger.info(f'I-02-02 非営業日設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NON_BUSINESS_DAY_LIST_PATH}') logger.info(f'I-02-02 非営業日設定ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{NON_BUSINESS_DAY_LIST_PATH}')
non_business_day_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=NON_BUSINESS_DAY_LIST_PATH) non_business_day_obj = s3_resource.Object(CONFIG_BUCKET_NAME, NON_BUSINESS_DAY_LIST_PATH)
non_business_day_response = non_business_day_obj.get()
logger.info('I-02-03 非営業日設定ファイルを読み込みました') logger.info('I-02-03 非営業日設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-02-01 非営業日設定ファイルの読み込みに失敗しました エラー内容:{e}') logger.error(f'E-02-01 非営業日設定ファイルの読み込みに失敗しました エラー内容:{e}')
@ -100,7 +102,8 @@ def lambda_handler(event, context):
# ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル日次]を読み込む # ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル日次]を読み込む
try: try:
logger.info(f'I-03-01 日次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_DAILY_FILE_NAME_LIST_PATH}') logger.info(f'I-03-01 日次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_DAILY_FILE_NAME_LIST_PATH}')
receive_daily_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_DAILY_FILE_NAME_LIST_PATH) receive_daily_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_DAILY_FILE_NAME_LIST_PATH)
receive_daily_file_name_response = receive_daily_file_name_obj.get()
logger.info('I-03-02 日次I/Fファイルネーム設定ファイルを読み込みました') logger.info('I-03-02 日次I/Fファイルネーム設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-03-01 日次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}') logger.error(f'E-03-01 日次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}')
@ -112,10 +115,10 @@ def lambda_handler(event, context):
# 1.SAP保管用バケットの処理稼働日に該当するサブフォルダにあるファイル一覧を取得する # 1.SAP保管用バケットの処理稼働日に該当するサブフォルダにあるファイル一覧を取得する
logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_date}/') logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_date}/')
object_prefix = f'{execute_date}/' object_prefix = f'{execute_date}/'
object_list = s3_client.list_objects_v2(Bucket=CHECK_BUCKET_NAME, Prefix=object_prefix) object_list = s3_resource.Bucket(CHECK_BUCKET_NAME).objects.filter(Prefix=object_prefix)
file_list = [] file_list = []
for obj in object_list.get('Contents', []): for obj in object_list:
obj_key = obj['Key'].rsplit('/', INDEX_SPLIT_NUM) obj_key = obj.key.rsplit('/', INDEX_SPLIT_NUM)
file_list.append(obj_key[INDEX_LAST]) file_list.append(obj_key[INDEX_LAST])
# 2.日次I/Fファイルチェック処理 # 2.日次I/Fファイルチェック処理
@ -123,8 +126,7 @@ def lambda_handler(event, context):
logger.info('I-04-04 取得したオブジェクトリストと日次I/Fファイルネーム設定ファイルの突き合わせを開始します') logger.info('I-04-04 取得したオブジェクトリストと日次I/Fファイルネーム設定ファイルの突き合わせを開始します')
receive_daily_file_name_body = io.TextIOWrapper(io.BytesIO(receive_daily_file_name_response["Body"].read()), encoding='utf-8') receive_daily_file_name_body = io.TextIOWrapper(io.BytesIO(receive_daily_file_name_response["Body"].read()), encoding='utf-8')
match_count = 0 match_count = 0
receive_daily_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_DAILY_FILE_NAME_LIST_PATH) row_count = sum(1 for line in io.BytesIO(receive_daily_file_name_obj.get()["Body"].read()))
row_count = sum(1 for line in io.BytesIO(receive_daily_file_name_response["Body"].read()))
for row in csv.reader(receive_daily_file_name_body, delimiter='\t'): for row in csv.reader(receive_daily_file_name_body, delimiter='\t'):
file_exists = False file_exists = False
for file_name in file_list: for file_name in file_list:

View File

@ -71,7 +71,8 @@ def lambda_handler(event, context):
# 1.設定ファイル[チェック処理実施指定日ファイル]を読み込む # 1.設定ファイル[チェック処理実施指定日ファイル]を読み込む
try: try:
logger.info(f'I-02-02 チェック処理実施指定日ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{MONTHLY_CEHCK_DAY_LIST_PATH}') logger.info(f'I-02-02 チェック処理実施指定日ファイル読込 読込元:{CONFIG_BUCKET_NAME}/{MONTHLY_CEHCK_DAY_LIST_PATH}')
monthly_day_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=MONTHLY_CEHCK_DAY_LIST_PATH) monthly_day_obj = s3_resource.Object(CONFIG_BUCKET_NAME, MONTHLY_CEHCK_DAY_LIST_PATH)
monthly_day_response = monthly_day_obj.get()
logger.info('I-02-03 チェック処理実施指定日ファイルを読み込みました') logger.info('I-02-03 チェック処理実施指定日ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-02-01 チェック処理実施指定日設定ファイルの読み込みに失敗しました エラー内容:{e}') logger.error(f'E-02-01 チェック処理実施指定日設定ファイルの読み込みに失敗しました エラー内容:{e}')
@ -103,7 +104,8 @@ def lambda_handler(event, context):
# ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル月次]を読み込む # ③ 設定ファイル[SAP_supI/Fファイルネーム設定ファイル月次]を読み込む
try: try:
logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}') logger.info(f'I-03-01 月次I/Fファイルネーム設定ファイル読込 読込元{CONFIG_BUCKET_NAME}/{RECEIVE_MONTHLY_FILE_NAME_LIST_PATH}')
receive_monthly_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_MONTHLY_FILE_NAME_LIST_PATH) receive_monthly_file_name_obj = s3_resource.Object(CONFIG_BUCKET_NAME, RECEIVE_MONTHLY_FILE_NAME_LIST_PATH)
receive_monthly_file_name_response = receive_monthly_file_name_obj.get()
logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました') logger.info('I-03-02 月次I/Fファイルネーム設定ファイルを読み込みました')
except Exception as e: except Exception as e:
logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}') logger.error(f'E-03-01 月次I/Fファイルネーム設定ファイルの読み込みに失敗しました エラー内容{e}')
@ -115,10 +117,10 @@ def lambda_handler(event, context):
# 1.SAP保管用バケットの処理稼働月に該当するサブフォルダにあるファイル一覧を取得する # 1.SAP保管用バケットの処理稼働月に該当するサブフォルダにあるファイル一覧を取得する
logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_month}/') logger.info(f'I-04-02 オブジェクトリストの取得 取得先:{CHECK_BUCKET_NAME}/{execute_month}/')
object_prefix = f'{execute_month}/' object_prefix = f'{execute_month}/'
object_list = s3_client.list_objects_v2(Bucket=CHECK_BUCKET_NAME, Prefix=object_prefix) object_list = s3_resource.Bucket(CHECK_BUCKET_NAME).objects.filter(Prefix=object_prefix)
file_list = [] file_list = []
for obj in object_list.get('Contents', []): for obj in object_list:
obj_key = obj['Key'].rsplit('/', INDEX_SPLIT_NUM) obj_key = obj.key.rsplit('/', INDEX_SPLIT_NUM)
file_list.append(obj_key[INDEX_LAST]) file_list.append(obj_key[INDEX_LAST])
# 2.月次I/Fファイルチェック処理 # 2.月次I/Fファイルチェック処理
@ -126,8 +128,7 @@ def lambda_handler(event, context):
logger.info('I-04-04 取得したオブジェクトリストと月次I/Fファイルネーム設定ファイルの突き合わせを開始します') logger.info('I-04-04 取得したオブジェクトリストと月次I/Fファイルネーム設定ファイルの突き合わせを開始します')
receive_monthly_file_name_body = io.TextIOWrapper(io.BytesIO(receive_monthly_file_name_response["Body"].read()), encoding='utf-8') receive_monthly_file_name_body = io.TextIOWrapper(io.BytesIO(receive_monthly_file_name_response["Body"].read()), encoding='utf-8')
match_count = 0 match_count = 0
receive_monthly_file_name_response = s3_client.get_object(Bucket=CONFIG_BUCKET_NAME, Key=RECEIVE_MONTHLY_FILE_NAME_LIST_PATH) row_count = sum(1 for line in io.BytesIO(receive_monthly_file_name_obj.get()["Body"].read()))
row_count = sum(1 for line in io.BytesIO(receive_monthly_file_name_response["Body"].read()))
for row in csv.reader(receive_monthly_file_name_body, delimiter='\t'): for row in csv.reader(receive_monthly_file_name_body, delimiter='\t'):
file_exists = False file_exists = False
for file_name in file_list: for file_name in file_list:

View File

@ -1,19 +0,0 @@
# AWS公式のDockerイメージを利用
FROM public.ecr.aws/lambda/python:3.12
# pythonの標準出力をバッファリングしないフラグ
ENV PYTHONUNBUFFERED=1
# pythonのバイトコードを生成しないフラグ
ENV PYTHONDONTWRITEBYTECODE=1
# 必要なファイルをイメージにコピー
COPY Pipfile Pipfile.lock main.py ./
# ライブラリインストール
RUN pip install --upgrade pip wheel setuptools && \
pip install pipenv --no-cache-dir && \
pipenv install --system --deploy && \
pip uninstall -y pipenv virtualenv-clone virtualenv
# lambdaハンドラを起動
CMD [ "main.handler" ]

View File

@ -1,15 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
boto3 = "*"
pyzipper = "*"
[dev-packages]
autopep8 = "*"
flake8 = "*"
[requires]
python_version = "3.12"

View File

@ -1,177 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "d8b79fd5be60005b43448511c67536c114e5fd73722a17e77a5e60a9283aea25"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.12"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"boto3": {
"hashes": [
"sha256:3faa2c328a61745f3215a63039606a6fcf55d9afe1cc76e3a5e27b9db58cdbf6",
"sha256:b998edac72f6740bd5d9d585cf3880f2dfeb4842e626b34430fd0e9623378011"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==1.38.32"
},
"botocore": {
"hashes": [
"sha256:0899a090e352cb5eeaae2c7bb52a987b469d23912c7ece86664dfb5c2e074978",
"sha256:64ab919a5d8b74dd73eaac1f978d0e674d11ff3bbe8815c3d2982477be9a082c"
],
"markers": "python_version >= '3.9'",
"version": "==1.38.32"
},
"jmespath": {
"hashes": [
"sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980",
"sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"
],
"markers": "python_version >= '3.7'",
"version": "==1.0.1"
},
"pycryptodomex": {
"hashes": [
"sha256:02d87b80778c171445d67e23d1caef279bf4b25c3597050ccd2e13970b57fd51",
"sha256:06698f957fe1ab229a99ba2defeeae1c09af185baa909a31a5d1f9d42b1aaed6",
"sha256:14c37aaece158d0ace436f76a7bb19093db3b4deade9797abfc39ec6cd6cc2fe",
"sha256:189afbc87f0b9f158386bf051f720e20fa6145975f1e76369303d0f31d1a8d7c",
"sha256:1c3a65ad441746b250d781910d26b7ed0a396733c6f2dbc3327bd7051ec8a541",
"sha256:1c6d919fc8429e5cb228ba8c0d4d03d202a560b421c14867a65f6042990adc8e",
"sha256:267a3038f87a8565bd834317dbf053a02055915acf353bf42ededb9edaf72010",
"sha256:27e13c80ac9a0a1d050ef0a7e0a18cc04c8850101ec891815b6c5a0375e8a245",
"sha256:43c446e2ba8df8889e0e16f02211c25b4934898384c1ec1ec04d7889c0333587",
"sha256:47f6d318fe864d02d5e59a20a18834819596c4ed1d3c917801b22b92b3ffa648",
"sha256:4e79f1aaff5a3a374e92eb462fa9e598585452135012e2945f96874ca6eeb1ff",
"sha256:4f2596e643d4365e14d0879dc5aafe6355616c61c2176009270f3048f6d9a61f",
"sha256:52e5ca58c3a0b0bd5e100a9fbc8015059b05cffc6c66ce9d98b4b45e023443b9",
"sha256:55ccbe27f049743a4caf4f4221b166560d3438d0b1e5ab929e07ae1702a4d6fd",
"sha256:58b851b9effd0d072d4ca2e4542bf2a4abcf13c82a29fd2c93ce27ee2a2e9462",
"sha256:6b8962204c47464d5c1c4038abeadd4514a133b28748bcd9fa5b6d62e3cec6fa",
"sha256:6bbcb1dd0f646484939e142462d9e532482bc74475cecf9c4903d4e1cd21f003",
"sha256:71909758f010c82bc99b0abf4ea12012c98962fbf0583c2164f8b84533c2e4da",
"sha256:7b37e08e3871efe2187bc1fd9320cc81d87caf19816c648f24443483005ff886",
"sha256:7de1e40a41a5d7f1ac42b6569b10bcdded34339950945948529067d8426d2785",
"sha256:8a4fcd42ccb04c31268d1efeecfccfd1249612b4de6374205376b8f280321744",
"sha256:91979028227543010d7b2ba2471cf1d1e398b3f183cb105ac584df0c36dac28d",
"sha256:a33986a0066860f7fcf7c7bd2bc804fa90e434183645595ae7b33d01f3c91ed8",
"sha256:a9d446e844f08299236780f2efa9898c818fe7e02f17263866b8550c7d5fb328",
"sha256:add243d204e125f189819db65eed55e6b4713f70a7e9576c043178656529cec7",
"sha256:b2c2537863eccef2d41061e82a881dcabb04944c5c06c5aa7110b577cc487545",
"sha256:bc65bdd9fc8de7a35a74cab1c898cab391a4add33a8fe740bda00f5976ca4708",
"sha256:bdc69d0d3d989a1029df0eed67cc5e8e5d968f3724f4519bd03e0ec68df7543c",
"sha256:bffc92138d75664b6d543984db7893a628559b9e78658563b0395e2a5fb47ed9",
"sha256:c25e30a20e1b426e1f0fa00131c516f16e474204eee1139d1603e132acffc314",
"sha256:c7947ab8d589e3178da3d7cdeabe14f841b391e17046954f2fbcd941705762b5",
"sha256:c84b239a1f4ec62e9c789aafe0543f0594f0acd90c8d9e15bcece3efe55eca66",
"sha256:c885da45e70139464f082018ac527fdaad26f1657a99ee13eecdce0f0ca24ab4",
"sha256:d9825410197a97685d6a1fa2a86196430b01877d64458a20e95d4fd00d739a08",
"sha256:da4fa650cef02db88c2b98acc5434461e027dce0ae8c22dd5a69013eaf510006",
"sha256:df027262368334552db2c0ce39706b3fb32022d1dce34673d0f9422df004b96a",
"sha256:ebfff755c360d674306e5891c564a274a47953562b42fb74a5c25b8fc1fb1cb5",
"sha256:eca54f4bb349d45afc17e3011ed4264ef1cc9e266699874cdd1349c504e64798",
"sha256:f489c4765093fb60e2edafdf223397bc716491b2b69fe74367b70d6999257a5c",
"sha256:fdfac7cda115bca3a5abb2f9e43bc2fb66c2b65ab074913643803ca7083a79ea",
"sha256:febec69c0291efd056c65691b6d9a339f8b4bc43c6635b8699471248fe897fea"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'",
"version": "==3.23.0"
},
"python-dateutil": {
"hashes": [
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.9.0.post0"
},
"pyzipper": {
"hashes": [
"sha256:0adca90a00c36a93fbe49bfa8c5add452bfe4ef85a1b8e3638739dd1c7b26bfc",
"sha256:6d097f465bfa47796b1494e12ea65d1478107d38e13bc56f6e58eedc4f6c1a87"
],
"index": "pypi",
"markers": "python_version >= '3.4'",
"version": "==0.3.6"
},
"s3transfer": {
"hashes": [
"sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be",
"sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177"
],
"markers": "python_version >= '3.9'",
"version": "==0.13.0"
},
"six": {
"hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",
"sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==1.17.0"
},
"urllib3": {
"hashes": [
"sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466",
"sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"
],
"markers": "python_version >= '3.9'",
"version": "==2.4.0"
}
},
"develop": {
"autopep8": {
"hashes": [
"sha256:8d6c87eba648fdcfc83e29b788910b8643171c395d9c4bcf115ece035b9c9dda",
"sha256:a203fe0fcad7939987422140ab17a930f684763bf7335bdb6709991dd7ef6c2d"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
"version": "==2.3.1"
},
"flake8": {
"hashes": [
"sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38",
"sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"
],
"index": "pypi",
"markers": "python_full_version >= '3.8.1'",
"version": "==7.1.1"
},
"mccabe": {
"hashes": [
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
],
"markers": "python_version >= '3.6'",
"version": "==0.7.0"
},
"pycodestyle": {
"hashes": [
"sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3",
"sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"
],
"markers": "python_version >= '3.8'",
"version": "==2.12.1"
},
"pyflakes": {
"hashes": [
"sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f",
"sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"
],
"markers": "python_version >= '3.8'",
"version": "==3.2.0"
}
}
}

View File

@ -1,236 +0,0 @@
import datetime
import logging
import os
from zoneinfo import ZoneInfo
import boto3
import pyzipper
from pyzipper.zipfile import BadZipFile
# 環境変数
DATA_IMPORT_BUCKET = os.environ["DATA_IMPORT_BUCKET"]
HCP_WEB_TARGET_FOLDER = os.environ["HCP_WEB_TARGET_FOLDER"]
HCP_WEB_BACKUP_BUCKET = os.environ["HCP_WEB_BACKUP_BUCKET"]
BACKUP_ZIPFILE_FOLDER = os.environ["BACKUP_ZIPFILE_FOLDER"]
BACKUP_DATA_IMPORT_FOLDER = os.environ["BACKUP_DATA_IMPORT_FOLDER"]
DATA_IMPORT_FILENAME = os.environ["DATA_IMPORT_FILENAME"]
MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY = os.environ["MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY"]
LOG_LEVEL = os.environ["LOG_LEVEL"]
TZ = os.environ["TZ"]
# 定数
# 多重起動抑制用のコントロールファイルの拡張子
EXCLUSIVE_CONTROL_FILE_EXT = '.doing'
# tmpフォルダパス
PATH_TMP = '/tmp'
# 拡張子
ZIP_FILE_EXT = 'zip'
CSV_FILE_EXT = 'csv'
# S3クライアント
s3_client = boto3.client('s3')
# SystemsManagerクライアント
ssm_client = boto3.client('ssm')
# logger設定
logger = logging.getLogger()
def log_datetime_convert_tz(*arg):
"""ログに出力するタイムスタンプのロケールを変更するJST指定"""
return datetime.datetime.now(ZoneInfo(TZ)).timetuple()
formatter = logging.Formatter(
'[%(levelname)s]\t%(asctime)s\t%(message)s\n',
'%Y-%m-%d %H:%M:%S'
)
formatter.converter = log_datetime_convert_tz
for handler in logger.handlers:
handler.setFormatter(formatter)
level = logging.getLevelName(LOG_LEVEL)
if not isinstance(level, int):
level = logging.INFO
logger.setLevel(level)
def extract_zip_with_password(zip_filepath: str, extract_to_folder: str, password: str) -> os.path:
"""
暗号化ZIPを解凍する
:param zip_filepath: ZIPファイルが保管されているフォルダパス
:param extract_to_folder: ZIPファイルの解凍先フォルダ
:param password: ZIPパスワード
:return 解凍されたファイルパス
"""
# ZIPを解凍
try:
with pyzipper.AESZipFile(zip_filepath) as z:
# ZIP内のファイルは1つのみ
inner_filename = z.filelist[0].filename
z.extractall(path=extract_to_folder, pwd=password.encode())
except Exception as e:
raise e
return os.path.join(extract_to_folder, inner_filename)
def get_s3_event_parameter(event: dict) -> tuple[str, str, str, str]:
s3_event = event["Records"][0]["s3"]
event_bucket_name: str = s3_event["bucket"]["name"]
event_object_key: str = s3_event["object"]["key"]
event_file_name: str = os.path.basename(event_object_key)
event_folder_name: str = os.path.dirname(event_object_key).split('/')[0]
return event_bucket_name, event_object_key, event_file_name, event_folder_name
def get_ssm_params(parameter_key: str, with_decryption: bool = True) -> str:
"""SSMパラメータストアから指定されたパラメータ名の値を取得する"""
response = ssm_client.get_parameter(
Name=parameter_key, WithDecryption=with_decryption)
parameter_value: str = response['Parameter']['Value']
return parameter_value
def delete_doing_file(event: dict) -> None:
""".doingファイルをバケット上から削除する"""
# イベント情報を取得
(
event_bucket_name,
event_object_key,
_,
_
) = get_s3_event_parameter(event)
# ⑨ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
s3_client.delete_object(
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}')
def handler(event, context) -> None:
try:
# ① 処理開始ログを出力する
logger.info('I-01-01 処理開始 medパスデータ解凍・復号化・転送処理')
# ② 処理開始時に受け取ったイベント情報をログに出力する
# バケット名・フォルダ名・受信データファイル名をメモリに保持
(
event_bucket_name,
event_object_key,
event_file_name,
event_folder_name
) = get_s3_event_parameter(event)
logger.info(f'I-02-01 受信バケット:{event_bucket_name}')
logger.info(f'I-02-01 フォルダ名:{event_folder_name}')
logger.info(f'I-02-01 ファイル名:{event_file_name}')
# ③ S3イベントによるLambdaの重複発火防止の為、メモリに保持したバケット名/フォルダ名内に、「受信データファイル名.doing」ファイルが存在するかチェックする
try:
s3_client.head_object(
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}')
logger.error(
f'E-01-01 {event_bucket_name}/{event_object_key}は現在処理中です。処理を終了します。')
return
except Exception:
# .doingファイルが見つからなかった場合は、処理を続行する
# メモリに保持したバケット名/フォルダ名内に、「受信データファイル名.doing」ファイルを作成する
logger.info('I-03-01 medパスデータの解凍・復号化・転送を開始します')
s3_client.put_object(
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}', Body=b'')
# ④ S3から暗号化ZIPファイルを読み込む
try:
logger.info(
f'I-04-01 暗号化ZIPファイル読込 読込元{event_bucket_name}/{event_object_key}')
s3_client.download_file(
event_bucket_name, event_object_key, os.path.join(PATH_TMP, event_file_name))
logger.info('I-04-02 暗号化ZIPファイルをダウンロードしました')
except Exception as e:
logger.exception(f'E-04-01 暗号化ZIPファイルのダウンロードに失敗しました エラー内容{e}')
delete_doing_file(event)
return
# ⑤ ZIP解凍パスワードをSSM パラメータストアから取得する
try:
logger.info('I-05-01 ZIP解凍パスワードを読込')
zip_password = get_ssm_params(
MEDPASS_ZIP_PASSWORD_PARAMETER_STORE_KEY)
except Exception as e:
logger.exception(f'E-05-01 ZIP解凍パスワードの読み込みに失敗しました エラー内容{e}')
delete_doing_file(event)
return
# ⑥ ZIPファイルを解凍してローカルに保存
try:
logger.info(f'I-05-02 ZIP解凍開始')
extracted_zip_file_path = extract_zip_with_password(
os.path.join(PATH_TMP, event_file_name), PATH_TMP, zip_password)
except RuntimeError as e:
if 'password' in str(e).lower():
# パスワードが間違っている場合のエラー
logger.exception(
f'E-05-02 ZIPのパスワードが不正のため、解凍に失敗しました エラー内容{e}')
delete_doing_file(event)
return
else:
# 想定外のエラー
raise e
# ZIPファイルが壊れている場合のエラー
except BadZipFile as e:
logger.exception(f'E-05-03 ZIPの形式が不正のため、解凍に失敗しました エラー内容{e}')
delete_doing_file(event)
return
# データ登録用にファイルをリネーム
# ZIPファイル名がyyyymmdd.zipのため、年月日部分をデータ登録用ファイル名の末尾につけ、拡張子をCSVに変更
data_import_file_name = f'{DATA_IMPORT_FILENAME}_{event_file_name.lower().replace(ZIP_FILE_EXT, CSV_FILE_EXT)}'
logger.info(f'I-05-03 ZIP解凍成功')
# ⑥ 受信した暗号化ZIPファイルと解凍後のファイルをバックアップする
backup_copy_source = {
'Bucket': event_bucket_name, 'Key': event_object_key}
execute_date_yyyymmdd = datetime.date.today().strftime('%Y/%m/%d')
# ZIPファイルのバックアップ
s3_client.copy_object(
Bucket=HCP_WEB_BACKUP_BUCKET,
Key=f'{BACKUP_ZIPFILE_FOLDER}/{execute_date_yyyymmdd}/{event_file_name}',
CopySource=backup_copy_source
)
logger.info(
f'I-06-01 medパス受信データのバックアップ完了{HCP_WEB_BACKUP_BUCKET}/{BACKUP_ZIPFILE_FOLDER}/{execute_date_yyyymmdd}/{event_file_name}')
# 解凍後ファイルのバックアップ
s3_client.upload_file(
extracted_zip_file_path,
Bucket=HCP_WEB_BACKUP_BUCKET,
Key=f'{BACKUP_DATA_IMPORT_FOLDER}/{execute_date_yyyymmdd}/{data_import_file_name}'
)
logger.info(
f'I-06-02 medパス解凍後データのバックアップ完了{HCP_WEB_BACKUP_BUCKET}/{BACKUP_DATA_IMPORT_FOLDER}/{execute_date_yyyymmdd}/{data_import_file_name}')
# ⑦ 解凍後のファイルをデータ登録バケットに転送する
data_import_copy_source = {'Bucket': HCP_WEB_BACKUP_BUCKET,
'Key': f'{BACKUP_DATA_IMPORT_FOLDER}/{execute_date_yyyymmdd}/{data_import_file_name}'}
s3_client.copy_object(
Bucket=DATA_IMPORT_BUCKET,
Key=f'{HCP_WEB_TARGET_FOLDER}/{data_import_file_name}',
CopySource=data_import_copy_source
)
# アップロード後、元のバケットからは削除する
s3_client.delete_object(Bucket=event_bucket_name, Key=event_object_key)
logger.info(
f'I-07-01 medパス解凍後データの転送完了{DATA_IMPORT_BUCKET}/{HCP_WEB_TARGET_FOLDER}/{data_import_file_name}')
# ⑧ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
delete_doing_file(event)
logger.info('I-08-01 処理終了 medパスデータ解凍・復号化・転送処理')
except Exception as e:
logger.exception(f'想定外のエラーが発生しました。処理を終了します。 例外内容:{e}')
delete_doing_file(event)
raise e

View File

@ -1,214 +0,0 @@
import datetime
import json
import logging
import os
import re
from zoneinfo import ZoneInfo
import boto3
# 環境変数
CONFIG_BUCKET_NAME = os.environ["CONFIG_BUCKET_NAME"]
BUCKET_TRANSFER_SETTING_FILE_FOLDER = os.environ["BUCKET_TRANSFER_SETTING_FILE_FOLDER"]
BUCKET_TRANSFER_SETTING_FILE_NAME = os.environ["BUCKET_TRANSFER_SETTING_FILE_NAME"]
LOG_LEVEL = os.environ["LOG_LEVEL"]
TZ = os.environ["TZ"]
ENV = os.environ["ENV"]
# 定数
EXCLUSIVE_CONTROL_FILE_EXT = '.doing'
# S3クライアント
s3_client = boto3.client('s3')
# logger設定
logger = logging.getLogger()
def log_datetime_convert_tz(*arg):
"""ログに出力するタイムスタンプのロケールを変更するJST指定"""
return datetime.datetime.now(ZoneInfo(TZ)).timetuple()
formatter = logging.Formatter(
'[%(levelname)s]\t%(asctime)s\t%(message)s\n',
'%Y-%m-%d %H:%M:%S'
)
formatter.converter = log_datetime_convert_tz
for handler in logger.handlers:
handler.setFormatter(formatter)
level = logging.getLevelName(LOG_LEVEL)
if not isinstance(level, int):
level = logging.INFO
logger.setLevel(level)
def get_s3_event_parameter(event: dict) -> tuple[str, str, str, str]:
"""Lambdaに送信されたEvent情報からS3のイベントを取得する"""
s3_event = event["Records"][0]["s3"]
event_bucket_name: str = s3_event["bucket"]["name"]
event_object_key: str = s3_event["object"]["key"]
event_file_name: str = os.path.basename(event_object_key)
event_folder_name: str = os.path.dirname(event_object_key).split('/')[0]
return event_bucket_name, event_object_key, event_file_name, event_folder_name
def delete_doing_file(event: dict) -> None:
""".doingファイルをバケット上から削除する"""
# イベント情報を取得
(
event_bucket_name,
event_object_key,
_,
_
) = get_s3_event_parameter(event)
# ⑨ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
s3_client.delete_object(
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}')
def lambda_handler(event, context):
"""Lambdaハンドラー関数"""
# ① 処理開始ログを出力する
logger.info('I-01-01 処理開始 S3バケット間ファイル転送処理')
# ② 処理開始時に受け取ったイベント情報をログに出力する
# バケット名・フォルダ名・受信データファイル名をメモリに保持
(
event_bucket_name,
event_object_key,
event_file_name,
event_folder_name
) = get_s3_event_parameter(event)
try:
logger.info(f'I-02-01 受信バケット:{event_bucket_name}')
logger.info(f'I-02-01 フォルダ名:{event_folder_name}')
logger.info(f'I-02-01 受信ファイル名:{event_file_name}')
# ③ S3イベントによるLambdaの重複発火防止の為、メモリに保持したバケット名/フォルダ名内に、「受信データファイル名.doing」ファイルが存在するかチェックする
try:
s3_client.head_object(
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}')
logger.error(
f'E-01-01 {event_bucket_name}/{event_object_key}は現在処理中です。処理を終了します。')
return
except Exception:
# .doingファイルが見つからなかった場合は、処理を続行する
# メモリに保持したバケット名/フォルダ名内に、「受信データファイル名.doing」ファイルを作成する
logger.info(
f'I-03-01 {event_bucket_name}/{event_object_key}を転送します')
s3_client.put_object(
Bucket=event_bucket_name, Key=f'{event_object_key}{EXCLUSIVE_CONTROL_FILE_EXT}', Body=b'')
# ④ バケット転送設定ファイルを特定する
transfer_config_file_response = s3_client.get_object(
Bucket=CONFIG_BUCKET_NAME, Key=f'{BUCKET_TRANSFER_SETTING_FILE_FOLDER}/{BUCKET_TRANSFER_SETTING_FILE_NAME}')
transfer_config_file = json.loads(
transfer_config_file_response['Body'].read().decode('utf8'))
# ⑤ バケット転送設定ファイルのキー[受信ファイル名正規表現パターン]と、[メモリに保持した受信ファイル名]と一致するものを取得する。
transfer_config = None
for key in transfer_config_file.keys():
filename_regex = re.compile(key)
match_result = filename_regex.fullmatch(event_file_name)
if match_result is not None:
transfer_config = transfer_config_file[key]
break
if transfer_config is None:
logger.error(
f'E-03-01 S3バケットの転送設定が見つかりません。{CONFIG_BUCKET_NAME}/{BUCKET_TRANSFER_SETTING_FILE_FOLDER}/{BUCKET_TRANSFER_SETTING_FILE_NAME}')
delete_doing_file(event)
return
# ⑥ 受信ファイルを、⑤でメモリ上に保持したJSONオブジェクトの設定内容に基づき、バックアップする
if transfer_config.get('backup_setting', None) is not None:
backup_setting = transfer_config['backup_setting']
copy_source = {'Bucket': event_bucket_name,
'Key': event_object_key}
backup_bucket = backup_setting['backup_bucket'].format(env=ENV)
backup_date_pattern = datetime.date.today().strftime(
backup_setting['date_pattern'])
s3_client.copy_object(
Bucket=backup_bucket,
Key=f'{event_folder_name}/{backup_date_pattern}/{event_file_name}',
CopySource=copy_source
)
logger.info(
f'I-04-01 受信ファイルのバックアップ完了::{backup_bucket}/{event_folder_name}/{backup_date_pattern}/{event_file_name}')
# ⑦ 受信ファイルを、⑤でメモリ上に保持したJSONオブジェクトの設定内容に基づき、移動する
destination_bucket = transfer_config['destination_bucket'].format(
env=ENV)
destination_folder = transfer_config['destination_folder']
s3_client.copy_object(
Bucket=destination_bucket,
Key=f"{destination_folder}/{event_file_name}",
CopySource=copy_source
)
# コピー後、元のバケットからは削除する
s3_client.delete_object(Bucket=event_bucket_name, Key=event_object_key)
logger.info(
f'I-05-01 受信ファイルの転送完了:{destination_bucket}/{destination_folder}/{event_file_name}')
# ⑧ メモリに保持したバケット名/フォルダ名内の「受信データファイル名.doing」ファイルを削除する
delete_doing_file(event)
logger.info('I-06-01 処理終了 S3バケット間ファイル転送処理')
except Exception as e:
logger.exception(
f'E-99 想定外のエラーが発生しました。処理を終了します。ファイル名フルパス: {event_bucket_name}/{event_object_key} 例外内容:{e}'
)
delete_doing_file(event)
raise e
return
# 動作確認用のコード
# if __name__ == '__main__':
# lambda_handler(
# {
# "Records": [
# {
# "eventVersion": "2.1",
# "eventSource": "aws:s3",
# "awsRegion": "ap-northeast-1",
# "eventTime": "2024-07-16T07:10:33.021Z",
# "eventName": "ObjectCreated:Put",
# "userIdentity": {
# "principalId": "AWS:AIDA4A3J5AIPDAT6MUJPZ"
# },
# "requestParameters": {
# "sourceIPAddress": "118.238.231.215"
# },
# "responseElements": {
# "x-amz-request-id": "0BST21P92A15BH55",
# "x-amz-id-2": "db9n9RpQxHEnq5o5ZLCeIGpuka54ghMHcbJ2Rj9aCcpjf111D4dyTZn5w5VvzV6W56rU89cSx/ihzkEHs8wk30ckbtRMYQ0byJn0UfK6bjg="
# },
# "s3": {
# "s3SchemaVersion": "1.0",
# "configurationId": "accesslog-receive-event2",
# "bucket": {
# "name": "mbj-newdwh2021-staging-hcp-web-receive",
# "ownerIdentity": {
# "principalId": "A1YQ10QIZBI5OE"
# },
# "arn": "arn:aws:s3:::mbj-newdwh2021-staging-hcp-web-receive"
# },
# "object": {
# "key": "palantir/hcpweb_accesslog_2024-07-16-071045.csv",
# "size": 597820,
# "eTag": "94299e880925b6f655c090521ff83d7a",
# "sequencer": "0066961CE8E7A670F2"
# }
# }
# }
# ]
# },
# None
# )

View File

@ -0,0 +1,48 @@
-- A5M2で実行時に[SQL] - [スラッシュ(/)のみの行でSQLを区切る]に変えてから実行する
-- $$から始まる文字は後からREPLACEする文字を示す独自ルール
-- crm_data_syncストアドプロシージャは、同一セッション内での並列処理を実行することができない
-- 実行者の権限でストアドプロシージャを実行するために、「SQL SECURITY INVOKER」を付与している
CREATE PROCEDURE src02.crm_data_sync(target_table VARCHAR(255), target_table_all VARCHAR(255), target_column VARCHAR(255))
SQL SECURITY INVOKER
BEGIN
-- 例外処理
-- エラーが発生した場合に一時テーブルの削除を実施
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
@error_state = RETURNED_SQLSTATE, @error_msg = MESSAGE_TEXT;
ROLLBACK;
SIGNAL SQLSTATE '45000'
SET MYSQL_ERRNO = @error_state, MESSAGE_TEXT = @error_msg;
END;
SET @error_state = NULL, @error_msg = NULL;
START TRANSACTION;
-- ①-1 Salesforce側で物理削除されたデータを検出し更新する
SET @update_end_datetime = '
UPDATE $$target_table$$ tt
SET
tt.end_datetime = CURRENT_TIMESTAMP ()
, tt.upd_user = CURRENT_USER ()
, tt.upd_date = CURRENT_TIMESTAMP ()
WHERE
tt.end_datetime = "9999-12-31 00:00:00"
AND NOT EXISTS (
SELECT
tta.Id
FROM
$$target_table_all$$ tta
WHERE
tt.Id = tta.Id
AND tt.$$target_column$$ = tta.$$target_column$$
)
';
SET @update_end_datetime = REPLACE(@update_end_datetime, "$$target_table$$", target_table);
SET @update_end_datetime = REPLACE(@update_end_datetime, "$$target_table_all$$", target_table_all);
SET @update_end_datetime = REPLACE(@update_end_datetime, "$$target_column$$", target_column);
PREPARE update_end_datetime_stmt from @update_end_datetime;
EXECUTE update_end_datetime_stmt;
COMMIT;
END

View File

@ -0,0 +1,95 @@
-- A5M2で実行時に[SQL] - [スラッシュ(/)のみの行でSQLを区切る]に変えてから実行する
-- $$から始まり$$で終わる文字は後からREPLACEする文字を示す独自ルール
-- crm_historyストアドプロシージャは、同一セッション内での並列処理を実行することができない
-- 実行者の権限でストアドプロシージャを実行するために、「SQL SECURITY INVOKER」を付与している
CREATE PROCEDURE src02.crm_history(target_table VARCHAR(255), target_column VARCHAR(255))
SQL SECURITY INVOKER
BEGIN
-- 例外処理
-- エラーが発生した場合に一時テーブルの削除を実施
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
@error_state = RETURNED_SQLSTATE, @error_msg = MESSAGE_TEXT;
EXECUTE drop_tmp_table_stmt;
DEALLOCATE PREPARE drop_tmp_table_stmt;
ROLLBACK;
SIGNAL SQLSTATE '45000'
SET MYSQL_ERRNO = @error_state, MESSAGE_TEXT = @error_msg;
END;
SET @error_state = NULL, @error_msg = NULL;
START TRANSACTION;
-- ②-3で利用する一時テーブル削除のSQLを準備
-- 例外処理でも利用するため先に記述
SET @drop_tmp_table = '
DROP TEMPORARY TABLE IF EXISTS $$target_table$$_make_history_tmp
';
SET @drop_tmp_table = REPLACE(@drop_tmp_table, "$$target_table$$", target_table);
PREPARE drop_tmp_table_stmt from @drop_tmp_table;
-- ①-1 Salesforce側で更新されたデータの適用開始日時と適用終了日時を設定する
SET @new_history_save = '
UPDATE $$target_table$$
SET
start_datetime = $$target_column$$
, end_datetime = "9999-12-31 00:00:00"
, upd_user = CURRENT_USER()
, upd_date = CURRENT_TIMESTAMP()
WHERE
start_datetime IS NULL
AND end_datetime IS NULL
';
SET @new_history_save = REPLACE(@new_history_save, "$$target_table$$", target_table);
SET @new_history_save = REPLACE(@new_history_save, "$$target_column$$", target_column);
PREPARE new_history_save_stmt from @new_history_save;
EXECUTE new_history_save_stmt;
DEALLOCATE PREPARE new_history_save_stmt;
-- ②-1 Salesforce側で更新されたデータを検出用一時テーブルの作成
SET @make_history_tmp_create = '
CREATE TEMPORARY TABLE $$target_table$$_make_history_tmp
SELECT
Id
, MIN($$target_column$$) AS min_start_datetime
, MAX(start_datetime) AS max_start_datetime
FROM
$$target_table$$
WHERE
end_datetime = "9999-12-31 00:00:00"
GROUP BY
Id
HAVING
count(Id) = 2
';
SET @make_history_tmp_create = REPLACE(@make_history_tmp_create, "$$target_table$$", target_table);
SET @make_history_tmp_create = REPLACE(@make_history_tmp_create, "$$target_column$$", target_column);
PREPARE make_history_tmp_create_stmt from @make_history_tmp_create;
EXECUTE make_history_tmp_create_stmt;
DEALLOCATE PREPARE make_history_tmp_create_stmt;
-- ②-2 「②-1」で取得した全件に更新処理を行う
SET @update_end_datetime = '
UPDATE $$target_table$$ tt
INNER JOIN $$target_table$$_make_history_tmp mht
ON tt.Id = mht.Id
AND tt.start_datetime = mht.min_start_datetime
SET
end_datetime = mht.max_start_datetime - INTERVAL 1 SECOND
, upd_user = CURRENT_USER()
, upd_date = CURRENT_TIMESTAMP()
';
SET @update_end_datetime = REPLACE(@update_end_datetime, "$$target_table$$", target_table);
SET @update_end_datetime = REPLACE(@update_end_datetime, "$$target_column$$", target_column);
PREPARE update_end_datetime_stmt from @update_end_datetime;
EXECUTE update_end_datetime_stmt;
DEALLOCATE PREPARE update_end_datetime_stmt;
-- ②-3 「②-1」で作成した一時テーブルを削除する
EXECUTE drop_tmp_table_stmt;
DEALLOCATE PREPARE drop_tmp_table_stmt;
COMMIT;
END

View File

@ -84,7 +84,7 @@ SET @upsert_statement_base =
MSJ_SIPAGL_comment__c, MSJ_SIPAGL_4B__c, MSJ_SIPAGL_5B__c, Location_Text_vod__c, Call_Channel_vod__c, MSJ_SIPAGL_comment__c, MSJ_SIPAGL_4B__c, MSJ_SIPAGL_5B__c, Location_Text_vod__c, Call_Channel_vod__c,
MSJ_Scientific_Interaction__c, MSJ_Activity_Email_Reply__c, MSJ_Interaction_Duration__c, MSJ_SIPAGL_1A_date__c, MSJ_Scientific_Interaction__c, MSJ_Activity_Email_Reply__c, MSJ_Interaction_Duration__c, MSJ_SIPAGL_1A_date__c,
MSJ_CoPromotion__c, Call_Channel_Formula_vod__c, Meeting_Request_vod__c, Phone_vod__c, Detail_Section_Attribute_vod__c, Remote_Meeting_Type_vod__c, MSJ_CoPromotion__c, Call_Channel_Formula_vod__c, Meeting_Request_vod__c, Phone_vod__c, Detail_Section_Attribute_vod__c, Remote_Meeting_Type_vod__c,
MSJ_SIPAGL_6__c,file_name, file_row_cnt, delete_flg, ins_user, ins_date, upd_user, upd_date) file_name, file_row_cnt, delete_flg, ins_user, ins_date, upd_user, upd_date)
SELECT SELECT
Id, OwnerId, IsDeleted, Name, RecordTypeId, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, Id, OwnerId, IsDeleted, Name, RecordTypeId, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById,
SystemModstamp, LastActivityDate, MayEdit, IsLocked, LastViewedDate, LastReferencedDate, Call_Comments_vod__c, SystemModstamp, LastActivityDate, MayEdit, IsLocked, LastViewedDate, LastReferencedDate, Call_Comments_vod__c,
@ -130,7 +130,7 @@ SET @upsert_statement_base =
MSJ_SIPAGL_comment__c, MSJ_SIPAGL_4B__c, MSJ_SIPAGL_5B__c, Location_Text_vod__c, Call_Channel_vod__c, MSJ_SIPAGL_comment__c, MSJ_SIPAGL_4B__c, MSJ_SIPAGL_5B__c, Location_Text_vod__c, Call_Channel_vod__c,
MSJ_Scientific_Interaction__c, MSJ_Activity_Email_Reply__c, MSJ_Interaction_Duration__c, MSJ_SIPAGL_1A_date__c, MSJ_Scientific_Interaction__c, MSJ_Activity_Email_Reply__c, MSJ_Interaction_Duration__c, MSJ_SIPAGL_1A_date__c,
MSJ_CoPromotion__c, Call_Channel_Formula_vod__c, Meeting_Request_vod__c, Phone_vod__c, Detail_Section_Attribute_vod__c, Remote_Meeting_Type_vod__c, MSJ_CoPromotion__c, Call_Channel_Formula_vod__c, Meeting_Request_vod__c, Phone_vod__c, Detail_Section_Attribute_vod__c, Remote_Meeting_Type_vod__c,
MSJ_SIPAGL_6__c,file_name, file_row_cnt, delete_flg, ins_user, ins_date, upd_user, upd_date file_name, file_row_cnt, delete_flg, ins_user, ins_date, upd_user, upd_date
FROM FROM
internal02.crm_Call2_vod__c AS internaltb internal02.crm_Call2_vod__c AS internaltb
WHERE WHERE
@ -246,7 +246,7 @@ SET @upsert_statement_base =
Call_Channel_Formula_vod__c = internaltb.Call_Channel_Formula_vod__c, Call_Channel_Formula_vod__c = internaltb.Call_Channel_Formula_vod__c,
Meeting_Request_vod__c = internaltb.Meeting_Request_vod__c, Phone_vod__c = internaltb.Phone_vod__c, Meeting_Request_vod__c = internaltb.Meeting_Request_vod__c, Phone_vod__c = internaltb.Phone_vod__c,
Detail_Section_Attribute_vod__c = internaltb.Detail_Section_Attribute_vod__c, Remote_Meeting_Type_vod__c = internaltb.Remote_Meeting_Type_vod__c, Detail_Section_Attribute_vod__c = internaltb.Detail_Section_Attribute_vod__c, Remote_Meeting_Type_vod__c = internaltb.Remote_Meeting_Type_vod__c,
MSJ_SIPAGL_6__c = internaltb.MSJ_SIPAGL_6__c,file_name = internaltb.file_name, file_row_cnt = internaltb.file_row_cnt, file_name = internaltb.file_name, file_row_cnt = internaltb.file_row_cnt,
upd_user = CURRENT_USER(), upd_date = CURRENT_TIMESTAMP();'; upd_user = CURRENT_USER(), upd_date = CURRENT_TIMESTAMP();';
OPEN table_cursor; OPEN table_cursor;

View File

@ -1,17 +0,0 @@
-- A5M2で実行時に[SQL] - [スラッシュ(/)のみの行でSQLを区切る]に変えてから実行する
CREATE FUNCTION medaca_common.convert_to_date(date_string VARCHAR(255), _format VARCHAR(50)) RETURNS datetime
DETERMINISTIC
BEGIN
DECLARE converted_date DATETIME;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- エラー発生時にNULLを返す
RETURN NULL;
END;
-- 日付変換の実行
SET converted_date = STR_TO_DATE(date_string, _format);
RETURN converted_date;
END

View File

@ -1,12 +1,12 @@
2025/01/03 2024/01/03
2025/02/03 2024/02/03
2025/03/03 2024/03/03
2025/04/03 2024/04/03
2025/05/03 2024/05/03
2025/06/03 2024/06/03
2025/07/03 2024/07/03
2025/08/03 2024/08/03
2025/09/03 2024/09/03
2025/10/03 2024/10/03
2025/11/03 2024/11/03
2025/12/03 2024/12/03

View File

@ -1,6 +1,6 @@
宛先各位 宛先各位
 SAP月次連携として、以下のファイルを受領しましたので通知いたします。  SAP月次I/Fである以下のファイルを受領しましたので、通知いたします。
{notice_file_names} {notice_file_names}
 尚、本メールはシステム自動送信のため、返信は出来ません。  尚、本メールはシステム自動送信のため、返信は出来ません。
 本件に関する問い合わせは、SAP担当者にお願いいたします。  本件に関する問い合わせは、IT部門 ゴザリ様にお願いいたします。

View File

@ -1 +1 @@
【MeDaCa連携通知】SAP Finance 月次連携ファイルを受領しました 【MeDaCa連携通知】SAP Finance 月次ファイルを受領しました

View File

@ -1,8 +1,8 @@
宛先各位 宛先各位
 SAP日次連携として、以下のファイルを受領できておりません。  SAP日次I/Fである以下のファイルを受領できておりません。
{notice_file_names} {notice_file_names}
 SAPシステム側のSFTP送信状況のご確認をお願いいたします。  SAPシステム側のSFTP送信状況のご確認をお願いいたします。
 尚、本メールはシステム自動送信のため、返信は出来ません。  尚、本メールはシステム自動送信のため、返信は出来ません。
 本件に関する問い合わせは、SAP担当者にお願いいたします。  本件に関する問い合わせは、IT部門 ゴザリ様にお願いいたします。

View File

@ -1,8 +1,8 @@
宛先各位 宛先各位
 SAP月次連携として、以下のファイルを受領できておりません。  SAP月次I/Fである以下のファイルを受領できておりません。
{notice_file_names} {notice_file_names}
 SAPシステム側のSFTP送信状況のご確認をお願いいたします。  SAPシステム側のSFTP送信状況のご確認をお願いいたします。
 尚、本メールはシステム自動送信のため、返信は出来ません。  尚、本メールはシステム自動送信のため、返信は出来ません。
 本件に関する問い合わせは、SAP担当者にお願いいたします。  本件に関する問い合わせは、IT部門 ゴザリ様にお願いいたします。

View File

@ -1 +1 @@
【MeDaCa連携エラー通知】SAP Finance 日次連携ファイル未受領 【MeDaCa連携エラー通知】SAP Finance 日次ファイル未受領

View File

@ -1 +1 @@
【MeDaCa連携エラー通知】SAP Finance 月次連携ファイル未受領 【MeDaCa連携エラー通知】SAP Finance 月次ファイル未受領

View File

@ -1,6 +1,6 @@
宛先各位 宛先各位
 SAP月次連携として、以下のファイルを受領しましたので通知いたします。  SAP月次I/Fである以下のファイルを受領しましたので、通知いたします。
{notice_file_names} {notice_file_names}
 尚、本メールはシステム自動送信のため、返信は出来ません。  尚、本メールはシステム自動送信のため、返信は出来ません。
 本件に関する問い合わせは、SAP担当者にお願いいたします。  本件に関する問い合わせは、IT部門 ゴザリ様にお願いいたします。

View File

@ -1 +1 @@
【MeDaCa連携通知】SAP SupplyChain 月次連携ファイルを受領しました 【MeDaCa連携通知】SAP SupplyChain 月次ファイルを受領しました

View File

@ -1,8 +1,8 @@
宛先各位 宛先各位
 SAP日次連携として、以下のファイルを受領できておりません。  SAP日次I/Fである以下のファイルを受領できておりません。
{notice_file_names} {notice_file_names}
 SAPシステム側のSFTP送信状況のご確認をお願いいたします。  SAPシステム側のSFTP送信状況のご確認をお願いいたします。
 尚、本メールはシステム自動送信のため、返信は出来ません。  尚、本メールはシステム自動送信のため、返信は出来ません。
 本件に関する問い合わせは、SAP担当者にお願いいたします。  本件に関する問い合わせは、IT部門 ゴザリ様にお願いいたします。

View File

@ -1,8 +1,8 @@
宛先各位 宛先各位
 SAP月次連携として、以下のファイルを受領できておりません。  SAP月次I/Fである以下のファイルを受領できておりません。
{notice_file_names} {notice_file_names}
 SAPシステム側のSFTP送信状況のご確認をお願いいたします。  SAPシステム側のSFTP送信状況のご確認をお願いいたします。
 尚、本メールはシステム自動送信のため、返信は出来ません。  尚、本メールはシステム自動送信のため、返信は出来ません。
 本件に関する問い合わせは、SAP担当者にお願いいたします。  本件に関する問い合わせは、IT部門 ゴザリ様にお願いいたします。

Some files were not shown because too many files have changed in this diff Show More