From 7f82cc9e48208adf765802b08590c89f1c78ccbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Fri, 23 Jun 2023 14:20:48 +0900 Subject: [PATCH 01/28] =?UTF-8?q?=E7=92=B0=E5=A2=83=E6=A7=8B=E7=AF=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/.dockerignore | 12 + ecs/jskult-batch-monthly/.env.example | 22 + ecs/jskult-batch-monthly/.gitignore | 10 + ecs/jskult-batch-monthly/.vscode/launch.json | 16 + .../.vscode/recommended_settings.json | 31 ++ ecs/jskult-batch-monthly/Dockerfile | 20 + ecs/jskult-batch-monthly/Pipfile | 26 ++ ecs/jskult-batch-monthly/Pipfile.lock | 387 ++++++++++++++++++ ecs/jskult-batch-monthly/README.md | 48 +++ ecs/jskult-batch-monthly/entrypoint.py | 10 + ecs/jskult-batch-monthly/src/__init__.py | 0 ecs/jskult-batch-monthly/src/aws/__init__.py | 0 ecs/jskult-batch-monthly/src/aws/s3.py | 98 +++++ .../src/batch/batch_functions.py | 101 +++++ .../src/batch/common/__init__.py | 0 .../src/batch/common/batch_context.py | 37 ++ .../src/batch/common/calendar_file.py | 32 ++ .../src/batch/parallel_processes.py | 32 ++ ecs/jskult-batch-monthly/src/db/__init__.py | 0 ecs/jskult-batch-monthly/src/db/database.py | 178 ++++++++ .../src/error/__init__.py | 0 .../src/error/exceptions.py | 10 + .../src/jobctrl_monthly.py | 88 ++++ .../src/logging/get_logger.py | 37 ++ .../src/system_var/__init__.py | 0 .../src/system_var/constants.py | 17 + .../src/system_var/environment.py | 25 ++ .../src/time/elapsed_time.py | 22 + .../calendar/jskult_arisj_output_day_list.txt | 100 +++++ 29 files changed, 1359 insertions(+) create mode 100644 ecs/jskult-batch-monthly/.dockerignore create mode 100644 ecs/jskult-batch-monthly/.env.example create mode 100644 ecs/jskult-batch-monthly/.gitignore create mode 100644 ecs/jskult-batch-monthly/.vscode/launch.json create mode 100644 ecs/jskult-batch-monthly/.vscode/recommended_settings.json create mode 100644 ecs/jskult-batch-monthly/Dockerfile create mode 100644 ecs/jskult-batch-monthly/Pipfile create mode 100644 ecs/jskult-batch-monthly/Pipfile.lock create mode 100644 ecs/jskult-batch-monthly/README.md create mode 100644 ecs/jskult-batch-monthly/entrypoint.py create mode 100644 ecs/jskult-batch-monthly/src/__init__.py create mode 100644 ecs/jskult-batch-monthly/src/aws/__init__.py create mode 100644 ecs/jskult-batch-monthly/src/aws/s3.py create mode 100644 ecs/jskult-batch-monthly/src/batch/batch_functions.py create mode 100644 ecs/jskult-batch-monthly/src/batch/common/__init__.py create mode 100644 ecs/jskult-batch-monthly/src/batch/common/batch_context.py create mode 100644 ecs/jskult-batch-monthly/src/batch/common/calendar_file.py create mode 100644 ecs/jskult-batch-monthly/src/batch/parallel_processes.py create mode 100644 ecs/jskult-batch-monthly/src/db/__init__.py create mode 100644 ecs/jskult-batch-monthly/src/db/database.py create mode 100644 ecs/jskult-batch-monthly/src/error/__init__.py create mode 100644 ecs/jskult-batch-monthly/src/error/exceptions.py create mode 100644 ecs/jskult-batch-monthly/src/jobctrl_monthly.py create mode 100644 ecs/jskult-batch-monthly/src/logging/get_logger.py create mode 100644 ecs/jskult-batch-monthly/src/system_var/__init__.py create mode 100644 ecs/jskult-batch-monthly/src/system_var/constants.py create mode 100644 ecs/jskult-batch-monthly/src/system_var/environment.py create mode 100644 ecs/jskult-batch-monthly/src/time/elapsed_time.py create mode 100644 s3/config/jskult/calendar/jskult_arisj_output_day_list.txt diff --git a/ecs/jskult-batch-monthly/.dockerignore b/ecs/jskult-batch-monthly/.dockerignore new file mode 100644 index 00000000..8b9da402 --- /dev/null +++ b/ecs/jskult-batch-monthly/.dockerignore @@ -0,0 +1,12 @@ +tests/* +.coverage +.env +.env.example +.report/* +.vscode/* +.pytest_cache/* +*/__pychache__/* +Dockerfile +pytest.ini +README.md +*.sql diff --git a/ecs/jskult-batch-monthly/.env.example b/ecs/jskult-batch-monthly/.env.example new file mode 100644 index 00000000..19a3f19f --- /dev/null +++ b/ecs/jskult-batch-monthly/.env.example @@ -0,0 +1,22 @@ +DB_HOST=************ +DB_PORT=************ +DB_USERNAME=************ +DB_PASSWORD=************ +DB_SCHEMA=src05 +LOG_LEVEL=INFO +ULTMARC_DATA_BUCKET=**************** +ULTMARC_DATA_FOLDER=recv +JSKULT_BACKUP_BUCKET=**************** +ULTMARC_BACKUP_FOLDER=ultmarc +JSKULT_CONFIG_BUCKET=********************** +JSKULT_CONFIG_CALENDAR_FOLDER=jskult/calendar +JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME=jskult_holiday_list.txt +ARISJ_DATA_BUCKET=********** +LOG_LEVEL=************** +ARISJ_BACKUP_FOLDER=************** +JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME=jskult_arisj_output_day_list.txt +DB_CONNECTION_MAX_RETRY_ATTEMPT=************** +DB_CONNECTION_RETRY_INTERVAL_INIT=************** +DB_CONNECTION_RETRY_INTERVAL_MIN_SECONDS=************** +DB_CONNECTION_RETRY_INTERVAL_MAX_SECONDS=************* +VJSK_DATA_BUCKET=************* \ No newline at end of file diff --git a/ecs/jskult-batch-monthly/.gitignore b/ecs/jskult-batch-monthly/.gitignore new file mode 100644 index 00000000..bd0b37f8 --- /dev/null +++ b/ecs/jskult-batch-monthly/.gitignore @@ -0,0 +1,10 @@ +.vscode/settings.json +.env + +# python +__pycache__ + +# python test +.pytest_cache +.coverage +.report/ \ No newline at end of file diff --git a/ecs/jskult-batch-monthly/.vscode/launch.json b/ecs/jskult-batch-monthly/.vscode/launch.json new file mode 100644 index 00000000..e0267567 --- /dev/null +++ b/ecs/jskult-batch-monthly/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // IntelliSense を使用して利用可能な属性を学べます。 + // 既存の属性の説明をホバーして表示します。 + // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(DEBUG)jskult batch monthly", + "type": "python", + "request": "launch", + "program": "entrypoint.py", + "console": "integratedTerminal", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/ecs/jskult-batch-monthly/.vscode/recommended_settings.json b/ecs/jskult-batch-monthly/.vscode/recommended_settings.json new file mode 100644 index 00000000..b5e79d73 --- /dev/null +++ b/ecs/jskult-batch-monthly/.vscode/recommended_settings.json @@ -0,0 +1,31 @@ +{ + "[python]": { + "editor.defaultFormatter": null, + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": true + } + }, + // 自身の環境に合わせて変えてください + "python.defaultInterpreterPath": "", + "python.linting.lintOnSave": true, + "python.linting.enabled": true, + "python.linting.pylintEnabled": false, + "python.linting.flake8Enabled": true, + "python.linting.flake8Args": [ + "--max-line-length=200", + "--ignore=F541" + ], + "python.formatting.provider": "autopep8", + "python.formatting.autopep8Path": "autopep8", + "python.formatting.autopep8Args": [ + "--max-line-length", "200", + "--ignore=F541" + ], + "python.testing.pytestArgs": [ + "tests/batch/ultmarc" + ], + + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} diff --git a/ecs/jskult-batch-monthly/Dockerfile b/ecs/jskult-batch-monthly/Dockerfile new file mode 100644 index 00000000..dd891d48 --- /dev/null +++ b/ecs/jskult-batch-monthly/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.9 + +ENV TZ="Asia/Tokyo" + +WORKDIR /usr/src/app +COPY Pipfile Pipfile.lock ./ +RUN \ + apt update -y && \ + # パッケージのセキュリティアップデートのみを適用するコマンド + apt install -y unattended-upgrades && \ + unattended-upgrades && \ + pip install --upgrade pip wheel setuptools && \ + pip install pipenv --no-cache-dir && \ + pipenv install --system --deploy && \ + pip uninstall -y pipenv virtualenv-clone virtualenv + +COPY src ./src +COPY entrypoint.py entrypoint.py + +CMD ["python", "entrypoint.py"] diff --git a/ecs/jskult-batch-monthly/Pipfile b/ecs/jskult-batch-monthly/Pipfile new file mode 100644 index 00000000..24e5efcd --- /dev/null +++ b/ecs/jskult-batch-monthly/Pipfile @@ -0,0 +1,26 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[scripts] +"test:ultmarc" = "pytest tests/batch/ultmarc/" +"test:ultmarc:cov" = "pytest --cov=src/batch/ultmarc/ --cov-branch --cov-report=term-missing tests/batch/ultmarc/" + +[packages] +boto3 = "*" +sqlalchemy = "*" +tenacity = "*" +pymysql = "*" + +[dev-packages] +autopep8 = "*" +flake8 = "*" +pytest = "*" +pytest-cov = "*" + +[requires] +python_version = "3.9" + +[pipenv] +allow_prereleases = true diff --git a/ecs/jskult-batch-monthly/Pipfile.lock b/ecs/jskult-batch-monthly/Pipfile.lock new file mode 100644 index 00000000..3e58b727 --- /dev/null +++ b/ecs/jskult-batch-monthly/Pipfile.lock @@ -0,0 +1,387 @@ +{ + "_meta": { + "hash": { + "sha256": "0b1dbc40a5069476aa66f172175ae24ffae385c335ff8e4794c1b25a111b9e43" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.9" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "boto3": { + "hashes": [ + "sha256:7694df61bd6d253d6d9db34adbcd218b8efbe7f894a4a51611f7e0587ae33218", + "sha256:fe49f91e057b241b23a58c74c2f22654216788052ce95b73439fdb18bfd0e155" + ], + "index": "pypi", + "version": "==1.26.159" + }, + "botocore": { + "hashes": [ + "sha256:86fe4641fd32dc6a5be4a289e00dc180448fc7bc37abac21bd624656985eef62", + "sha256:da1c61757d466b82cc89f379a50662064bcb0beb67cc6efa1fbfc9a341bd08b0" + ], + "markers": "python_version >= '3.7'", + "version": "==1.29.159" + }, + "greenlet": { + "hashes": [ + "sha256:0a9dfcadc1d79696e90ccb1275c30ad4ec5fd3d1ab3ae6671286fac78ef33435", + "sha256:0f313771cb8ee0a04dfdf586b7d4076180d80c94be09049daeea018089b5b957", + "sha256:17503397bf6cbb5e364217143b6150c540020c51a3f6b08f9a20cd67c25e2ca8", + "sha256:180ec55cb127bc745669eddc9793ffab6e0cf7311e67e1592f183d6ca00d88c1", + "sha256:1b3f3568478bc21b85968e8038c4f98f4bf0039a692791bc324b5e0d1522f4b1", + "sha256:1bd4ea36f0aeb14ca335e0c9594a5aaefa1ac4e2db7d86ba38f0be96166b3102", + "sha256:21ebcb570e0d8501457d6a2695a44c5af3b6c2143dc6644ec73574beba067c90", + "sha256:24071eee113d75fedebaeb86264d94f04b5a24e311c5ba3e8003c07d00112a7e", + "sha256:270432cfdd6a50016b8259b3bbf398a3f7c06a06f2c68c7b93e49f53bc193bcf", + "sha256:271ed380389d2f7e4c1545b6e0837986e62504ab561edbaff05da9c9f3f98f96", + "sha256:2840187a94e258445e62ff1545e34f0b1a14aef4d0078e5c88246688d2b6515e", + "sha256:2cda110faee67613fed221f90467003f477088ef1cc84c8fc88537785a5b4de9", + "sha256:2e160a65cc6023a237be870f2072513747d512a1d018efa083acce0b673cccc0", + "sha256:2fcf7af83516db35af3d0ed5d182dea8585eddd891977adff1b74212f4bfd2fd", + "sha256:36cebce1f30964d5672fd956860e7e7b69772da69658d5743cb676b442eeff36", + "sha256:42bfe67824a9b53e73f568f982f0d1d4c7ac0f587d2e702a23f8a7b505d7b7c2", + "sha256:450a7e52a515402fd110ba807f1a7d464424bfa703be4effbcb97e1dfbfcc621", + "sha256:463d63ca5d8c236788284a9a44b9715372a64d5318a6b5eee36815df1ea0ba3d", + "sha256:4d0c0ffd732466ff324ced144fad55ed5deca36f6036c1d8f04cec69b084c9d6", + "sha256:4ff2a765f4861fc018827eab4df1992f7508d06c62de5d2fe8a6ac2233d4f1d0", + "sha256:53abf19b7dc62795c67b8d0a3d8ef866db166b21017632fff2624cf8fbf3481c", + "sha256:5552d7be37d878e9b6359bbffa0512d857bb9703616a4c0656b49c10739d5971", + "sha256:585810056a8adacd3152945ebfcd25deb58335d41f16ae4e0f3d768918957f9a", + "sha256:5942b1d6ba447cff1ec23a21ec525dde2288f00464950bc647f4e0f03bd537d1", + "sha256:5c355c99be5bb23e85d899b059a4f22fdf8a0741c57e7029425ee63eb436f689", + "sha256:5f61df4fe07864561f49b45c8bd4d2c42e3f03d2872ed05c844902a58b875028", + "sha256:665942d3a954c3e4c976581715f57fb3b86f4cf6bae3ac30b133f8ff777ac6c7", + "sha256:68368e908f14887fb202a81960bfbe3a02d97e6d3fa62b821556463084ffb131", + "sha256:6aac94ff957b5dea0216af71ab59c602e1b947b394e4f5e878a5a65643090038", + "sha256:889934aa8d72b6bfc46babd1dc4b817a56c97ec0f4a10ae7551fb60ab1f96fae", + "sha256:a00550757fca1b9cbc479f8eb1cf3514dbc0103b3f76eae46341c26ddcca67a9", + "sha256:a4a2d6ed0515c05afd5cc435361ced0baabd9ba4536ddfe8ad9a95bcb702c8ce", + "sha256:a8dd92fd76a61af2abc8ccad0c6c6069b3c4ebd4727ecc9a7c33aae37651c8c7", + "sha256:ab81f9ff3e3c2ca65e824454214c10985a846cd9bee5f4d04e15cd875d9fe13b", + "sha256:ac10196b8cde7a082e4e371ff171407270d3337c8d57ed43030094eb01d9c95c", + "sha256:b767930af686551dc96a5eb70af3736709d547ffa275c11a5e820bfb3ae61d8d", + "sha256:b9a1f4d256b81f59ba87bb7a29b9b38b1c018e052dba60a543cb0ddb5062d159", + "sha256:ba94c08321b5d345100fc64eb1ab235f42faf9aabba805cface55ebe677f1c2c", + "sha256:bab71f73001cd15723c4e2ca398f2f48e0a3f584c619eefddb1525e8986e06eb", + "sha256:bce5cf2b0f0b29680396c5c98ab39a011bd70f2dfa8b8a6811a69ee6d920cf9f", + "sha256:c02e514c72e745e49a3ae7e672a1018ba9b68460c21e0361054e956e5d595bc6", + "sha256:c3fb459ced6c5e3b2a895f23f1400f93e9b24d85c30fbe2d637d4f7706a1116b", + "sha256:cd31ab223e43ac64fd23f8f5dad249addadac2a459f040546200acbf7e84e353", + "sha256:ce70aa089ec589b5d5fab388af9f8c9f9dfe8fe4ad844820a92eb240d8628ddf", + "sha256:d47b2e1ad1429da9aa459ef189fbcd8a74ec28a16bc4c3f5f3cf3f88e36535eb", + "sha256:d61bad421c1f496f9fb6114dbd7c30a1dac0e9ff90e9be06f4472cbd8f7a1704", + "sha256:d7ba2e5cb119eddbc10874b41047ad99525e39e397f7aef500e6da0d6f46ab91", + "sha256:dde0ab052c7a1deee8d13d72c37f2afecee30ebdf6eb139790157eaddf04dd61", + "sha256:df34b52aa50a38d7a79f3abc9fda7e400791447aa0400ed895f275f6d8b0bb1f", + "sha256:e0fc20e6e6b298861035a5fc5dcf9fbaa0546318e8bda81112591861a7dcc28f", + "sha256:e20d5e8dc76b73db9280464d6e81bea05e51a99f4d4dd29c5f78dc79f294a5d3", + "sha256:e31d1a33dc9006b278f72cb0aacfe397606c2693aa2fdc0c2f2dcddbad9e0b53", + "sha256:e3a99f890f2cc5535e1b3a90049c6ca9ff9da9ec251cc130c8d269997f9d32ee", + "sha256:e7b192c3df761d0fdd17c2d42d41c28460f124f5922e8bd524018f1d35610682", + "sha256:ed0f4fad4c3656e34d20323a789b6a2d210a6bb82647d9c86dded372f55c58a1", + "sha256:f34ec09702be907727fd479046193725441aaaf7ed4636ca042734f469bb7451", + "sha256:f3530c0ec1fc98c43d5b7061781a8c55bd0db44f789f8152e19d9526cbed6021", + "sha256:f5672082576d0e9f52fa0fa732ff57254d65faeb4a471bc339fe54b58b3e79d2", + "sha256:ffb9f8969789771e95d3c982a36be81f0adfaa7302a1d56e29f168ca15e284b8" + ], + "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.0a1" + }, + "jmespath": { + "hashes": [ + "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", + "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" + ], + "markers": "python_version >= '3.7'", + "version": "==1.0.1" + }, + "pymysql": { + "hashes": [ + "sha256:766b72e4370aba94e6266a4dbd62c51fbc6a894c38de25a41a8a01f0461a2387", + "sha256:aade29b861e81a3c68a9e90d43f3db257940c0208983a0128b82f1a4cef639aa" + ], + "index": "pypi", + "version": "==1.1.0rc2" + }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.2" + }, + "s3transfer": { + "hashes": [ + "sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346", + "sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9" + ], + "markers": "python_version >= '3.7'", + "version": "==0.6.1" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "sqlalchemy": { + "hashes": [ + "sha256:0db6734cb5644c55d0262a813b764c6e2cda1e66e939a488b3d6298cdc7344c2", + "sha256:0e4645b260cfe375a0603aa117f0a47680864cf37833129da870919e88b08d8f", + "sha256:131f0c894c6572cb1bdcf97c92d999d3128c4ff1ca13061296057072f61afe13", + "sha256:1e2caba78e7d1f5003e88817b7a1754d4e58f4a8f956dc423bf8e304c568ab09", + "sha256:2de1477af7f48c633b8ecb88245aedd811dca88e88aee9e9d787b388abe74c44", + "sha256:2f3b6c31b915159b96b68372212fa77f69230b0a32acab40cf539d2823954f5a", + "sha256:3ef876615ff4b53e2033022195830ec4941a6e21068611f8d77de60203b90a98", + "sha256:43e69c8c1cea0188b7094e22fb93ae1a1890aac748628b7e925024a206f75368", + "sha256:53081c6fce0d49bb36d05f12dc87e008c9b0df58a163b792c5fc4ac638925f98", + "sha256:5a934eff1a2882137be3384826f997db8441d43b61fda3094923e69fffe474be", + "sha256:5e8522b49e0e640287308b68f71cc338446bbe1c226c8f81743baa91b0246e92", + "sha256:61f2035dea56ff1a429077e481496f813378beb02b823d2e3e7eb05bc1a7a8ca", + "sha256:63ea36c08792a7a8a08958bc806ecff6b491386feeaf14607c3d9d2d9325e67f", + "sha256:6e85e315725807c127ad8ba3d628fdb861cf9ebfb0e10c39a97c01e257cdd71b", + "sha256:7641f6ed2682de84d77c4894cf2e43700f3cf7a729361d7f9cac98febf3d8614", + "sha256:7be04dbe3470fe8dd332fdb48c979887c381ef6c635eddf2dec43d2766111be4", + "sha256:81d867c1be5abd49f7e547c108391f371a9d980ba7ec34666c50d683f782b754", + "sha256:8544c6e62eacb77d5106e2055ef10f2407fc0dbd547e879f8745b2032eefd2bc", + "sha256:8d3cbdb2f07fb0e4b897dc1df39166735e194fb946f28f26f4c9f9801c8b24f7", + "sha256:8d6ef848e5afcd1bda3e9a843751f845c0ca888b61e669237680e913d84ec206", + "sha256:8e2569dac4e3cb85365b91ab569d06a221e0e17e65ce59949d00c3958946282b", + "sha256:90d320fde566b864adbc19abb40ecb80f4e25d6f084639969bb972d5cca16858", + "sha256:91eb8f89fcce8f709f8a4d65d265bc48a80264ee14c7c9e955f3222f19b4b39c", + "sha256:a08a791c75d6154d46914d1e23bd81d9455f2950ec1de81f2723848c593d2c8b", + "sha256:a2e9f50a906d0b81292576a9fb458f8cace904c81a67088f4a2ca9ff2856f55d", + "sha256:a5a2856e12cf5f54301ddf043bcbf0552561d61555e1bcf348b63f42b8e1eec2", + "sha256:b2801f85c5c0293aa710f8aa5262c707a83c1c203962ae5a22b4d9095e71aa9d", + "sha256:b72f4e4def50414164a1d899f2ce4e782a029fad0ed5585981d1611e8ae29a74", + "sha256:bdaf89dd82f4a0e1b8b5ffc9cdc0c9551be6175f7eee5af6a838e92ba2e57100", + "sha256:c5e333b81fe10d14efebd4e9429b7bb865ed9463ca8bef07a7136dfa1fd4a37b", + "sha256:ce1fc3f64fd42d5f763d6b83651471f32920338a1ba107a3186211474861af57", + "sha256:d0c96592f54edd571e00ba6b1ed5df8263328ca1da9e78088c0ebc93c2e6562c", + "sha256:dc97238fa44be86971270943a0c21c19ce18b8d1596919048e57912e8abc02cc", + "sha256:e19546924f0cf2ec930d1faf318b7365e5827276410a513340f31a2b423e96a4", + "sha256:f2938edc512dd1fa48653e14c1655ab46144d4450f0e6b33da7acd8ba77fbfd7", + "sha256:f387b496a4c9474d8580195bb2660264a3f295a04d3a9d00f4fa15e9e597427e", + "sha256:f409f35a0330ab0cb18ece736b86d8b8233c64f4461fcb10993f67afc0ac7e5a", + "sha256:f662cf69484c59f8a3435902c40dfc34d86050bdb15e23d437074ce9f153306b", + "sha256:fbcc51fdbc89fafe4f4fe66f59372a8be88ded04de34ef438ab04f980beb12d4", + "sha256:fc1dae11bd5167f9eb53b3ccad24a79813004612141e76de21cf4c028dc30b34", + "sha256:ff6496ad5e9dc8baeb93a151cc2f599d01e5f8928a2aaf0b09a06428fdbaf553" + ], + "index": "pypi", + "version": "==2.0.16" + }, + "tenacity": { + "hashes": [ + "sha256:2f277afb21b851637e8f52e6a613ff08734c347dc19ade928e519d7d2d8569b0", + "sha256:43af037822bd0029025877f3b2d97cc4d7bb0c2991000a3d59d71517c5c969e0" + ], + "index": "pypi", + "version": "==8.2.2" + }, + "typing-extensions": { + "hashes": [ + "sha256:16224afa8cc2b3679dd9e9a1efe719dd2e20a03f0cc2e4cc4c97870ae9622532", + "sha256:3c2c2cd887648efa0ea8f8ba4260a1213058e8e4a25a6a6f4e084740b2c858e2" + ], + "markers": "python_version >= '3.7'", + "version": "==4.7.0rc1" + }, + "urllib3": { + "hashes": [ + "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f", + "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.16" + } + }, + "develop": { + "autopep8": { + "hashes": [ + "sha256:86e9303b5e5c8160872b2f5ef611161b2893e9bfe8ccc7e2f76385947d57a2f1", + "sha256:f9849cdd62108cb739dbcdbfb7fdcc9a30d1b63c4cc3e1c1f893b5360941b61c" + ], + "index": "pypi", + "version": "==2.0.2" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.6" + }, + "coverage": { + "extras": [ + "toml" + ], + "hashes": [ + "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f", + "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2", + "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a", + "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a", + "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01", + "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6", + "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7", + "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f", + "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02", + "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c", + "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063", + "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a", + "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5", + "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959", + "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97", + "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6", + "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f", + "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9", + "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5", + "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f", + "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562", + "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe", + "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9", + "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f", + "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb", + "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb", + "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1", + "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb", + "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250", + "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e", + "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511", + "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5", + "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59", + "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2", + "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d", + "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3", + "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4", + "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de", + "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9", + "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833", + "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0", + "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9", + "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d", + "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050", + "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d", + "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6", + "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353", + "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb", + "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e", + "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8", + "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495", + "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2", + "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd", + "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27", + "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1", + "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818", + "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4", + "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e", + "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850", + "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3" + ], + "markers": "python_version >= '3.7'", + "version": "==7.2.7" + }, + "exceptiongroup": { + "hashes": [ + "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e", + "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785" + ], + "markers": "python_version < '3.11'", + "version": "==1.1.1" + }, + "flake8": { + "hashes": [ + "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7", + "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181" + ], + "index": "pypi", + "version": "==6.0.0" + }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "packaging": { + "hashes": [ + "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", + "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1" + }, + "pluggy": { + "hashes": [ + "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", + "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.0" + }, + "pycodestyle": { + "hashes": [ + "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", + "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610" + ], + "markers": "python_version >= '3.6'", + "version": "==2.10.0" + }, + "pyflakes": { + "hashes": [ + "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf", + "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd" + ], + "markers": "python_version >= '3.6'", + "version": "==3.0.1" + }, + "pytest": { + "hashes": [ + "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295", + "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b" + ], + "index": "pypi", + "version": "==7.3.2" + }, + "pytest-cov": { + "hashes": [ + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" + ], + "index": "pypi", + "version": "==4.1.0" + }, + "tomli": { + "hashes": [ + "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + ], + "markers": "python_version < '3.11'", + "version": "==2.0.1" + } + } +} diff --git a/ecs/jskult-batch-monthly/README.md b/ecs/jskult-batch-monthly/README.md new file mode 100644 index 00000000..acf096d2 --- /dev/null +++ b/ecs/jskult-batch-monthly/README.md @@ -0,0 +1,48 @@ +# 実消化&アルトマーク 月次バッチ + +## 概要 + +実消化&アルトマークの月次バッチ処理。 + +## 環境情報 + +- Python 3.9 +- MySQL 8.23 +- VSCode + +## 環境構築 + +- Python の構築 + + - Merck_NewDWH 開発 2021 の Wiki、[Python 環境構築](https://nds-tyo.backlog.com/alias/wiki/1874930)を参照 + - 「Pipenv の導入」までを行っておくこと + - 構築完了後、プロジェクト配下で以下のコマンドを実行し、Python の仮想環境を作成する + - `pipenv install --dev --python ` + - この手順で出力される仮想環境のパスは、後述する VSCode の設定手順で使用するため、控えておく + +- MySQL の環境構築 + - Windows の場合、以下のリンクからダウンロードする + - + - Docker を利用する場合、「newsdwh-tools」リポジトリの MySQL 設定を使用すると便利 + - 「crm-table-to-ddl」フォルダ内で以下のコマンドを実行すると + - `docker-compose up -d` + - Docker の構築手順は、[Docker のセットアップ手順](https://nds-tyo.backlog.com/alias/wiki/1754332)を参照のこと + - データを投入する + - 立ち上げたデータベースに「src05」スキーマを作成する + - [ローカル開発用データ](https://ndstokyo.sharepoint.com/:f:/r/sites/merck-new-dwh-team/Shared%20Documents/03.NewDWH%E6%A7%8B%E7%AF%89%E3%83%95%E3%82%A7%E3%83%BC%E3%82%BA3/02.%E9%96%8B%E7%99%BA/90.%E9%96%8B%E7%99%BA%E5%85%B1%E6%9C%89/%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E9%96%8B%E7%99%BA%E7%94%A8%E3%83%87%E3%83%BC%E3%82%BF?csf=1&web=1&e=VVcRUs)をダウンロードし、mysql コマンドを使用して復元する + - `mysql -h <ホスト名> -P <ポート> -u <ユーザー名> -p src05 < src05_dump.sql` +- 環境変数の設定 + - 「.env.example」ファイルをコピーし、「.env」ファイルを作成する + - 環境変数を設定する。設定内容は PRJ メンバーより共有を受けてください +- VSCode の設定 + - 「.vscode/recommended_settings.json」ファイルをコピーし、「settings.json」ファイルを作成する + - 「python.defaultInterpreterPath」を、Python の構築手順で作成した仮想環境のパスに変更する + +## 実行 + +- VSCode 上で「F5」キーを押下すると、バッチ処理が起動する。 +- 「entrypoint.py」が、バッチ処理のエントリーポイント。 +- 実際の処理は、「src/jobctrl_daily.py」で行っている。 + + +## フォルダ構成(工事中) diff --git a/ecs/jskult-batch-monthly/entrypoint.py b/ecs/jskult-batch-monthly/entrypoint.py new file mode 100644 index 00000000..191d0eae --- /dev/null +++ b/ecs/jskult-batch-monthly/entrypoint.py @@ -0,0 +1,10 @@ +"""実消化&アルトマーク 日次バッチのエントリーポイント""" +from src import jobctrl_monthly + +if __name__ == '__main__': + try: + exit(jobctrl_monthly.exec()) + except Exception: + # エラーが起きても、正常系のコードで返す。 + # エラーが起きた事実はbatch_process内でログを出す。 + exit(0) diff --git a/ecs/jskult-batch-monthly/src/__init__.py b/ecs/jskult-batch-monthly/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ecs/jskult-batch-monthly/src/aws/__init__.py b/ecs/jskult-batch-monthly/src/aws/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ecs/jskult-batch-monthly/src/aws/s3.py b/ecs/jskult-batch-monthly/src/aws/s3.py new file mode 100644 index 00000000..847f5bad --- /dev/null +++ b/ecs/jskult-batch-monthly/src/aws/s3.py @@ -0,0 +1,98 @@ +import os.path as path +import tempfile + +import boto3 + +from src.system_var import environment + + +class S3Client: + __s3_client = boto3.client('s3') + _bucket_name: str + + def list_objects(self, bucket_name: str, folder_name: str): + response = self.__s3_client.list_objects_v2(Bucket=bucket_name, Prefix=folder_name) + if response['KeyCount'] == 0: + return [] + contents = response['Contents'] + # 末尾がスラッシュで終わるものはフォルダとみなしてスキップする + objects = [{'filename': content['Key'], 'size': content['Size']} for content in contents if not content['Key'].endswith('/')] + return objects + + def copy(self, src_bucket: str, src_key: str, dest_bucket: str, dest_key: str) -> None: + copy_source = {'Bucket': src_bucket, 'Key': src_key} + self.__s3_client.copy(copy_source, dest_bucket, dest_key) + return + + def download_file(self, bucket_name: str, file_key: str, file): + self.__s3_client.download_fileobj( + Bucket=bucket_name, + Key=file_key, + Fileobj=file + ) + return + + def upload_file(self, local_file_path: str, bucket_name: str, file_key: str): + self.__s3_client.upload_file( + local_file_path, + Bucket=bucket_name, + Key=file_key + ) + + def delete_file(self, bucket_name: str, file_key: str): + self.__s3_client.delete_object( + Bucket=bucket_name, + Key=file_key + ) + + +class S3Bucket(): + _s3_client = S3Client() + _bucket_name: str = None + + +class UltmarcBucket(S3Bucket): + _bucket_name = environment.ULTMARC_DATA_BUCKET + _folder = environment.ULTMARC_DATA_FOLDER + + def list_dat_file(self): + return self._s3_client.list_objects(self._bucket_name, self._folder) + + def download_dat_file(self, dat_filename: str): + # 一時ファイルとして保存する + temporary_dir = tempfile.mkdtemp() + temporary_file_path = path.join(temporary_dir, f'{dat_filename.replace(f"{self._folder}/", "")}') + with open(temporary_file_path, mode='wb') as f: + self._s3_client.download_file(self._bucket_name, dat_filename, f) + f.seek(0) + return temporary_file_path + + def backup_dat_file(self, dat_file_key: str, datetime_key: str): + # バックアップバケットにコピー + ultmarc_backup_bucket = UltmarcBackupBucket() + backup_key = f'{ultmarc_backup_bucket._folder}/{datetime_key}/{dat_file_key.replace(f"{self._folder}/", "")}' + self._s3_client.copy(self._bucket_name, dat_file_key, ultmarc_backup_bucket._bucket_name, backup_key) + # コピー元のファイルを削除 + self._s3_client.delete_file(self._bucket_name, dat_file_key) + + +class ConfigBucket(S3Bucket): + _bucket_name = environment.JSKULT_CONFIG_BUCKET + + def download_arisj_output_day_list(self): + # 一時ファイルとして保存する + temporary_dir = tempfile.mkdtemp() + temporary_file_path = path.join(temporary_dir, environment.JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME) + arisj_output_day_list_key = f'{environment.JSKULT_CONFIG_CALENDAR_FOLDER}/{environment.JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME}' + with open(temporary_file_path, mode='wb') as f: + self._s3_client.download_file(self._bucket_name, arisj_output_day_list_key, f) + f.seek(0) + return temporary_file_path + + +class JskUltBackupBucket(S3Bucket): + _bucket_name = environment.JSKULT_BACKUP_BUCKET + + +class UltmarcBackupBucket(JskUltBackupBucket): + _folder = environment.ULTMARC_BACKUP_FOLDER diff --git a/ecs/jskult-batch-monthly/src/batch/batch_functions.py b/ecs/jskult-batch-monthly/src/batch/batch_functions.py new file mode 100644 index 00000000..27aac450 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/batch/batch_functions.py @@ -0,0 +1,101 @@ +"""バッチ処理の共通関数""" +import logging +import textwrap +from datetime import datetime + +from src.db.database import Database +from src.error.exceptions import BatchOperationException, DBException +from src.system_var import constants + + +def get_batch_statuses() -> tuple[str, str, str]: + """日付テーブルから、以下を取得して返す。 + - バッチ処理中フラグ + - dump取得状況区分 + - 処理日(YYYY/MM/DD) + + Raises: + BatchOperationException: 日付テーブルが取得できないとき、何らかのエラーが発生したとき + + Returns: + tuple[str, str]: [0]バッチ処理中フラグ、dump取得状況区分 + """ + db = Database.get_instance() + sql = 'SELECT bch_actf, dump_sts_kbn, src05.get_syor_date() AS syor_date FROM src05.hdke_tbl' + try: + db.connect() + hdke_tbl_result = db.execute_select(sql) + except DBException as e: + raise BatchOperationException(e) + finally: + db.disconnect() + + if len(hdke_tbl_result) == 0: + raise BatchOperationException('日付テーブルが取得できませんでした') + + # 必ず1件取れる + hdke_tbl_record = hdke_tbl_result[0] + batch_processing_flag = hdke_tbl_record['bch_actf'] + dump_status_kbn = hdke_tbl_record['dump_sts_kbn'] + syor_date = hdke_tbl_record['syor_date'] + # 処理日を文字列に変換する + syor_date_str = datetime.strftime(syor_date, '%Y/%m/%d') + + return batch_processing_flag, dump_status_kbn, syor_date_str + + +def update_batch_processing_flag_in_processing() -> None: + """バッチ処理中フラグを処理中に更新する + + Raises: + BatchOperationException: DB操作の何らかのエラー + """ + db = Database.get_instance() + sql = 'UPDATE src05.hdke_tbl SET bch_actf = :in_processing' + try: + db.connect() + db.execute(sql, {'in_processing': constants.BATCH_ACTF_BATCH_IN_PROCESSING}) + except DBException as e: + raise BatchOperationException(e) + finally: + db.disconnect() + + return + + +def update_batch_process_complete() -> None: + """バッチ処理を完了とし、処理日、バッチ処理中フラグ、dump処理状態区分を更新する + + Raises: + BatchOperationException: DB操作の何らかのエラー + """ + db = Database.get_instance() + sql = """\ + UPDATE src05.hdke_tbl + SET + bch_actf = :batch_complete, + dump_sts_kbn = :dump_unprocessed, + syor_date = DATE_FORMAT((src05.get_syor_date() + interval 1 day), '%Y%m%d') -- +1日 + """ + try: + db.connect() + db.execute(sql, { + 'batch_complete': constants.BATCH_ACTF_BATCH_UNPROCESSED, + 'dump_unprocessed': constants.DUMP_STATUS_KBN_UNPROCESSED + }) + except DBException as e: + raise BatchOperationException(e) + finally: + db.disconnect() + + return + + +def logging_sql(logger: logging.Logger, sql: str) -> None: + """SQL文をデバッグログで出力する + + Args: + logger (logging.Logger): ロガー + sql (str): SQL文 + """ + logger.debug(f'\n{"-" * 15}\n{textwrap.dedent(sql)[1:-1]}\n{"-" * 15}') diff --git a/ecs/jskult-batch-monthly/src/batch/common/__init__.py b/ecs/jskult-batch-monthly/src/batch/common/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ecs/jskult-batch-monthly/src/batch/common/batch_context.py b/ecs/jskult-batch-monthly/src/batch/common/batch_context.py new file mode 100644 index 00000000..8b76415a --- /dev/null +++ b/ecs/jskult-batch-monthly/src/batch/common/batch_context.py @@ -0,0 +1,37 @@ +class BatchContext: + __instance = None + __syor_date: str # 処理日(yyyy/mm/dd形式) + __is_not_business_monthly: bool # 月次バッチ起動日フラグ + + def __init__(self) -> None: + self.__is_not_business_monthly = False + + @classmethod + def get_instance(cls): + if cls.__instance is None: + cls.__instance = cls() + return cls.__instance + + @property + def syor_date(self): + return self.__syor_date + + @syor_date.setter + def syor_date(self, syor_date_str: str): + self.__syor_date = syor_date_str + + @property + def is_not_business_monthly(self): + return self.__is_not_business_monthly + + @is_not_business_monthly.setter + def is_not_business_monthly(self, flag: bool): + self.__is_not_business_monthly = flag + + @property + def is_ultmarc_imported(self): + return self.__is_ultmarc_imported + + @is_ultmarc_imported.setter + def is_ultmarc_imported(self, flag: bool): + self.__is_ultmarc_imported = flag diff --git a/ecs/jskult-batch-monthly/src/batch/common/calendar_file.py b/ecs/jskult-batch-monthly/src/batch/common/calendar_file.py new file mode 100644 index 00000000..b456f03c --- /dev/null +++ b/ecs/jskult-batch-monthly/src/batch/common/calendar_file.py @@ -0,0 +1,32 @@ +from src.system_var import constants + + +class CalendarFile: + """カレンダーファイル""" + + __calendar_file_lines: list[str] + + def __init__(self, calendar_file_path): + with open(calendar_file_path) as f: + self.__calendar_file_lines: list[str] = f.readlines() + + def compare_date(self, date_str: str) -> bool: + """与えられた日付がカレンダーファイル内に含まれているかどうか + カレンダーファイル内の日付はyyyy/mm/ddで書かれている前提 + コメント(#)が含まれている行は無視される + + Args: + date_str (str): yyyy/mm/dd文字列 + + Returns: + bool: 含まれていればTrue + """ + for calendar_date in self.__calendar_file_lines: + # コメント行が含まれている場合はスキップ + if constants.CALENDAR_COMMENT_SYMBOL in calendar_date: + continue + + if date_str in calendar_date: + return True + + return False diff --git a/ecs/jskult-batch-monthly/src/batch/parallel_processes.py b/ecs/jskult-batch-monthly/src/batch/parallel_processes.py new file mode 100644 index 00000000..0fb2d715 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/batch/parallel_processes.py @@ -0,0 +1,32 @@ +"""並列処理""" + +import concurrent.futures + +from src.batch.bio_sales import create_bio_sales_lot +from src.batch.laundering import sales_laundering +from src.error.exceptions import BatchOperationException + + +def exec(): + # 並列処理を開始 + with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: + + # 実績更新 + future_sales_laundering = executor.submit(sales_laundering.exec) + # 生物由来ロット分解 + future_create_bio_sales_lot = executor.submit(create_bio_sales_lot.exec) + + # 両方の処理が完了するまで待つ + concurrent.futures.wait([future_sales_laundering, future_create_bio_sales_lot]) + + # エラーがあれば呼び出し元でキャッチする + sales_laundering_exc = future_sales_laundering.exception() + create_bio_sales_lot_exc = future_create_bio_sales_lot.exception() + + # いずれかにエラーが発生していれば、1つのエラーとして返す。 + if sales_laundering_exc is not None or create_bio_sales_lot_exc is not None: + sales_laundering_exc_message = str(sales_laundering_exc) if sales_laundering_exc is not None else '' + create_bio_sales_lot_exc_message = str(create_bio_sales_lot_exc) if create_bio_sales_lot_exc is not None else '' + raise BatchOperationException(f'並列処理中にエラーが発生しました。実績更新="{sales_laundering_exc_message}", 生物由来ロット分解={create_bio_sales_lot_exc_message}') + + return diff --git a/ecs/jskult-batch-monthly/src/db/__init__.py b/ecs/jskult-batch-monthly/src/db/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ecs/jskult-batch-monthly/src/db/database.py b/ecs/jskult-batch-monthly/src/db/database.py new file mode 100644 index 00000000..f67a21b9 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/db/database.py @@ -0,0 +1,178 @@ +from sqlalchemy import (Connection, CursorResult, Engine, QueuePool, + create_engine, text) +from sqlalchemy.engine.url import URL +from tenacity import retry, stop_after_attempt, wait_exponential + +from src.error.exceptions import DBException +from src.logging.get_logger import get_logger +from src.system_var import environment + +logger = get_logger(__name__) + + +class Database: + """データベース操作クラス""" + __connection: Connection = None + __engine: Engine = None + __host: str = None + __port: str = None + __username: str = None + __password: str = None + __schema: str = None + __connection_string: str = None + + def __init__(self, username: str, password: str, host: str, port: int, schema: str) -> None: + """このクラスの新たなインスタンスを初期化します + + Args: + username (str): DBユーザー名 + password (str): DBパスワード + host (str): DBホスト名 + port (int): DBポート + schema (str): DBスキーマ名 + """ + self.__username = username + self.__password = password + self.__host = host + self.__port = int(port) + self.__schema = schema + + self.__connection_string = URL.create( + drivername='mysql+pymysql', + username=self.__username, + password=self.__password, + host=self.__host, + port=self.__port, + database=self.__schema, + query={"charset": "utf8mb4"} + ) + + self.__engine = create_engine( + self.__connection_string, + pool_timeout=5, + poolclass=QueuePool + ) + + @classmethod + def get_instance(cls): + """インスタンスを取得します + + Returns: + Database: DB操作クラスインスタンス + """ + return cls( + username=environment.DB_USERNAME, + password=environment.DB_PASSWORD, + host=environment.DB_HOST, + port=environment.DB_PORT, + schema=environment.DB_SCHEMA + ) + + @retry( + wait=wait_exponential( + multiplier=environment.DB_CONNECTION_RETRY_INTERVAL_INIT, + min=environment.DB_CONNECTION_RETRY_INTERVAL_MIN_SECONDS, + max=environment.DB_CONNECTION_RETRY_INTERVAL_MAX_SECONDS + ), + stop=stop_after_attempt(environment.DB_CONNECTION_MAX_RETRY_ATTEMPT)) + def connect(self): + """ + DBに接続します。接続に失敗した場合、リトライします。 + Raises: + DBException: 接続失敗 + """ + try: + self.__connection = self.__engine.connect() + except Exception as e: + raise DBException(e) + + def execute_select(self, select_query: str, parameters=None) -> list[dict]: + """SELECTクエリを実行します。 + + Args: + select_query (str): SELECT文 + parameters (dict, optional): クエリのプレースホルダーに埋め込む変数の辞書. Defaults to None. + + Raises: + DBException: DBエラー + + Returns: + list[dict]: カラム名: 値の辞書リスト + """ + if self.__connection is None: + raise DBException('DBに接続していません') + + result = None + try: + # トランザクションが開始している場合は、トランザクションを引き継ぐ + if self.__connection.in_transaction(): + result = self.__connection.execute(text(select_query), parameters) + else: + # トランザクションが明示的に開始していない場合は、クエリ単位でトランザクションをbegin-commitする。 + result = self.__execute_with_transaction(select_query, parameters) + except Exception as e: + raise DBException(f'SQL Error: {e}') + + result_rows = result.mappings().all() + return result_rows + + def execute(self, query: str, parameters=None) -> CursorResult: + """SQLクエリを実行します。 + + Args: + query (str): SQL文 + parameters (dict, optional): クエリのプレースホルダーに埋め込む変数の辞書. Defaults to None. + + Raises: + DBException: DBエラー + + Returns: + CursorResult: 取得結果 + """ + if self.__connection is None: + raise DBException('DBに接続していません') + + result = None + try: + # トランザクションが開始している場合は、トランザクションを引き継ぐ + if self.__connection.in_transaction(): + result = self.__connection.execute(text(query), parameters) + else: + # トランザクションが明示的に開始していない場合は、クエリ単位でトランザクションをbegin-commitする。 + result = self.__execute_with_transaction(query, parameters) + except Exception as e: + raise DBException(f'SQL Error: {e}') + + return result + + def begin(self): + """トランザクションを開始します。""" + if not self.__connection.in_transaction(): + self.__connection.begin() + + def commit(self): + """トランザクションをコミットします""" + if self.__connection.in_transaction(): + self.__connection.commit() + + def rollback(self): + """トランザクションをロールバックします""" + if self.__connection.in_transaction(): + self.__connection.rollback() + + def disconnect(self): + """DB接続を切断します。""" + if self.__connection is not None: + self.__connection.close() + self.__connection = None + + def __execute_with_transaction(self, query: str, parameters: dict): + # トランザクションを開始してクエリを実行する + with self.__connection.begin(): + try: + result = self.__connection.execute(text(query), parameters=parameters) + except Exception as e: + self.__connection.rollback() + raise e + # ここでコミットされる + return result diff --git a/ecs/jskult-batch-monthly/src/error/__init__.py b/ecs/jskult-batch-monthly/src/error/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ecs/jskult-batch-monthly/src/error/exceptions.py b/ecs/jskult-batch-monthly/src/error/exceptions.py new file mode 100644 index 00000000..055c24f6 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/error/exceptions.py @@ -0,0 +1,10 @@ +class MeDaCaException(Exception): + pass + + +class DBException(MeDaCaException): + pass + + +class BatchOperationException(MeDaCaException): + pass diff --git a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py new file mode 100644 index 00000000..b58c4601 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py @@ -0,0 +1,88 @@ +"""実消化&アルトマーク 月次バッチ処理""" + +from src.aws.s3 import ConfigBucket +from src.batch.batch_functions import ( + get_batch_statuses, update_batch_process_complete, + update_batch_processing_flag_in_processing) +from src.batch.common.batch_context import BatchContext +from src.batch.common.calendar_file import CalendarFile +from src.error.exceptions import BatchOperationException +from src.logging.get_logger import get_logger +from src.system_var import constants + +logger = get_logger('月次処理コントロール') + +# バッチ共通設定を取得 +batch_context = BatchContext.get_instance() + + +def exec(): + try: + logger.info('月次バッチ:開始') + try: + # 月次バッチ処置中フラグ、dump処理状態区分、処理日を取得 + batch_processing_flag, dump_status_kbn, syor_date = get_batch_statuses() + except BatchOperationException as e: + logger.exception(f'日付テーブル取得(異常終了){e}') + return constants.BATCH_EXIT_CODE_SUCCESS + + # 月次バッチ処理中の場合、後続の処理は行わない + if batch_processing_flag == constants.BATCH_ACTF_BATCH_IN_PROCESSING: + logger.error('バッチ処理中のため、月次バッチ処理を終了します。') + return constants.BATCH_EXIT_CODE_SUCCESS + + # dump取得が正常終了していない場合、後続の処理は行わない + if dump_status_kbn != constants.DUMP_STATUS_KBN_COMPLETE: + logger.error('dump取得が正常終了していないため、月次バッチ処理を終了します。') + return constants.BATCH_EXIT_CODE_SUCCESS + + logger.info(f'処理日={syor_date}') + # バッチ共通設定に処理日を追加 + batch_context.syor_date = syor_date + + # 稼働日かかどうかを、実消化&アルトマーク月次バッチ稼働日ファイルをダウンロードして判定 + try: + arisj_output_day_list_file_path = ConfigBucket().download_arisj_output_day_list() + arisj_output_day_calendar = CalendarFile(arisj_output_day_list_file_path) + batch_context.is_not_business_monthly = arisj_output_day_calendar.compare_date(syor_date) + except Exception as e: + logger.exception(f'実消化&アルトマーク月次バッチ稼働日ファイルの読み込みに失敗しました。{e}') + return constants.BATCH_EXIT_CODE_SUCCESS + + # 調査目的でV実消化稼働日かどうかをログ出力 + logger.debug(f'本日は{"実消化&アルトマーク月次バッチ稼働日です。" if batch_context.is_not_business_monthly else "実消化&アルトマーク月次バッチ非稼働日です。"}') + + # バッチ処理中に更新 + try: + update_batch_processing_flag_in_processing() + except BatchOperationException as e: + logger.exception(f'処理フラグ更新(未処理→処理中) エラー(異常終了){e}') + return constants.BATCH_EXIT_CODE_SUCCESS + + try: + logger.info('月次バッチ:起動') + # ultmarc_process.exec_import() + logger.info('月次バッチ:終了') + except BatchOperationException as e: + logger.exception(f'月次バッチ処理エラー(異常終了){e}') + return constants.BATCH_EXIT_CODE_SUCCESS + + # 調査目的で月次バッチが行われたかどうかをログ出力 + logger.debug(f'{"月次バッチが行われました。" if batch_context.is_not_business_monthly else "月次バッチが行われませんでした。"}') + + # バッチ処理完了とし、処理日、バッチ処置中フラグ、dump取得状態区分を更新 + logger.info('業務日付更新・バッチステータスリフレッシュ:起動') + try: + update_batch_process_complete() + except BatchOperationException as e: + logger.exception(f'業務日付更新・バッチステータスリフレッシュ エラー(異常終了){e}') + return constants.BATCH_EXIT_CODE_SUCCESS + logger.info('業務日付更新・バッチステータスリフレッシュ:終了') + + # 正常終了を保守ユーザーに通知 + logger.info('[NOTICE]月次バッチ:終了(正常終了)') + return constants.BATCH_EXIT_CODE_SUCCESS + + except Exception as e: + logger.exception(f'月次バッチ処理中に想定外のエラーが発生しました {e}') + raise e diff --git a/ecs/jskult-batch-monthly/src/logging/get_logger.py b/ecs/jskult-batch-monthly/src/logging/get_logger.py new file mode 100644 index 00000000..f36f1199 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/logging/get_logger.py @@ -0,0 +1,37 @@ +import logging + +from src.system_var.environment import LOG_LEVEL + +# boto3関連モジュールのログレベルを事前に個別指定し、モジュール内のDEBUGログの表示を抑止する +for name in ["boto3", "botocore", "s3transfer", "urllib3"]: + logging.getLogger(name).setLevel(logging.WARNING) + + +def get_logger(log_name: str) -> logging.Logger: + """一意のログ出力モジュールを取得します。 + + Args: + log_name (str): ロガー名 + + Returns: + _type_: _description_ + """ + logger = logging.getLogger(log_name) + level = logging.getLevelName(LOG_LEVEL) + if not isinstance(level, int): + level = logging.INFO + logger.setLevel(level) + + if not logger.hasHandlers(): + handler = logging.StreamHandler() + logger.addHandler(handler) + + formatter = logging.Formatter( + '%(name)s\t[%(levelname)s]\t%(asctime)s\t%(message)s', + '%Y-%m-%d %H:%M:%S' + ) + + for handler in logger.handlers: + handler.setFormatter(formatter) + + return logger diff --git a/ecs/jskult-batch-monthly/src/system_var/__init__.py b/ecs/jskult-batch-monthly/src/system_var/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ecs/jskult-batch-monthly/src/system_var/constants.py b/ecs/jskult-batch-monthly/src/system_var/constants.py new file mode 100644 index 00000000..8a0ccbb3 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/system_var/constants.py @@ -0,0 +1,17 @@ +# バッチ正常終了コード +BATCH_EXIT_CODE_SUCCESS = 0 + +# バッチ処理中フラグ:未処理 +BATCH_ACTF_BATCH_UNPROCESSED = '0' +# バッチ処理中フラグ:処理中 +BATCH_ACTF_BATCH_IN_PROCESSING = '1' +# dump取得状態区分:未処理 +DUMP_STATUS_KBN_UNPROCESSED = '0' +# dump取得状態区分:dump取得正常終了 +DUMP_STATUS_KBN_COMPLETE = '2' + +# カレンダーファイルのコメントシンボル +CALENDAR_COMMENT_SYMBOL = '#' + +# 月曜日(datetime.weekday()で月曜日を表す数字) +WEEKDAY_MONDAY = 0 diff --git a/ecs/jskult-batch-monthly/src/system_var/environment.py b/ecs/jskult-batch-monthly/src/system_var/environment.py new file mode 100644 index 00000000..25afc294 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/system_var/environment.py @@ -0,0 +1,25 @@ +import os + +# Database +DB_HOST = os.environ['DB_HOST'] +DB_PORT = int(os.environ['DB_PORT']) +DB_USERNAME = os.environ['DB_USERNAME'] +DB_PASSWORD = os.environ['DB_PASSWORD'] +DB_SCHEMA = os.environ['DB_SCHEMA'] + +# AWS +ULTMARC_DATA_BUCKET = os.environ['ULTMARC_DATA_BUCKET'] +ULTMARC_DATA_FOLDER = os.environ['ULTMARC_DATA_FOLDER'] +JSKULT_BACKUP_BUCKET = os.environ['JSKULT_BACKUP_BUCKET'] +ULTMARC_BACKUP_FOLDER = os.environ['ULTMARC_BACKUP_FOLDER'] +JSKULT_CONFIG_BUCKET = os.environ['JSKULT_CONFIG_BUCKET'] +JSKULT_CONFIG_CALENDAR_FOLDER = os.environ['JSKULT_CONFIG_CALENDAR_FOLDER'] +JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME'] +JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME'] + +# 初期値がある環境変数 +LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') +DB_CONNECTION_MAX_RETRY_ATTEMPT = int(os.environ.get('DB_CONNECTION_MAX_RETRY_ATTEMPT', 4)) +DB_CONNECTION_RETRY_INTERVAL_INIT = int(os.environ.get('DB_CONNECTION_RETRY_INTERVAL', 5)) +DB_CONNECTION_RETRY_INTERVAL_MIN_SECONDS = int(os.environ.get('DB_CONNECTION_RETRY_MIN_SECONDS', 5)) +DB_CONNECTION_RETRY_INTERVAL_MAX_SECONDS = int(os.environ.get('DB_CONNECTION_RETRY_MAX_SECONDS', 50)) diff --git a/ecs/jskult-batch-monthly/src/time/elapsed_time.py b/ecs/jskult-batch-monthly/src/time/elapsed_time.py new file mode 100644 index 00000000..c1432e91 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/time/elapsed_time.py @@ -0,0 +1,22 @@ +import time + + +class ElapsedTime: + """処理実行時間計測クラス""" + def __init__(self) -> None: + """このクラスの新たなインスタンスを初期化します。""" + self.__start = time.perf_counter() + + @property + def of(self): + """インスタンス化してからの経過時間をhh:mm:ssの形式にフォーマットして返す + Returns: + str: 時分秒形式の経過時間 + """ + elapsed_time = time.perf_counter() - self.__start + h, rem = divmod(elapsed_time, 3600) + m, s = divmod(rem, 60) + h_str = f'{h:02.0f} hour ' if h > 0.0 else '' + m_str = f'{m:02.0f} min ' if m > 0.0 else '' + s_str = f'{s:06.02f} sec' if s > 0.0 else '' + return f"{h_str}{m_str}{s_str}" diff --git a/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt b/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt new file mode 100644 index 00000000..2d5f42c0 --- /dev/null +++ b/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt @@ -0,0 +1,100 @@ +2023/06/23 +2023/06/24 +2023/06/25 +2023/06/26 +2023/06/27 +2023/06/28 +2023/06/29 +2023/06/30 +2023/07/01 +2023/07/02 +2023/07/03 +2023/07/04 +2023/07/05 +2023/07/06 +2023/07/07 +2023/07/08 +2023/07/09 +2023/07/10 +2023/07/11 +2023/07/12 +2023/07/13 +2023/07/14 +2023/07/15 +2023/07/16 +2023/07/17 +2023/07/18 +2023/07/19 +2023/07/20 +2023/07/21 +2023/07/22 +2023/07/23 +2023/07/24 +2023/07/25 +2023/07/26 +2023/07/27 +2023/07/28 +2023/07/29 +2023/07/30 +2023/07/31 +2023/08/01 +2023/08/02 +2023/08/03 +2023/08/04 +2023/08/05 +2023/08/06 +2023/08/07 +2023/08/08 +2023/08/09 +2023/08/10 +2023/08/11 +2023/08/12 +2023/08/13 +2023/08/14 +2023/08/15 +2023/08/16 +2023/08/17 +2023/08/18 +2023/08/19 +2023/08/20 +2023/08/21 +2023/08/22 +2023/08/23 +2023/08/24 +2023/08/25 +2023/08/26 +2023/08/27 +2023/08/28 +2023/08/29 +2023/08/30 +2023/08/31 +2023/09/01 +2023/09/02 +2023/09/03 +2023/09/04 +2023/09/05 +2023/09/06 +2023/09/07 +2023/09/08 +2023/09/09 +2023/09/10 +2023/09/11 +2023/09/12 +2023/09/13 +2023/09/14 +2023/09/15 +2023/09/16 +2023/09/17 +2023/09/18 +2023/09/19 +2023/09/20 +2023/09/21 +2023/09/22 +2023/09/23 +2023/09/24 +2023/09/25 +2023/09/26 +2023/09/27 +2023/09/28 +2023/09/29 +2023/09/30 From 626ee291c36245e5fc6562f3114c29a0261998a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Mon, 26 Jun 2023 08:54:13 +0900 Subject: [PATCH 02/28] =?UTF-8?q?=E4=BD=9C=E6=A5=AD=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/batch/jskult_batch_monthly.py | 236 ++++++++++++++++++ .../src/jobctrl_monthly.py | 5 +- 2 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py diff --git a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py new file mode 100644 index 00000000..3cbecd15 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py @@ -0,0 +1,236 @@ + +from datetime import datetime + +# from src.aws.s3 import UltmarcBucket +# from src.batch.common.batch_context import BatchContext +from src.db.database import Database +from src.error.exceptions import BatchOperationException +from src.logging.get_logger import get_logger +# from src.system_var import constants +import pathlib +import os + +logger = get_logger('実消化&アルトマーク月次バッチ') + + +class JskultBathcMonthly(): + """ 実消化&アルトマーク月次バッチ """ + + # WKテーブルの過去分削除SQL + PHYSICAL_NORMAL_DELETE_QUERY = """\ + DELETE FROM src05.wk_inst_aris_if + """ + + # 正常系データを取得しWKテーブルに保存SQL + NORMAL_INSERT_SELECT_QUERY = """\ + INSERT src05.wk_inst_aris_if + SELECT + TRIM(' ' FROM TRIM(' ' FROM SUBSTRIN(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form + ,TRIM(' ' FROM TRIM(' ' FROM ci.prefc_cd)) AS pref_cd + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(cp.prefc_name,1,8))) AS pref_name + ,TRIM(' ' FROM TRIM(' ' FROM ci.postal_number)) AS postal_cd + ,TRIM(' ' FROM TRIM(' ' FROM cc.city_name)) AS city_name + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_addr)) AS address + ,TRIM(' ' FROM TRIM(' ' FROM cd.inst_div_name)) + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_phone_number)) AS phone_no + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_div_cd)) + ,TRIM(' ' FROM TRIM(' ' FROM ci.manage_cd)) + ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date + ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date + ,sysdate() + FROM src05.com_inst ci + LEFT JOIN src05.mst_prefc cp + ON ci.prefc_cd = cp.prefc_cd + LEFT JOIN src05.mst_city cc + ON ci.prefc_cd = cc.prefc_cd + AND ci.city_cd = cc.city_cd + LEFT OUTER JOIN src05.JOIN com_inst_div cd + ON ci.inst_div_cd = cd.inst_div_cd + WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' + AND ci.dcf_dsf_inst_cd IS NOT NULL + AND ci.form_inst_name_kanji IS NOT NULL + AND ci.prefc_cd IS NOT NULL + AND cp.prefc_name IS NOT NULL + AND cc.city_name IS NOT NULL + AND ci.inst_addr IS NOT NULL + ORDER BY ci.dcf_dsf_inst_cd + """ + + # 正常系データの件数を取得SQL + NORMAL_COUNT_QUERY = """\ + SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if + """ + + # 異常系WKテーブルの過去分削除SQL + PHYSICAL_ABNORMAL_DELETE_QUERY = """\ + DELETE FROM src05.wk_inst_aris_if_wrn + """ + + # 異常系データを取得しWKテーブルに保存SQL + ABNORMAL_INSERT_SELECT_QUERY = """\ + INSERT src05.wk_inst_aris_if_wrn + SELECT + TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form + ,TRIM(' ' FROM TRIM(' ' from ci.prefc_cd)) AS pref_cd + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(cp.prefc_name,1,8))) AS pref_name + ,TRIM(' ' FROM TRIM(' ' from ci.postal_number)) AS postal_cd + ,TRIM(' ' FROM TRIM(' ' from cc.city_name)) AS city_name + ,TRIM(' ' FROM TRIM(' ' from ci.inst_addr)) AS address + ,TRIM(' ' FROM TRIM(' ' from cd.inst_div_name)) + ,TRIM(' ' FROM TRIM(' ' from ci.inst_phone_number)) AS phone_no + ,TRIM(' ' FROM TRIM(' ' from ci.inst_div_cd)) + ,TRIM(' ' FROM TRIM(' ' from ci.manage_cd)) + ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date + ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date + ,IF(ci.dcf_dsf_inst_cd IS NULL,'bi0402000001', NULL) AS wrnid_dcf_inst_cd + ,IF(ci.form_inst_name_kanji IS NULL,'bi0402000002', NULL) AS wrnid_inst_name_form + ,IF(ci.prefc_cd IS NULL,'bi0402000003', NULL) AS wrnid_pref_cd + ,IF(cp.prefc_name IS NULL,'bi0402000004', NULL) AS wrnid_pref_name + ,IF(cc.city_name IS NULL,'bi0402000005', NULL) AS wrnid_city_name + ,IF(ci.inst_addr IS NULL,'bi0402000006', NULL) AS wrnid_address + ,sysdate() + FROM src05.com_inst ci + LEFT JOIN src05.mst_prefc cp + ON ci.prefc_cd = cp.prefc_cd + LEFT JOIN src05.mst_city cc + ON ci.prefc_cd = cc.prefc_cd + AND ci.city_cd = cc.city_cd + LEFT OUTER JOIN src05.com_inst_div cd + ON ci.inst_div_cd = cd.inst_div_cd + WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' + AND( ci.dcf_dsf_inst_cd IS NULL + OR ci.form_inst_name_kanji IS NULL + OR ci.prefc_cd IS NULL + OR cp.prefc_name IS NULL + OR cc.city_name IS NULL + OR ci.inst_addr IS NULL) + ORDER BY ci.dcf_dsf_inst_cd + """ + + # 正常系データの件数を取得SQL + ABNORMAL_COUNT_QUERY = """\ + SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if_wrn + """ + # CSVファイルの作成用のSQL + SELECT_QUERY = """\ + SELECT dcf_inst_cd, inst_name_form, inst_name, inst_name_kana_form, pref_cd, pref_name, + postal_cd, city_name, address, inst_div_name, phone_no, inst_div_cd, manage_cd, + '', inst_delete_date + FROM src05.wk_inst_aris_if ORDER BY dcf_inst_cd + """ + + aris_log = '/var/log/temporarydwh/' + move_file_path = '/data/mountaris/DATA/' + create_date = datetime.now().strftime('%Y%m%d%H%M%S') + create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + aris_create_csv = f'/home/nds_dwh/tmpcsv/D0004_ARIS_M_DCF_{create_date}csv' + aris_move_csv = f'{move_file_path}D0004_ARIS_M_DCF_{create_date}.csv' + res_log = f'{aris_log}D0004{create_date}.log' + move_res_og = f'{move_file_path}D0004{create_date}log' + prg_id = 'PrgId:BI0402' + head_str = 'TC_HOSPITAL, TJ_HOSPITAL, TJ_HOSPITALSHORT, TK_HOSPITAL, \ + TC_PREFECTURE, TJ_PREFECTURE, TJ_ZIPCODE, TJ_CITY, TJ_ADDRESS, TJ_DEPARTMENT, \ + TJ_TELEPHONENUMBER, TC_HOSPITALCAT, TC_HOSPITALTYPE, TS_UPDATE, TD_UPDATE' + + start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。\n" + dbConnect_err_msg = "MsgID:999999000002 Message:DB接続エラーです。\n" + err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。\n" + move_err_msg = "MsgID:BI0000000041 Message:S3バケットARISへのCSVデータ、実行ログ移動できませんでした。\n" + sql_err_msg = "MsgID:999999000002 Message:SQL実行エラーです。\n" + csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。\n" + cnt_msg = "MsgID: Message: LogText:" + suc_end_msg = "MsgID:BI0000009999 Message:バッチ処理を正常に終了しました。\n" + + def exec_batch_monthly(self): + """ 実消化&アルトマーク月次バッチ """ + try: + # 実行ログに書き込む + res_log_p = pathlib.Path(self.res_log) + res_log_p.touch() + os.chmod(self.res_log, '0664') + + # 実行ログ + resLog_f = open(self.res_log) + print(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.start_msg}') + + db = Database.get_instance() + # DB接続 + db.connect() + # トランザクションの開始 + db.begin() + + # 正常系データの反映 + # 過去分は不要のため、デリート + db.execute(self.PHYSICAL_NORMAL_DELETE_QUERY) + + # 正常系データを取得しWKテーブルに保存する。 + db.execute(self.NORMAL_INSERT_SELECT_QUERY) + + # 正常系データの件数を取得 + record_count = db.execute_select(self.NORMAL_COUNT_QUERY) + suc_count = record_count[0]['countNum'] + + # 警告系データの反映 + # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 + db.execute(self.PHYSICAL_ABNORMAL_DELETE_QUERY) + + # 異常系データを取得しWKテーブルに保存する。 + db.execute(self.ABNORMAL_INSERT_SELECT_QUERY) + + # 異常系データの件数を取得 + record_count = db.execute_select(self.ABNORMAL_COUNT_QUERY) + wrn_count = record_count[0]['countNum'] + + # CSVファイルの作成用のSQL実行 + record_csv = db.execute_select(self.SELECT_QUERY) + + # CSVファイル作成 + arisCreateCsv_p = pathlib.Path(self.arisCreateCsv) + arisCreateCsv_p.touch() + if not os.path.exists(self.arisCreateCsv): + print(f'{self.create_date_format}[DWH][5][ERROR]{self.prg_id} {self.csv_err_msg}') + print(f'{self.create_date_format}[DWH][5][ERROR]{self.prg_id} {self.err_end_msg}') + + # ヘッダ行書き込み + resLog_f = open(self.aris_create_csv) + print(f'{self.head_str}\r\n') + + # データ部分書き込み + for record_data in record_csv: + csv_data = ",".join(record_data).encode('shift_jis') + print(f'{csv_data}\r\n') + + logger.info('use memory--->') + logger.info('memory_get_usage 与えられたメモリの量') + logger.info('\n') + logger.info('max memory--->') + logger.info('memory_get_peak_usage  メモリの最大値') + logger.info('\n') + + resLog_f.close() + + # トランザクションの終了 + db.commit() + + # 実行ログファイルの追記 + # 実行ログに処理件数を書き込む。 + sum_count = suc_count + wrn_count + print(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})\n') + + # ファイル移動処理 + + logger.info('実消化&アルトマーク月次バッチ処理: 終了') + except Exception as e: + raise BatchOperationException(e) + + finally: + # 終了時に必ずコミットする + db.commit() + db.disconnect() + return diff --git a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py index b58c4601..302993a2 100644 --- a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py +++ b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py @@ -9,6 +9,7 @@ from src.batch.common.calendar_file import CalendarFile from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger from src.system_var import constants +from src.batch.jskult_batch_monthly import JskultBathcMonthly logger = get_logger('月次処理コントロール') @@ -34,7 +35,7 @@ def exec(): # dump取得が正常終了していない場合、後続の処理は行わない if dump_status_kbn != constants.DUMP_STATUS_KBN_COMPLETE: logger.error('dump取得が正常終了していないため、月次バッチ処理を終了します。') - return constants.BATCH_EXIT_CODE_SUCCESS + # 戻すんだよ return constants.BATCH_EXIT_CODE_SUCCESS logger.info(f'処理日={syor_date}') # バッチ共通設定に処理日を追加 @@ -61,7 +62,7 @@ def exec(): try: logger.info('月次バッチ:起動') - # ultmarc_process.exec_import() + JskultBathcMonthly.exec_batch_monthly() logger.info('月次バッチ:終了') except BatchOperationException as e: logger.exception(f'月次バッチ処理エラー(異常終了){e}') From c76700a37ae165a10114312c2200767fe33c60e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Mon, 26 Jun 2023 16:28:01 +0900 Subject: [PATCH 03/28] =?UTF-8?q?=E4=BB=AE=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/.env.example | 3 +- .../src/batch/jskult_batch_monthly.py | 108 +++++++++++------- .../src/jobctrl_monthly.py | 5 +- 3 files changed, 69 insertions(+), 47 deletions(-) diff --git a/ecs/jskult-batch-monthly/.env.example b/ecs/jskult-batch-monthly/.env.example index 19a3f19f..f2bb73c8 100644 --- a/ecs/jskult-batch-monthly/.env.example +++ b/ecs/jskult-batch-monthly/.env.example @@ -13,7 +13,8 @@ JSKULT_CONFIG_CALENDAR_FOLDER=jskult/calendar JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME=jskult_holiday_list.txt ARISJ_DATA_BUCKET=********** LOG_LEVEL=************** -ARISJ_BACKUP_FOLDER=************** +ARISJ_BACKUP_FOLDER=arisj +ARISJ_DATA_FOLDER=DATA JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME=jskult_arisj_output_day_list.txt DB_CONNECTION_MAX_RETRY_ATTEMPT=************** DB_CONNECTION_RETRY_INTERVAL_INIT=************** diff --git a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py index 3cbecd15..b4caefe1 100644 --- a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py +++ b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py @@ -1,14 +1,13 @@ from datetime import datetime -# from src.aws.s3 import UltmarcBucket -# from src.batch.common.batch_context import BatchContext from src.db.database import Database from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger -# from src.system_var import constants -import pathlib import os +import tempfile +import os.path as path +import boto3 logger = get_logger('実消化&アルトマーク月次バッチ') @@ -25,7 +24,7 @@ class JskultBathcMonthly(): NORMAL_INSERT_SELECT_QUERY = """\ INSERT src05.wk_inst_aris_if SELECT - TRIM(' ' FROM TRIM(' ' FROM SUBSTRIN(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form @@ -47,7 +46,7 @@ class JskultBathcMonthly(): LEFT JOIN src05.mst_city cc ON ci.prefc_cd = cc.prefc_cd AND ci.city_cd = cc.city_cd - LEFT OUTER JOIN src05.JOIN com_inst_div cd + LEFT OUTER JOIN src05.com_inst_div cd ON ci.inst_div_cd = cd.inst_div_cd WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' AND ci.dcf_dsf_inst_cd IS NOT NULL @@ -129,35 +128,26 @@ class JskultBathcMonthly(): move_file_path = '/data/mountaris/DATA/' create_date = datetime.now().strftime('%Y%m%d%H%M%S') create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - aris_create_csv = f'/home/nds_dwh/tmpcsv/D0004_ARIS_M_DCF_{create_date}csv' - aris_move_csv = f'{move_file_path}D0004_ARIS_M_DCF_{create_date}.csv' - res_log = f'{aris_log}D0004{create_date}.log' - move_res_og = f'{move_file_path}D0004{create_date}log' + aris_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' + res_log = f'D0004{create_date}.log' prg_id = 'PrgId:BI0402' head_str = 'TC_HOSPITAL, TJ_HOSPITAL, TJ_HOSPITALSHORT, TK_HOSPITAL, \ TC_PREFECTURE, TJ_PREFECTURE, TJ_ZIPCODE, TJ_CITY, TJ_ADDRESS, TJ_DEPARTMENT, \ TJ_TELEPHONENUMBER, TC_HOSPITALCAT, TC_HOSPITALTYPE, TS_UPDATE, TD_UPDATE' start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。\n" - dbConnect_err_msg = "MsgID:999999000002 Message:DB接続エラーです。\n" err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。\n" - move_err_msg = "MsgID:BI0000000041 Message:S3バケットARISへのCSVデータ、実行ログ移動できませんでした。\n" - sql_err_msg = "MsgID:999999000002 Message:SQL実行エラーです。\n" csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。\n" cnt_msg = "MsgID: Message: LogText:" - suc_end_msg = "MsgID:BI0000009999 Message:バッチ処理を正常に終了しました。\n" def exec_batch_monthly(self): """ 実消化&アルトマーク月次バッチ """ try: # 実行ログに書き込む - res_log_p = pathlib.Path(self.res_log) - res_log_p.touch() - os.chmod(self.res_log, '0664') - - # 実行ログ - resLog_f = open(self.res_log) - print(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.start_msg}') + resLog = make_log_data(self) + resLog_f = resLog[0] + log_file_path = resLog[1] + resLog_f.write(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.start_msg}') db = Database.get_instance() # DB接続 @@ -191,29 +181,11 @@ class JskultBathcMonthly(): record_csv = db.execute_select(self.SELECT_QUERY) # CSVファイル作成 - arisCreateCsv_p = pathlib.Path(self.arisCreateCsv) - arisCreateCsv_p.touch() - if not os.path.exists(self.arisCreateCsv): - print(f'{self.create_date_format}[DWH][5][ERROR]{self.prg_id} {self.csv_err_msg}') - print(f'{self.create_date_format}[DWH][5][ERROR]{self.prg_id} {self.err_end_msg}') + csv_file_path = make_csv_data(self, record_csv) - # ヘッダ行書き込み - resLog_f = open(self.aris_create_csv) - print(f'{self.head_str}\r\n') - - # データ部分書き込み - for record_data in record_csv: - csv_data = ",".join(record_data).encode('shift_jis') - print(f'{csv_data}\r\n') - - logger.info('use memory--->') - logger.info('memory_get_usage 与えられたメモリの量') - logger.info('\n') - logger.info('max memory--->') - logger.info('memory_get_peak_usage  メモリの最大値') - logger.info('\n') - - resLog_f.close() + # テスト用に出力している(あとで消す) + logger.info(log_file_path) + logger.info(csv_file_path) # トランザクションの終了 db.commit() @@ -221,12 +193,17 @@ class JskultBathcMonthly(): # 実行ログファイルの追記 # 実行ログに処理件数を書き込む。 sum_count = suc_count + wrn_count - print(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})\n') + resLog_f.write(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})\n') + + # 実行ログファイルクローズ + resLog_f.close() # ファイル移動処理 + s3_upload_data(self, csv_file_path, log_file_path) logger.info('実消化&アルトマーク月次バッチ処理: 終了') except Exception as e: + resLog_f.write(f'{self.create_date_format}[DWH][5][INFO]{e.message}') raise BatchOperationException(e) finally: @@ -234,3 +211,46 @@ class JskultBathcMonthly(): db.commit() db.disconnect() return + + +def make_csv_data(self, record_csv: list): + # 一時ファイルとして保存する(CSVファイル) + temporary_dir = tempfile.mkdtemp() + csv_file_path = path.join(temporary_dir, self.aris_create_csv) + + # ヘッダ行書き込み + fp = open(csv_file_path, mode='w') + fp.write(f'{self.head_str}\n') + + # データ部分書き込み + for record_data in record_csv: + record_value = list(record_data.values()) + csv_data = ",".join(map(str, record_value)) + fp.write(f'{csv_data}\n') + + # ファイルクローズ + fp.close() + return csv_file_path + + +def make_log_data(self): + # 一時ファイルとして保存する(ログファイル) + temporary_dir = tempfile.mkdtemp() + log_file_path = path.join(temporary_dir, self.res_log) + fp = open(log_file_path, mode='w') + return fp, log_file_path + + +def s3_upload_data(self, csv_file_path, log_file_path): + # s3にログファイルとCSVファイルをUPする + + Bucket = os.environ['ARISJ_DATA_BUCKET'] + folder = os.environ['ARISJ_DATA_FOLDER'] + csv_file_name = f'{folder}/{self.aris_create_csv}' + log_file_name = f'{folder}/{self.res_log}' + + s3_client = boto3.client('s3') + s3_client.upload_file(csv_file_path, Bucket, csv_file_name) + s3_client.upload_file(csv_file_path, Bucket, log_file_name) + + return diff --git a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py index 302993a2..3a1e8d68 100644 --- a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py +++ b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py @@ -30,7 +30,7 @@ def exec(): # 月次バッチ処理中の場合、後続の処理は行わない if batch_processing_flag == constants.BATCH_ACTF_BATCH_IN_PROCESSING: logger.error('バッチ処理中のため、月次バッチ処理を終了します。') - return constants.BATCH_EXIT_CODE_SUCCESS + # 戻すんだよ return constants.BATCH_EXIT_CODE_SUCCESS # dump取得が正常終了していない場合、後続の処理は行わない if dump_status_kbn != constants.DUMP_STATUS_KBN_COMPLETE: @@ -62,7 +62,8 @@ def exec(): try: logger.info('月次バッチ:起動') - JskultBathcMonthly.exec_batch_monthly() + BathcMonthly = JskultBathcMonthly() + BathcMonthly.exec_batch_monthly() logger.info('月次バッチ:終了') except BatchOperationException as e: logger.exception(f'月次バッチ処理エラー(異常終了){e}') From 6478bd078b0a49ac82448eae5b08bfba26be5a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Tue, 27 Jun 2023 14:15:20 +0900 Subject: [PATCH 04/28] =?UTF-8?q?=E4=BB=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/batch/jskult_batch_monthly.py | 441 +++++++++--------- .../src/jobctrl_monthly.py | 9 +- 2 files changed, 235 insertions(+), 215 deletions(-) diff --git a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py index b4caefe1..fe9b46ee 100644 --- a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py +++ b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py @@ -11,246 +11,267 @@ import boto3 logger = get_logger('実消化&アルトマーク月次バッチ') +# WKテーブルの過去分削除SQL +PHYSICAL_NORMAL_DELETE_QUERY = """\ + DELETE FROM src05.wk_inst_aris_if +""" -class JskultBathcMonthly(): - """ 実消化&アルトマーク月次バッチ """ +# 正常系データを取得しWKテーブルに保存SQL +NORMAL_INSERT_SELECT_QUERY = """\ + INSERT src05.wk_inst_aris_if + SELECT + TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form + ,TRIM(' ' FROM TRIM(' ' FROM ci.prefc_cd)) AS pref_cd + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(cp.prefc_name,1,8))) AS pref_name + ,TRIM(' ' FROM TRIM(' ' FROM ci.postal_number)) AS postal_cd + ,TRIM(' ' FROM TRIM(' ' FROM cc.city_name)) AS city_name + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_addr)) AS address + ,TRIM(' ' FROM TRIM(' ' FROM cd.inst_div_name)) + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_phone_number)) AS phone_no + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_div_cd)) + ,TRIM(' ' FROM TRIM(' ' FROM ci.manage_cd)) + ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date + ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date + ,sysdate() + FROM src05.com_inst ci + LEFT JOIN src05.mst_prefc cp + ON ci.prefc_cd = cp.prefc_cd + LEFT JOIN src05.mst_city cc + ON ci.prefc_cd = cc.prefc_cd + AND ci.city_cd = cc.city_cd + LEFT OUTER JOIN src05.com_inst_div cd + ON ci.inst_div_cd = cd.inst_div_cd + WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' + AND ci.dcf_dsf_inst_cd IS NOT NULL + AND ci.form_inst_name_kanji IS NOT NULL + AND ci.prefc_cd IS NOT NULL + AND cp.prefc_name IS NOT NULL + AND cc.city_name IS NOT NULL + AND ci.inst_addr IS NOT NULL + ORDER BY ci.dcf_dsf_inst_cd +""" - # WKテーブルの過去分削除SQL - PHYSICAL_NORMAL_DELETE_QUERY = """\ - DELETE FROM src05.wk_inst_aris_if - """ +# 正常系データの件数を取得SQL +NORMAL_COUNT_QUERY = """\ + SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if +""" - # 正常系データを取得しWKテーブルに保存SQL - NORMAL_INSERT_SELECT_QUERY = """\ - INSERT src05.wk_inst_aris_if +# 異常系WKテーブルの過去分削除SQL +PHYSICAL_ABNORMAL_DELETE_QUERY = """\ + DELETE FROM src05.wk_inst_aris_if_wrn +""" + +# 異常系データを取得しWKテーブルに保存SQL +ABNORMAL_INSERT_SELECT_QUERY = """\ + INSERT src05.wk_inst_aris_if_wrn SELECT - TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form - ,TRIM(' ' FROM TRIM(' ' FROM ci.prefc_cd)) AS pref_cd - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(cp.prefc_name,1,8))) AS pref_name - ,TRIM(' ' FROM TRIM(' ' FROM ci.postal_number)) AS postal_cd - ,TRIM(' ' FROM TRIM(' ' FROM cc.city_name)) AS city_name - ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_addr)) AS address - ,TRIM(' ' FROM TRIM(' ' FROM cd.inst_div_name)) - ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_phone_number)) AS phone_no - ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_div_cd)) - ,TRIM(' ' FROM TRIM(' ' FROM ci.manage_cd)) - ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date - ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date - ,sysdate() + TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form + ,TRIM(' ' FROM TRIM(' ' from ci.prefc_cd)) AS pref_cd + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(cp.prefc_name,1,8))) AS pref_name + ,TRIM(' ' FROM TRIM(' ' from ci.postal_number)) AS postal_cd + ,TRIM(' ' FROM TRIM(' ' from cc.city_name)) AS city_name + ,TRIM(' ' FROM TRIM(' ' from ci.inst_addr)) AS address + ,TRIM(' ' FROM TRIM(' ' from cd.inst_div_name)) + ,TRIM(' ' FROM TRIM(' ' from ci.inst_phone_number)) AS phone_no + ,TRIM(' ' FROM TRIM(' ' from ci.inst_div_cd)) + ,TRIM(' ' FROM TRIM(' ' from ci.manage_cd)) + ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date + ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date + ,IF(ci.dcf_dsf_inst_cd IS NULL,'bi0402000001', NULL) AS wrnid_dcf_inst_cd + ,IF(ci.form_inst_name_kanji IS NULL,'bi0402000002', NULL) AS wrnid_inst_name_form + ,IF(ci.prefc_cd IS NULL,'bi0402000003', NULL) AS wrnid_pref_cd + ,IF(cp.prefc_name IS NULL,'bi0402000004', NULL) AS wrnid_pref_name + ,IF(cc.city_name IS NULL,'bi0402000005', NULL) AS wrnid_city_name + ,IF(ci.inst_addr IS NULL,'bi0402000006', NULL) AS wrnid_address + ,sysdate() FROM src05.com_inst ci LEFT JOIN src05.mst_prefc cp - ON ci.prefc_cd = cp.prefc_cd + ON ci.prefc_cd = cp.prefc_cd LEFT JOIN src05.mst_city cc - ON ci.prefc_cd = cc.prefc_cd - AND ci.city_cd = cc.city_cd + ON ci.prefc_cd = cc.prefc_cd + AND ci.city_cd = cc.city_cd LEFT OUTER JOIN src05.com_inst_div cd - ON ci.inst_div_cd = cd.inst_div_cd + ON ci.inst_div_cd = cd.inst_div_cd WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' - AND ci.dcf_dsf_inst_cd IS NOT NULL - AND ci.form_inst_name_kanji IS NOT NULL - AND ci.prefc_cd IS NOT NULL - AND cp.prefc_name IS NOT NULL - AND cc.city_name IS NOT NULL - AND ci.inst_addr IS NOT NULL + AND( ci.dcf_dsf_inst_cd IS NULL + OR ci.form_inst_name_kanji IS NULL + OR ci.prefc_cd IS NULL + OR cp.prefc_name IS NULL + OR cc.city_name IS NULL + OR ci.inst_addr IS NULL) ORDER BY ci.dcf_dsf_inst_cd - """ +""" - # 正常系データの件数を取得SQL - NORMAL_COUNT_QUERY = """\ - SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if - """ +# 正常系データの件数を取得SQL +ABNORMAL_COUNT_QUERY = """\ + SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if_wrn +""" +# CSVファイルの作成用のSQL +SELECT_QUERY = """\ + SELECT dcf_inst_cd, inst_name_form, inst_name, inst_name_kana_form, pref_cd, pref_name, + postal_cd, city_name, address, inst_div_name, phone_no, inst_div_cd, manage_cd, + '', inst_delete_date + FROM src05.wk_inst_aris_if ORDER BY dcf_inst_cd +""" - # 異常系WKテーブルの過去分削除SQL - PHYSICAL_ABNORMAL_DELETE_QUERY = """\ - DELETE FROM src05.wk_inst_aris_if_wrn - """ - - # 異常系データを取得しWKテーブルに保存SQL - ABNORMAL_INSERT_SELECT_QUERY = """\ - INSERT src05.wk_inst_aris_if_wrn - SELECT - TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form - ,TRIM(' ' FROM TRIM(' ' from ci.prefc_cd)) AS pref_cd - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(cp.prefc_name,1,8))) AS pref_name - ,TRIM(' ' FROM TRIM(' ' from ci.postal_number)) AS postal_cd - ,TRIM(' ' FROM TRIM(' ' from cc.city_name)) AS city_name - ,TRIM(' ' FROM TRIM(' ' from ci.inst_addr)) AS address - ,TRIM(' ' FROM TRIM(' ' from cd.inst_div_name)) - ,TRIM(' ' FROM TRIM(' ' from ci.inst_phone_number)) AS phone_no - ,TRIM(' ' FROM TRIM(' ' from ci.inst_div_cd)) - ,TRIM(' ' FROM TRIM(' ' from ci.manage_cd)) - ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date - ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date - ,IF(ci.dcf_dsf_inst_cd IS NULL,'bi0402000001', NULL) AS wrnid_dcf_inst_cd - ,IF(ci.form_inst_name_kanji IS NULL,'bi0402000002', NULL) AS wrnid_inst_name_form - ,IF(ci.prefc_cd IS NULL,'bi0402000003', NULL) AS wrnid_pref_cd - ,IF(cp.prefc_name IS NULL,'bi0402000004', NULL) AS wrnid_pref_name - ,IF(cc.city_name IS NULL,'bi0402000005', NULL) AS wrnid_city_name - ,IF(ci.inst_addr IS NULL,'bi0402000006', NULL) AS wrnid_address - ,sysdate() - FROM src05.com_inst ci - LEFT JOIN src05.mst_prefc cp - ON ci.prefc_cd = cp.prefc_cd - LEFT JOIN src05.mst_city cc - ON ci.prefc_cd = cc.prefc_cd - AND ci.city_cd = cc.city_cd - LEFT OUTER JOIN src05.com_inst_div cd - ON ci.inst_div_cd = cd.inst_div_cd - WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' - AND( ci.dcf_dsf_inst_cd IS NULL - OR ci.form_inst_name_kanji IS NULL - OR ci.prefc_cd IS NULL - OR cp.prefc_name IS NULL - OR cc.city_name IS NULL - OR ci.inst_addr IS NULL) - ORDER BY ci.dcf_dsf_inst_cd - """ - - # 正常系データの件数を取得SQL - ABNORMAL_COUNT_QUERY = """\ - SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if_wrn - """ - # CSVファイルの作成用のSQL - SELECT_QUERY = """\ - SELECT dcf_inst_cd, inst_name_form, inst_name, inst_name_kana_form, pref_cd, pref_name, - postal_cd, city_name, address, inst_div_name, phone_no, inst_div_cd, manage_cd, - '', inst_delete_date - FROM src05.wk_inst_aris_if ORDER BY dcf_inst_cd - """ - - aris_log = '/var/log/temporarydwh/' - move_file_path = '/data/mountaris/DATA/' - create_date = datetime.now().strftime('%Y%m%d%H%M%S') - create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - aris_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' - res_log = f'D0004{create_date}.log' - prg_id = 'PrgId:BI0402' - head_str = 'TC_HOSPITAL, TJ_HOSPITAL, TJ_HOSPITALSHORT, TK_HOSPITAL, \ - TC_PREFECTURE, TJ_PREFECTURE, TJ_ZIPCODE, TJ_CITY, TJ_ADDRESS, TJ_DEPARTMENT, \ - TJ_TELEPHONENUMBER, TC_HOSPITALCAT, TC_HOSPITALTYPE, TS_UPDATE, TD_UPDATE' - - start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。\n" - err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。\n" - csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。\n" - cnt_msg = "MsgID: Message: LogText:" - - def exec_batch_monthly(self): - """ 実消化&アルトマーク月次バッチ """ - try: - # 実行ログに書き込む - resLog = make_log_data(self) - resLog_f = resLog[0] - log_file_path = resLog[1] - resLog_f.write(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.start_msg}') - - db = Database.get_instance() - # DB接続 - db.connect() - # トランザクションの開始 - db.begin() - - # 正常系データの反映 - # 過去分は不要のため、デリート - db.execute(self.PHYSICAL_NORMAL_DELETE_QUERY) - - # 正常系データを取得しWKテーブルに保存する。 - db.execute(self.NORMAL_INSERT_SELECT_QUERY) - - # 正常系データの件数を取得 - record_count = db.execute_select(self.NORMAL_COUNT_QUERY) - suc_count = record_count[0]['countNum'] - - # 警告系データの反映 - # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 - db.execute(self.PHYSICAL_ABNORMAL_DELETE_QUERY) - - # 異常系データを取得しWKテーブルに保存する。 - db.execute(self.ABNORMAL_INSERT_SELECT_QUERY) - - # 異常系データの件数を取得 - record_count = db.execute_select(self.ABNORMAL_COUNT_QUERY) - wrn_count = record_count[0]['countNum'] - - # CSVファイルの作成用のSQL実行 - record_csv = db.execute_select(self.SELECT_QUERY) - - # CSVファイル作成 - csv_file_path = make_csv_data(self, record_csv) - - # テスト用に出力している(あとで消す) - logger.info(log_file_path) - logger.info(csv_file_path) - - # トランザクションの終了 - db.commit() - - # 実行ログファイルの追記 - # 実行ログに処理件数を書き込む。 - sum_count = suc_count + wrn_count - resLog_f.write(f'{self.create_date_format}[DWH][3][INFO]{self.prg_id} {self.cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})\n') - - # 実行ログファイルクローズ - resLog_f.close() - - # ファイル移動処理 - s3_upload_data(self, csv_file_path, log_file_path) - - logger.info('実消化&アルトマーク月次バッチ処理: 終了') - except Exception as e: - resLog_f.write(f'{self.create_date_format}[DWH][5][INFO]{e.message}') - raise BatchOperationException(e) - - finally: - # 終了時に必ずコミットする - db.commit() - db.disconnect() - return +create_date = datetime.now().strftime('%Y%m%d%H%M%S') +create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') +aris_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' +res_log = f'D0004{create_date}.log' +prg_id = 'PrgId:BI0402' +head_str = 'TC_HOSPITAL,TJ_HOSPITAL,TJ_HOSPITALSHORT,TK_HOSPITAL,TC_PREFECTURE,TJ_PREFECTURE,TJ_ZIPCODE,TJ_CITY,TJ_ADDRESS,\ +TJ_DEPARTMENT,TJ_TELEPHONENUMBER,TC_HOSPITALCAT,TC_HOSPITALTYPE,TS_UPDATE, TD_UPDATE' +start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。" +err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。" +csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。" +cnt_msg = "MsgID: Message: LogText:" +move_err_msg = "MsgID:BI0000000041 Message:S3バケットARISへのCSVデータ、実行ログ移動できませんでした。" -def make_csv_data(self, record_csv: list): +def exec(): + """ 実消化&アルトマーク月次バッチ """ + try: + # 実行ログに書き込む + resLog = make_log_data() + resLog_f = resLog[0] + log_file_path = resLog[1] + resLog_f.write(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}\n') + logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}') + + db = Database.get_instance() + # DB接続 + db.connect() + # トランザクションの開始 + db.begin() + + # 正常系データの反映 + # 過去分は不要のため、デリート + db.execute(PHYSICAL_NORMAL_DELETE_QUERY) + + # 正常系データを取得しWKテーブルに保存する。 + db.execute(NORMAL_INSERT_SELECT_QUERY) + + # 正常系データの件数を取得 + record_count = db.execute_select(NORMAL_COUNT_QUERY) + suc_count = record_count[0]['countNum'] + + # 警告系データの反映 + # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 + db.execute(PHYSICAL_ABNORMAL_DELETE_QUERY) + + # 異常系データを取得しWKテーブルに保存する。 + db.execute(ABNORMAL_INSERT_SELECT_QUERY) + + # 異常系データの件数を取得 + record_count = db.execute_select(ABNORMAL_COUNT_QUERY) + wrn_count = record_count[0]['countNum'] + + # CSVファイルの作成用のSQL実行 + record_csv = db.execute_select(SELECT_QUERY) + + # CSVファイル作成 + csv_file_path = make_csv_data(record_csv, resLog_f) + + # トランザクションの終了 + db.commit() + + # 実行ログファイルの追記 + # 実行ログに処理件数を書き込む。 + sum_count = suc_count + wrn_count + resLog_f.write(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})\n') + logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') + + # CSVファイル移動処理 + s3_csv_upload_data(csv_file_path, resLog_f) + + # 実行ログファイルクローズ + resLog_f.close() + + # logファイル移動処理 + s3_log_upload_data(log_file_path) + + logger.info('実消化&アルトマーク月次バッチ処理: 終了') + except Exception as e: + logger.info(f'{create_date_format}[DWH][5][INFO]{e.message}') + raise BatchOperationException(e) + + finally: + # 終了時に必ずコミットする + db.commit() + db.disconnect() + + +def make_csv_data(record_csv: list, resLog_f): # 一時ファイルとして保存する(CSVファイル) - temporary_dir = tempfile.mkdtemp() - csv_file_path = path.join(temporary_dir, self.aris_create_csv) + try: - # ヘッダ行書き込み - fp = open(csv_file_path, mode='w') - fp.write(f'{self.head_str}\n') + temporary_dir = tempfile.mkdtemp() + csv_file_path = path.join(temporary_dir, aris_create_csv) - # データ部分書き込み - for record_data in record_csv: - record_value = list(record_data.values()) - csv_data = ",".join(map(str, record_value)) - fp.write(f'{csv_data}\n') + # ヘッダ行書き込み + fp = open(csv_file_path, mode='w') + fp.write(f'{head_str}\n') + + # データ部分書き込み + for record_data in record_csv: + record_value = list(record_data.values()) + csv_data = ",".join(map(str, record_value)) + fp.write(f'{csv_data}\n') + + # ファイルクローズ + fp.close() + except Exception as e: + resLog_f.write(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}\n') + resLog_f.write(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}\n') + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}') + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}') + raise e - # ファイルクローズ - fp.close() return csv_file_path -def make_log_data(self): +def make_log_data(): # 一時ファイルとして保存する(ログファイル) temporary_dir = tempfile.mkdtemp() - log_file_path = path.join(temporary_dir, self.res_log) + log_file_path = path.join(temporary_dir, res_log) fp = open(log_file_path, mode='w') return fp, log_file_path -def s3_upload_data(self, csv_file_path, log_file_path): +def s3_csv_upload_data(csv_file_path, resLog_f): # s3にログファイルとCSVファイルをUPする - Bucket = os.environ['ARISJ_DATA_BUCKET'] folder = os.environ['ARISJ_DATA_FOLDER'] - csv_file_name = f'{folder}/{self.aris_create_csv}' - log_file_name = f'{folder}/{self.res_log}' - + csv_file_name = f'{folder}/{aris_create_csv}' s3_client = boto3.client('s3') - s3_client.upload_file(csv_file_path, Bucket, csv_file_name) - s3_client.upload_file(csv_file_path, Bucket, log_file_name) + + try: + s3_client.upload_file(csv_file_path, Bucket, csv_file_name) + except Exception as e: + resLog_f.write(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}\n') + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') + raise e + + return + + +def s3_log_upload_data(log_file_path): + # s3にログファイルとCSVファイルをUPする + Bucket = os.environ['ARISJ_DATA_BUCKET'] + folder = os.environ['ARISJ_DATA_FOLDER'] + log_file_name = f'{folder}/{res_log}' + s3_client = boto3.client('s3') + + try: + s3_client.upload_file(log_file_path, Bucket, log_file_name) + except Exception as e: + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') + raise e return diff --git a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py index 3a1e8d68..fdb7d0c1 100644 --- a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py +++ b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py @@ -9,7 +9,7 @@ from src.batch.common.calendar_file import CalendarFile from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger from src.system_var import constants -from src.batch.jskult_batch_monthly import JskultBathcMonthly +from src.batch import jskult_batch_monthly logger = get_logger('月次処理コントロール') @@ -30,12 +30,12 @@ def exec(): # 月次バッチ処理中の場合、後続の処理は行わない if batch_processing_flag == constants.BATCH_ACTF_BATCH_IN_PROCESSING: logger.error('バッチ処理中のため、月次バッチ処理を終了します。') - # 戻すんだよ return constants.BATCH_EXIT_CODE_SUCCESS + return constants.BATCH_EXIT_CODE_SUCCESS # dump取得が正常終了していない場合、後続の処理は行わない if dump_status_kbn != constants.DUMP_STATUS_KBN_COMPLETE: logger.error('dump取得が正常終了していないため、月次バッチ処理を終了します。') - # 戻すんだよ return constants.BATCH_EXIT_CODE_SUCCESS + return constants.BATCH_EXIT_CODE_SUCCESS logger.info(f'処理日={syor_date}') # バッチ共通設定に処理日を追加 @@ -62,8 +62,7 @@ def exec(): try: logger.info('月次バッチ:起動') - BathcMonthly = JskultBathcMonthly() - BathcMonthly.exec_batch_monthly() + jskult_batch_monthly.exec() logger.info('月次バッチ:終了') except BatchOperationException as e: logger.exception(f'月次バッチ処理エラー(異常終了){e}') From be75bf7a9a5f291f8211d746c1b5df0069fc62db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Tue, 27 Jun 2023 16:50:29 +0900 Subject: [PATCH 05/28] =?UTF-8?q?=E4=BB=AE=E5=AE=8C=E6=88=90=EF=BC=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py index fe9b46ee..2a8d4c06 100644 --- a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py +++ b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py @@ -221,6 +221,7 @@ def make_csv_data(record_csv: list, resLog_f): # データ部分書き込み for record_data in record_csv: record_value = list(record_data.values()) + record_value = ['' if n is None else n for n in record_value] csv_data = ",".join(map(str, record_value)) fp.write(f'{csv_data}\n') From e38938a243ac3b2c9a7ee2203496d9f58a9071ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 28 Jun 2023 15:02:16 +0900 Subject: [PATCH 06/28] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BA=8B=E9=A0=85?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=EF=BC=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/.env.example | 29 +- ecs/jskult-batch-monthly/Pipfile | 6 - ecs/jskult-batch-monthly/README.md | 2 +- ecs/jskult-batch-monthly/entrypoint.py | 2 +- ecs/jskult-batch-monthly/src/aws/s3.py | 25 -- .../src/batch/batch_functions.py | 58 +-- .../src/batch/common/batch_context.py | 31 +- .../src/batch/jskult_batch_monthly.py | 278 -------------- .../src/batch/output_arisj_file_process.py | 361 ++++++++++++++++++ .../src/batch/parallel_processes.py | 32 -- .../src/jobctrl_monthly.py | 48 +-- .../src/system_var/constants.py | 9 - .../src/system_var/environment.py | 8 +- 13 files changed, 403 insertions(+), 486 deletions(-) delete mode 100644 ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py create mode 100644 ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py delete mode 100644 ecs/jskult-batch-monthly/src/batch/parallel_processes.py diff --git a/ecs/jskult-batch-monthly/.env.example b/ecs/jskult-batch-monthly/.env.example index f2bb73c8..6bda1a69 100644 --- a/ecs/jskult-batch-monthly/.env.example +++ b/ecs/jskult-batch-monthly/.env.example @@ -1,23 +1,20 @@ DB_HOST=************ -DB_PORT=************ +DB_PORT=3306 DB_USERNAME=************ DB_PASSWORD=************ DB_SCHEMA=src05 + +ARISJ_DATA_BUCKET=mbj-newdwh2021-staging-jskult-arisj +JSKULT_BACKUP_BUCKET=mbj-newdwh2021-staging-backup-jskult +JSKULT_CONFIG_BUCKET=mbj-newdwh2021-staging-config +ULTMARC_BACKUP_FOLDER=************ + LOG_LEVEL=INFO -ULTMARC_DATA_BUCKET=**************** -ULTMARC_DATA_FOLDER=recv -JSKULT_BACKUP_BUCKET=**************** -ULTMARC_BACKUP_FOLDER=ultmarc -JSKULT_CONFIG_BUCKET=********************** -JSKULT_CONFIG_CALENDAR_FOLDER=jskult/calendar -JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME=jskult_holiday_list.txt -ARISJ_DATA_BUCKET=********** -LOG_LEVEL=************** -ARISJ_BACKUP_FOLDER=arisj ARISJ_DATA_FOLDER=DATA +ARISJ_BACKUP_FOLDER=arisj +JSKULT_CONFIG_CALENDAR_FOLDER=jskult/calendar JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME=jskult_arisj_output_day_list.txt -DB_CONNECTION_MAX_RETRY_ATTEMPT=************** -DB_CONNECTION_RETRY_INTERVAL_INIT=************** -DB_CONNECTION_RETRY_INTERVAL_MIN_SECONDS=************** -DB_CONNECTION_RETRY_INTERVAL_MAX_SECONDS=************* -VJSK_DATA_BUCKET=************* \ No newline at end of file +DB_CONNECTION_MAX_RETRY_ATTEMPT=************ +DB_CONNECTION_RETRY_INTERVAL_INIT=************ +DB_CONNECTION_RETRY_INTERVAL_MIN_SECONDS=************ +DB_CONNECTION_RETRY_INTERVAL_MAX_SECONDS=************ diff --git a/ecs/jskult-batch-monthly/Pipfile b/ecs/jskult-batch-monthly/Pipfile index 24e5efcd..fe0fdc38 100644 --- a/ecs/jskult-batch-monthly/Pipfile +++ b/ecs/jskult-batch-monthly/Pipfile @@ -3,10 +3,6 @@ url = "https://pypi.org/simple" verify_ssl = true name = "pypi" -[scripts] -"test:ultmarc" = "pytest tests/batch/ultmarc/" -"test:ultmarc:cov" = "pytest --cov=src/batch/ultmarc/ --cov-branch --cov-report=term-missing tests/batch/ultmarc/" - [packages] boto3 = "*" sqlalchemy = "*" @@ -16,8 +12,6 @@ pymysql = "*" [dev-packages] autopep8 = "*" flake8 = "*" -pytest = "*" -pytest-cov = "*" [requires] python_version = "3.9" diff --git a/ecs/jskult-batch-monthly/README.md b/ecs/jskult-batch-monthly/README.md index acf096d2..f6e7c2da 100644 --- a/ecs/jskult-batch-monthly/README.md +++ b/ecs/jskult-batch-monthly/README.md @@ -42,7 +42,7 @@ - VSCode 上で「F5」キーを押下すると、バッチ処理が起動する。 - 「entrypoint.py」が、バッチ処理のエントリーポイント。 -- 実際の処理は、「src/jobctrl_daily.py」で行っている。 +- 実際の処理は、「src/jobctrl_monthly.py」で行っている。 ## フォルダ構成(工事中) diff --git a/ecs/jskult-batch-monthly/entrypoint.py b/ecs/jskult-batch-monthly/entrypoint.py index 191d0eae..4ab8d3b3 100644 --- a/ecs/jskult-batch-monthly/entrypoint.py +++ b/ecs/jskult-batch-monthly/entrypoint.py @@ -1,4 +1,4 @@ -"""実消化&アルトマーク 日次バッチのエントリーポイント""" +"""実消化&アルトマーク 月次バッチのエントリーポイント""" from src import jobctrl_monthly if __name__ == '__main__': diff --git a/ecs/jskult-batch-monthly/src/aws/s3.py b/ecs/jskult-batch-monthly/src/aws/s3.py index 847f5bad..ed337407 100644 --- a/ecs/jskult-batch-monthly/src/aws/s3.py +++ b/ecs/jskult-batch-monthly/src/aws/s3.py @@ -51,31 +51,6 @@ class S3Bucket(): _bucket_name: str = None -class UltmarcBucket(S3Bucket): - _bucket_name = environment.ULTMARC_DATA_BUCKET - _folder = environment.ULTMARC_DATA_FOLDER - - def list_dat_file(self): - return self._s3_client.list_objects(self._bucket_name, self._folder) - - def download_dat_file(self, dat_filename: str): - # 一時ファイルとして保存する - temporary_dir = tempfile.mkdtemp() - temporary_file_path = path.join(temporary_dir, f'{dat_filename.replace(f"{self._folder}/", "")}') - with open(temporary_file_path, mode='wb') as f: - self._s3_client.download_file(self._bucket_name, dat_filename, f) - f.seek(0) - return temporary_file_path - - def backup_dat_file(self, dat_file_key: str, datetime_key: str): - # バックアップバケットにコピー - ultmarc_backup_bucket = UltmarcBackupBucket() - backup_key = f'{ultmarc_backup_bucket._folder}/{datetime_key}/{dat_file_key.replace(f"{self._folder}/", "")}' - self._s3_client.copy(self._bucket_name, dat_file_key, ultmarc_backup_bucket._bucket_name, backup_key) - # コピー元のファイルを削除 - self._s3_client.delete_file(self._bucket_name, dat_file_key) - - class ConfigBucket(S3Bucket): _bucket_name = environment.JSKULT_CONFIG_BUCKET diff --git a/ecs/jskult-batch-monthly/src/batch/batch_functions.py b/ecs/jskult-batch-monthly/src/batch/batch_functions.py index 27aac450..40cf84f2 100644 --- a/ecs/jskult-batch-monthly/src/batch/batch_functions.py +++ b/ecs/jskult-batch-monthly/src/batch/batch_functions.py @@ -5,23 +5,21 @@ from datetime import datetime from src.db.database import Database from src.error.exceptions import BatchOperationException, DBException -from src.system_var import constants -def get_batch_statuses() -> tuple[str, str, str]: +def get_batch_statuses() -> tuple[str, str]: """日付テーブルから、以下を取得して返す。 - バッチ処理中フラグ - - dump取得状況区分 - 処理日(YYYY/MM/DD) Raises: BatchOperationException: 日付テーブルが取得できないとき、何らかのエラーが発生したとき Returns: - tuple[str, str]: [0]バッチ処理中フラグ、dump取得状況区分 + tuple[str, str]: [0]バッチ処理中フラグ,[1]処理日 """ db = Database.get_instance() - sql = 'SELECT bch_actf, dump_sts_kbn, src05.get_syor_date() AS syor_date FROM src05.hdke_tbl' + sql = 'SELECT bch_actf, src05.get_syor_date() AS syor_date FROM src05.hdke_tbl' try: db.connect() hdke_tbl_result = db.execute_select(sql) @@ -36,59 +34,11 @@ def get_batch_statuses() -> tuple[str, str, str]: # 必ず1件取れる hdke_tbl_record = hdke_tbl_result[0] batch_processing_flag = hdke_tbl_record['bch_actf'] - dump_status_kbn = hdke_tbl_record['dump_sts_kbn'] syor_date = hdke_tbl_record['syor_date'] # 処理日を文字列に変換する syor_date_str = datetime.strftime(syor_date, '%Y/%m/%d') - return batch_processing_flag, dump_status_kbn, syor_date_str - - -def update_batch_processing_flag_in_processing() -> None: - """バッチ処理中フラグを処理中に更新する - - Raises: - BatchOperationException: DB操作の何らかのエラー - """ - db = Database.get_instance() - sql = 'UPDATE src05.hdke_tbl SET bch_actf = :in_processing' - try: - db.connect() - db.execute(sql, {'in_processing': constants.BATCH_ACTF_BATCH_IN_PROCESSING}) - except DBException as e: - raise BatchOperationException(e) - finally: - db.disconnect() - - return - - -def update_batch_process_complete() -> None: - """バッチ処理を完了とし、処理日、バッチ処理中フラグ、dump処理状態区分を更新する - - Raises: - BatchOperationException: DB操作の何らかのエラー - """ - db = Database.get_instance() - sql = """\ - UPDATE src05.hdke_tbl - SET - bch_actf = :batch_complete, - dump_sts_kbn = :dump_unprocessed, - syor_date = DATE_FORMAT((src05.get_syor_date() + interval 1 day), '%Y%m%d') -- +1日 - """ - try: - db.connect() - db.execute(sql, { - 'batch_complete': constants.BATCH_ACTF_BATCH_UNPROCESSED, - 'dump_unprocessed': constants.DUMP_STATUS_KBN_UNPROCESSED - }) - except DBException as e: - raise BatchOperationException(e) - finally: - db.disconnect() - - return + return batch_processing_flag, syor_date_str def logging_sql(logger: logging.Logger, sql: str) -> None: diff --git a/ecs/jskult-batch-monthly/src/batch/common/batch_context.py b/ecs/jskult-batch-monthly/src/batch/common/batch_context.py index 8b76415a..6a05a423 100644 --- a/ecs/jskult-batch-monthly/src/batch/common/batch_context.py +++ b/ecs/jskult-batch-monthly/src/batch/common/batch_context.py @@ -1,10 +1,9 @@ class BatchContext: __instance = None - __syor_date: str # 処理日(yyyy/mm/dd形式) - __is_not_business_monthly: bool # 月次バッチ起動日フラグ + __is_arisj_output_day: bool # 月次バッチ起動日フラグ def __init__(self) -> None: - self.__is_not_business_monthly = False + self.__is_arisj_output_day = False @classmethod def get_instance(cls): @@ -13,25 +12,9 @@ class BatchContext: return cls.__instance @property - def syor_date(self): - return self.__syor_date + def is_arisj_output_day(self): + return self.__is_arisj_output_day - @syor_date.setter - def syor_date(self, syor_date_str: str): - self.__syor_date = syor_date_str - - @property - def is_not_business_monthly(self): - return self.__is_not_business_monthly - - @is_not_business_monthly.setter - def is_not_business_monthly(self, flag: bool): - self.__is_not_business_monthly = flag - - @property - def is_ultmarc_imported(self): - return self.__is_ultmarc_imported - - @is_ultmarc_imported.setter - def is_ultmarc_imported(self, flag: bool): - self.__is_ultmarc_imported = flag + @is_arisj_output_day.setter + def is_arisj_output_day(self, flag: bool): + self.__is_arisj_output_day = flag diff --git a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py b/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py deleted file mode 100644 index 2a8d4c06..00000000 --- a/ecs/jskult-batch-monthly/src/batch/jskult_batch_monthly.py +++ /dev/null @@ -1,278 +0,0 @@ - -from datetime import datetime - -from src.db.database import Database -from src.error.exceptions import BatchOperationException -from src.logging.get_logger import get_logger -import os -import tempfile -import os.path as path -import boto3 - -logger = get_logger('実消化&アルトマーク月次バッチ') - -# WKテーブルの過去分削除SQL -PHYSICAL_NORMAL_DELETE_QUERY = """\ - DELETE FROM src05.wk_inst_aris_if -""" - -# 正常系データを取得しWKテーブルに保存SQL -NORMAL_INSERT_SELECT_QUERY = """\ - INSERT src05.wk_inst_aris_if - SELECT - TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form - ,TRIM(' ' FROM TRIM(' ' FROM ci.prefc_cd)) AS pref_cd - ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(cp.prefc_name,1,8))) AS pref_name - ,TRIM(' ' FROM TRIM(' ' FROM ci.postal_number)) AS postal_cd - ,TRIM(' ' FROM TRIM(' ' FROM cc.city_name)) AS city_name - ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_addr)) AS address - ,TRIM(' ' FROM TRIM(' ' FROM cd.inst_div_name)) - ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_phone_number)) AS phone_no - ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_div_cd)) - ,TRIM(' ' FROM TRIM(' ' FROM ci.manage_cd)) - ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date - ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date - ,sysdate() - FROM src05.com_inst ci - LEFT JOIN src05.mst_prefc cp - ON ci.prefc_cd = cp.prefc_cd - LEFT JOIN src05.mst_city cc - ON ci.prefc_cd = cc.prefc_cd - AND ci.city_cd = cc.city_cd - LEFT OUTER JOIN src05.com_inst_div cd - ON ci.inst_div_cd = cd.inst_div_cd - WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' - AND ci.dcf_dsf_inst_cd IS NOT NULL - AND ci.form_inst_name_kanji IS NOT NULL - AND ci.prefc_cd IS NOT NULL - AND cp.prefc_name IS NOT NULL - AND cc.city_name IS NOT NULL - AND ci.inst_addr IS NOT NULL - ORDER BY ci.dcf_dsf_inst_cd -""" - -# 正常系データの件数を取得SQL -NORMAL_COUNT_QUERY = """\ - SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if -""" - -# 異常系WKテーブルの過去分削除SQL -PHYSICAL_ABNORMAL_DELETE_QUERY = """\ - DELETE FROM src05.wk_inst_aris_if_wrn -""" - -# 異常系データを取得しWKテーブルに保存SQL -ABNORMAL_INSERT_SELECT_QUERY = """\ - INSERT src05.wk_inst_aris_if_wrn - SELECT - TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form - ,TRIM(' ' FROM TRIM(' ' from ci.prefc_cd)) AS pref_cd - ,TRIM(' ' FROM TRIM(' ' from SUBSTR(cp.prefc_name,1,8))) AS pref_name - ,TRIM(' ' FROM TRIM(' ' from ci.postal_number)) AS postal_cd - ,TRIM(' ' FROM TRIM(' ' from cc.city_name)) AS city_name - ,TRIM(' ' FROM TRIM(' ' from ci.inst_addr)) AS address - ,TRIM(' ' FROM TRIM(' ' from cd.inst_div_name)) - ,TRIM(' ' FROM TRIM(' ' from ci.inst_phone_number)) AS phone_no - ,TRIM(' ' FROM TRIM(' ' from ci.inst_div_cd)) - ,TRIM(' ' FROM TRIM(' ' from ci.manage_cd)) - ,DATE_FORMAT(ci.sys_update_date,'%y%m%d') AS update_date - ,DATE_FORMAT(ci.abolish_ymd,'%y%m%d') AS delete_date - ,IF(ci.dcf_dsf_inst_cd IS NULL,'bi0402000001', NULL) AS wrnid_dcf_inst_cd - ,IF(ci.form_inst_name_kanji IS NULL,'bi0402000002', NULL) AS wrnid_inst_name_form - ,IF(ci.prefc_cd IS NULL,'bi0402000003', NULL) AS wrnid_pref_cd - ,IF(cp.prefc_name IS NULL,'bi0402000004', NULL) AS wrnid_pref_name - ,IF(cc.city_name IS NULL,'bi0402000005', NULL) AS wrnid_city_name - ,IF(ci.inst_addr IS NULL,'bi0402000006', NULL) AS wrnid_address - ,sysdate() - FROM src05.com_inst ci - LEFT JOIN src05.mst_prefc cp - ON ci.prefc_cd = cp.prefc_cd - LEFT JOIN src05.mst_city cc - ON ci.prefc_cd = cc.prefc_cd - AND ci.city_cd = cc.city_cd - LEFT OUTER JOIN src05.com_inst_div cd - ON ci.inst_div_cd = cd.inst_div_cd - WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' - AND( ci.dcf_dsf_inst_cd IS NULL - OR ci.form_inst_name_kanji IS NULL - OR ci.prefc_cd IS NULL - OR cp.prefc_name IS NULL - OR cc.city_name IS NULL - OR ci.inst_addr IS NULL) - ORDER BY ci.dcf_dsf_inst_cd -""" - -# 正常系データの件数を取得SQL -ABNORMAL_COUNT_QUERY = """\ - SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if_wrn -""" -# CSVファイルの作成用のSQL -SELECT_QUERY = """\ - SELECT dcf_inst_cd, inst_name_form, inst_name, inst_name_kana_form, pref_cd, pref_name, - postal_cd, city_name, address, inst_div_name, phone_no, inst_div_cd, manage_cd, - '', inst_delete_date - FROM src05.wk_inst_aris_if ORDER BY dcf_inst_cd -""" - -create_date = datetime.now().strftime('%Y%m%d%H%M%S') -create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') -aris_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' -res_log = f'D0004{create_date}.log' -prg_id = 'PrgId:BI0402' -head_str = 'TC_HOSPITAL,TJ_HOSPITAL,TJ_HOSPITALSHORT,TK_HOSPITAL,TC_PREFECTURE,TJ_PREFECTURE,TJ_ZIPCODE,TJ_CITY,TJ_ADDRESS,\ -TJ_DEPARTMENT,TJ_TELEPHONENUMBER,TC_HOSPITALCAT,TC_HOSPITALTYPE,TS_UPDATE, TD_UPDATE' -start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。" -err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。" -csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。" -cnt_msg = "MsgID: Message: LogText:" -move_err_msg = "MsgID:BI0000000041 Message:S3バケットARISへのCSVデータ、実行ログ移動できませんでした。" - - -def exec(): - """ 実消化&アルトマーク月次バッチ """ - try: - # 実行ログに書き込む - resLog = make_log_data() - resLog_f = resLog[0] - log_file_path = resLog[1] - resLog_f.write(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}\n') - logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}') - - db = Database.get_instance() - # DB接続 - db.connect() - # トランザクションの開始 - db.begin() - - # 正常系データの反映 - # 過去分は不要のため、デリート - db.execute(PHYSICAL_NORMAL_DELETE_QUERY) - - # 正常系データを取得しWKテーブルに保存する。 - db.execute(NORMAL_INSERT_SELECT_QUERY) - - # 正常系データの件数を取得 - record_count = db.execute_select(NORMAL_COUNT_QUERY) - suc_count = record_count[0]['countNum'] - - # 警告系データの反映 - # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 - db.execute(PHYSICAL_ABNORMAL_DELETE_QUERY) - - # 異常系データを取得しWKテーブルに保存する。 - db.execute(ABNORMAL_INSERT_SELECT_QUERY) - - # 異常系データの件数を取得 - record_count = db.execute_select(ABNORMAL_COUNT_QUERY) - wrn_count = record_count[0]['countNum'] - - # CSVファイルの作成用のSQL実行 - record_csv = db.execute_select(SELECT_QUERY) - - # CSVファイル作成 - csv_file_path = make_csv_data(record_csv, resLog_f) - - # トランザクションの終了 - db.commit() - - # 実行ログファイルの追記 - # 実行ログに処理件数を書き込む。 - sum_count = suc_count + wrn_count - resLog_f.write(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})\n') - logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') - - # CSVファイル移動処理 - s3_csv_upload_data(csv_file_path, resLog_f) - - # 実行ログファイルクローズ - resLog_f.close() - - # logファイル移動処理 - s3_log_upload_data(log_file_path) - - logger.info('実消化&アルトマーク月次バッチ処理: 終了') - except Exception as e: - logger.info(f'{create_date_format}[DWH][5][INFO]{e.message}') - raise BatchOperationException(e) - - finally: - # 終了時に必ずコミットする - db.commit() - db.disconnect() - - -def make_csv_data(record_csv: list, resLog_f): - # 一時ファイルとして保存する(CSVファイル) - try: - - temporary_dir = tempfile.mkdtemp() - csv_file_path = path.join(temporary_dir, aris_create_csv) - - # ヘッダ行書き込み - fp = open(csv_file_path, mode='w') - fp.write(f'{head_str}\n') - - # データ部分書き込み - for record_data in record_csv: - record_value = list(record_data.values()) - record_value = ['' if n is None else n for n in record_value] - csv_data = ",".join(map(str, record_value)) - fp.write(f'{csv_data}\n') - - # ファイルクローズ - fp.close() - except Exception as e: - resLog_f.write(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}\n') - resLog_f.write(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}\n') - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}') - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}') - raise e - - return csv_file_path - - -def make_log_data(): - # 一時ファイルとして保存する(ログファイル) - temporary_dir = tempfile.mkdtemp() - log_file_path = path.join(temporary_dir, res_log) - fp = open(log_file_path, mode='w') - return fp, log_file_path - - -def s3_csv_upload_data(csv_file_path, resLog_f): - # s3にログファイルとCSVファイルをUPする - Bucket = os.environ['ARISJ_DATA_BUCKET'] - folder = os.environ['ARISJ_DATA_FOLDER'] - csv_file_name = f'{folder}/{aris_create_csv}' - s3_client = boto3.client('s3') - - try: - s3_client.upload_file(csv_file_path, Bucket, csv_file_name) - except Exception as e: - resLog_f.write(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}\n') - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') - raise e - - return - - -def s3_log_upload_data(log_file_path): - # s3にログファイルとCSVファイルをUPする - Bucket = os.environ['ARISJ_DATA_BUCKET'] - folder = os.environ['ARISJ_DATA_FOLDER'] - log_file_name = f'{folder}/{res_log}' - s3_client = boto3.client('s3') - - try: - s3_client.upload_file(log_file_path, Bucket, log_file_name) - except Exception as e: - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') - raise e - - return diff --git a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py new file mode 100644 index 00000000..0deec661 --- /dev/null +++ b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py @@ -0,0 +1,361 @@ + +from datetime import datetime + +from src.db.database import Database +from src.error.exceptions import BatchOperationException +from src.aws.s3 import S3Client +from src.logging.get_logger import get_logger +import tempfile +import os +import os.path as path +import logging +import csv + +logger = get_logger('実消化&アルトマーク月次バッチ') + +create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') +prg_id = 'PrgId:BI0402' +create_date = datetime.now().strftime('%Y%m%d%H%M%S') +aris_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' +res_log = f'D0004{create_date}.log' +sql_err_msg = "MsgID:999999000002 Message:SQL実行エラーです。" +move_err_msg = "MsgID:BI0000000041 Message:S3バケットARISへのCSVデータ、実行ログ移動できませんでした。" + + +def exec(): + """ 実消化&アルトマーク月次バッチ """ + try: + + start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。" + cnt_msg = "MsgID: Message: LogText:" + + # 実行ログに書き込む + resLog, log_file_path = make_log_data() + resLog.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}') + logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}') + + db = Database.get_instance() + # DB接続 + db.connect() + # トランザクションの開始 + db.begin() + + # 正常系データの反映 + # 過去分は不要のため、デリート + physical_normal_delete(db) + + # 正常系データを取得しWKテーブルに保存する。 + normal_insert_into(db) + + # 正常系データの件数を取得 + suc_count = normal_count(db) + + # 警告系データの反映 + # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 + physical_abnormal_delete(db) + + # 異常系データを取得しWKテーブルに保存する。 + abnormal_insert_into(db) + + # 異常系データの件数を取得 + wrn_count = abnormal_count(db) + + # CSVファイルの作成用のSQL実行 + record_csv = csv_data_select(db) + + # CSVファイル作成 + csv_file_path = make_csv_data(record_csv, resLog) + + # トランザクションの終了 + db.commit() + + # 実行ログファイルの追記 + # 実行ログに処理件数を書き込む。 + sum_count = suc_count + wrn_count + resLog.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') + logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') + + # CSVファイル移動処理 + s3_csv_upload_data(csv_file_path, resLog) + + # logファイル移動処理 + s3_log_upload_data(log_file_path) + + logger.info('実消化&アルトマーク月次バッチ処理: 終了') + except Exception as e: + logger.info(f'{create_date_format}[DWH][5][INFO]') + raise BatchOperationException(e) + + finally: + # 終了時に必ずコミットする + db.commit() + db.disconnect() + + +def physical_normal_delete(db): + # 過去分は不要のため、デリート + try: + # WKテーブルの過去分削除SQL + sql = """\ + DELETE FROM src05.wk_inst_aris_if + """ + db.execute(sql) + return + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def normal_insert_into(db): + # 正常系データを取得しWKテーブルに保存する。 + try: + # 正常系データを取得しWKテーブルに保存SQL + sql = """\ + INSERT src05.wk_inst_aris_if + SELECT + TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form + ,TRIM(' ' FROM TRIM(' ' FROM ci.prefc_cd)) AS pref_cd + ,TRIM(' ' FROM TRIM(' ' FROM SUBSTR(cp.prefc_name,1,8))) AS pref_name + ,TRIM(' ' FROM TRIM(' ' FROM ci.postal_number)) AS postal_cd + ,TRIM(' ' FROM TRIM(' ' FROM cc.city_name)) AS city_name + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_addr)) AS address + ,TRIM(' ' FROM TRIM(' ' FROM cd.inst_div_name)) + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_phone_number)) AS phone_no + ,TRIM(' ' FROM TRIM(' ' FROM ci.inst_div_cd)) + ,TRIM(' ' FROM TRIM(' ' FROM ci.manage_cd)) + ,DATE_FORMAT(ci.sys_update_date,'%Y%m%d') AS update_date + ,DATE_FORMAT(ci.abolish_ymd,'%Y%m%d') AS delete_date + ,sysdate() + FROM src05.com_inst ci + LEFT JOIN src05.mst_prefc cp + ON ci.prefc_cd = cp.prefc_cd + LEFT JOIN src05.mst_city cc + ON ci.prefc_cd = cc.prefc_cd + AND ci.city_cd = cc.city_cd + LEFT OUTER JOIN src05.com_inst_div cd + ON ci.inst_div_cd = cd.inst_div_cd + WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' + AND ci.dcf_dsf_inst_cd IS NOT NULL + AND ci.form_inst_name_kanji IS NOT NULL + AND ci.prefc_cd IS NOT NULL + AND cp.prefc_name IS NOT NULL + AND cc.city_name IS NOT NULL + AND ci.inst_addr IS NOT NULL + ORDER BY ci.dcf_dsf_inst_cd + """ + + db.execute(sql) + return + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def normal_count(db): + # 正常系データの件数を取得 + try: + # 正常系データの件数を取得SQL + sql = """\ + SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if + """ + record_count = db.execute_select(sql) + return record_count[0]['countNum'] + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def physical_abnormal_delete(db): + # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 + try: + # 異常系WKテーブルの過去分削除SQL + sql = """\ + DELETE FROM src05.wk_inst_aris_if_wrn + """ + + db.execute(sql) + return + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def abnormal_insert_into(db): + # 異常系データを取得しWKテーブルに保存する。 + try: + # 異常系データを取得しWKテーブルに保存SQL + sql = """\ + INSERT src05.wk_inst_aris_if_wrn + SELECT + TRIM(' ' FROM TRIM(' ' FROM SUBSTRING(ci.dcf_dsf_inst_cd,3))) AS dcf_inst_cd + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kanji,1,50))) AS inst_name_form + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.inst_name_kanji,1,10))) AS inst_name + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(ci.form_inst_name_kana,1,80))) AS inst_name_kana_form + ,TRIM(' ' FROM TRIM(' ' from ci.prefc_cd)) AS pref_cd + ,TRIM(' ' FROM TRIM(' ' from SUBSTR(cp.prefc_name,1,8))) AS pref_name + ,TRIM(' ' FROM TRIM(' ' from ci.postal_number)) AS postal_cd + ,TRIM(' ' FROM TRIM(' ' from cc.city_name)) AS city_name + ,TRIM(' ' FROM TRIM(' ' from ci.inst_addr)) AS address + ,TRIM(' ' FROM TRIM(' ' from cd.inst_div_name)) + ,TRIM(' ' FROM TRIM(' ' from ci.inst_phone_number)) AS phone_no + ,TRIM(' ' FROM TRIM(' ' from ci.inst_div_cd)) + ,TRIM(' ' FROM TRIM(' ' from ci.manage_cd)) + ,DATE_FORMAT(ci.sys_update_date,'%Y%m%d') AS update_date + ,DATE_FORMAT(ci.abolish_ymd,'%Y%m%d') AS delete_date + ,IF(ci.dcf_dsf_inst_cd IS NULL,'bi0402000001', NULL) AS wrnid_dcf_inst_cd + ,IF(ci.form_inst_name_kanji IS NULL,'bi0402000002', NULL) AS wrnid_inst_name_form + ,IF(ci.prefc_cd IS NULL,'bi0402000003', NULL) AS wrnid_pref_cd + ,IF(cp.prefc_name IS NULL,'bi0402000004', NULL) AS wrnid_pref_name + ,IF(cc.city_name IS NULL,'bi0402000005', NULL) AS wrnid_city_name + ,IF(ci.inst_addr IS NULL,'bi0402000006', NULL) AS wrnid_address + ,sysdate() + FROM src05.com_inst ci + LEFT JOIN src05.mst_prefc cp + ON ci.prefc_cd = cp.prefc_cd + LEFT JOIN src05.mst_city cc + ON ci.prefc_cd = cc.prefc_cd + AND ci.city_cd = cc.city_cd + LEFT OUTER JOIN src05.com_inst_div cd + ON ci.inst_div_cd = cd.inst_div_cd + WHERE ci.dcf_dsf_inst_cd NOT LIKE '%9999999%' + AND( ci.dcf_dsf_inst_cd IS NULL + OR ci.form_inst_name_kanji IS NULL + OR ci.prefc_cd IS NULL + OR cp.prefc_name IS NULL + OR cc.city_name IS NULL + OR ci.inst_addr IS NULL) + ORDER BY ci.dcf_dsf_inst_cd + """ + + db.execute(sql) + return + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def abnormal_count(db): + # 異常系データの件数を取得 + try: + # 異常系データの件数を取得SQL + sql = """\ + SELECT COUNT(*) AS countNum FROM src05.wk_inst_aris_if_wrn + """ + + record_count = db.execute_select(sql) + + return record_count[0]['countNum'] + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def csv_data_select(db): + # CSVファイルの作成用のSQL実行 + try: + # CSVファイルの作成用のSQL + sql = """\ + SELECT dcf_inst_cd, inst_name_form, inst_name, inst_name_kana_form, pref_cd, pref_name, + postal_cd, city_name, address, inst_div_name, phone_no, inst_div_cd, manage_cd, + '', inst_delete_date + FROM src05.wk_inst_aris_if ORDER BY dcf_inst_cd + """ + + return db.execute_select(sql) + except Exception as e: + logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + raise e + + +def make_csv_data(record_csv: list, resLog): + # 一時ファイルとして保存する(CSVファイル) + try: + err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。" + csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。" + + temporary_dir = tempfile.mkdtemp() + csv_file_path = path.join(temporary_dir, aris_create_csv) + + head_str = ['TC_HOSPITAL', 'TJ_HOSPITAL', 'TJ_HOSPITALSHORT', 'TK_HOSPITAL', + 'TC_PREFECTURE', 'TJ_PREFECTURE', 'TJ_ZIPCODE', 'TJ_CITY', 'TJ_ADDRESS', 'TJ_DEPARTMENT', + 'TJ_TELEPHONENUMBER', 'TC_HOSPITALCAT', 'TC_HOSPITALTYPE', 'TS_UPDATE', ' TD_UPDATE'] + + # Shift-JIS、CRLF、価囲いありで書き込む + with open(csv_file_path, mode='w', encoding='cp932') as csv_file: + writer = csv.writer(csv_file, delimiter=',', lineterminator='\n', + quotechar='"', doublequote=True, quoting=csv.QUOTE_ALL, + strict=True + ) + # ヘッダ行書き込み + writer.writerow(head_str) + # データ部分書き込み + for record_data in record_csv: + record_value = list(record_data.values()) + csv_data = ['' if n is None else n for n in record_value] + writer.writerow(csv_data) + + except Exception as e: + resLog.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}') + resLog.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}') + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}') + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}') + raise e + + return csv_file_path + + +def make_log_data(): + # 一時ファイルとして保存する(ログファイル) + temporary_dir = tempfile.mkdtemp() + log_file_path = path.join(temporary_dir, res_log) + + # ロガーの生成 + resLog = logging.getLogger('resLog') + # 出力レベルの設定 + resLog.setLevel(logging.INFO) + # ハンドラの生成 + resLog_handler = logging.FileHandler(log_file_path) + # ロガーにハンドラを登録 + resLog.addHandler(resLog_handler) + # フォーマッタの生成 + fmt = logging.Formatter('%(message)s') + # ハンドラにフォーマッタを登録 + resLog_handler.setFormatter(fmt) + + return resLog, log_file_path + + +def s3_csv_upload_data(csv_file_path, resLog): + # s3にCSVファイルをUPする + Bucket = os.environ['ARISJ_DATA_BUCKET'] + folder = os.environ['ARISJ_DATA_FOLDER'] + csv_file_name = f'{folder}/{aris_create_csv}' + s3_client = S3Client() + + try: + s3_client.upload_file(csv_file_path, Bucket, csv_file_name) + except Exception as e: + resLog.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') + raise e + + return + + +def s3_log_upload_data(log_file_path): + # s3にログファイルをUPする + Bucket = os.environ['ARISJ_DATA_BUCKET'] + folder = os.environ['ARISJ_DATA_FOLDER'] + log_file_name = f'{folder}/{res_log}' + s3_client = S3Client() + + try: + s3_client.upload_file(log_file_path, Bucket, log_file_name) + except Exception as e: + logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') + raise e + + return diff --git a/ecs/jskult-batch-monthly/src/batch/parallel_processes.py b/ecs/jskult-batch-monthly/src/batch/parallel_processes.py deleted file mode 100644 index 0fb2d715..00000000 --- a/ecs/jskult-batch-monthly/src/batch/parallel_processes.py +++ /dev/null @@ -1,32 +0,0 @@ -"""並列処理""" - -import concurrent.futures - -from src.batch.bio_sales import create_bio_sales_lot -from src.batch.laundering import sales_laundering -from src.error.exceptions import BatchOperationException - - -def exec(): - # 並列処理を開始 - with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: - - # 実績更新 - future_sales_laundering = executor.submit(sales_laundering.exec) - # 生物由来ロット分解 - future_create_bio_sales_lot = executor.submit(create_bio_sales_lot.exec) - - # 両方の処理が完了するまで待つ - concurrent.futures.wait([future_sales_laundering, future_create_bio_sales_lot]) - - # エラーがあれば呼び出し元でキャッチする - sales_laundering_exc = future_sales_laundering.exception() - create_bio_sales_lot_exc = future_create_bio_sales_lot.exception() - - # いずれかにエラーが発生していれば、1つのエラーとして返す。 - if sales_laundering_exc is not None or create_bio_sales_lot_exc is not None: - sales_laundering_exc_message = str(sales_laundering_exc) if sales_laundering_exc is not None else '' - create_bio_sales_lot_exc_message = str(create_bio_sales_lot_exc) if create_bio_sales_lot_exc is not None else '' - raise BatchOperationException(f'並列処理中にエラーが発生しました。実績更新="{sales_laundering_exc_message}", 生物由来ロット分解={create_bio_sales_lot_exc_message}') - - return diff --git a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py index fdb7d0c1..dba5fac4 100644 --- a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py +++ b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py @@ -1,15 +1,13 @@ """実消化&アルトマーク 月次バッチ処理""" from src.aws.s3 import ConfigBucket -from src.batch.batch_functions import ( - get_batch_statuses, update_batch_process_complete, - update_batch_processing_flag_in_processing) +from src.batch.batch_functions import get_batch_statuses from src.batch.common.batch_context import BatchContext from src.batch.common.calendar_file import CalendarFile from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger from src.system_var import constants -from src.batch import jskult_batch_monthly +from src.batch import output_arisj_file_process logger = get_logger('月次処理コントロール') @@ -22,64 +20,42 @@ def exec(): logger.info('月次バッチ:開始') try: # 月次バッチ処置中フラグ、dump処理状態区分、処理日を取得 - batch_processing_flag, dump_status_kbn, syor_date = get_batch_statuses() + batch_processing_flag, syor_date = get_batch_statuses() except BatchOperationException as e: logger.exception(f'日付テーブル取得(異常終了){e}') return constants.BATCH_EXIT_CODE_SUCCESS - # 月次バッチ処理中の場合、後続の処理は行わない + # 日次バッチ処理中の場合、後続の処理は行わない if batch_processing_flag == constants.BATCH_ACTF_BATCH_IN_PROCESSING: - logger.error('バッチ処理中のため、月次バッチ処理を終了します。') - return constants.BATCH_EXIT_CODE_SUCCESS - - # dump取得が正常終了していない場合、後続の処理は行わない - if dump_status_kbn != constants.DUMP_STATUS_KBN_COMPLETE: - logger.error('dump取得が正常終了していないため、月次バッチ処理を終了します。') + logger.error('日次バッチ処理中のため、月次バッチ処理を終了します。') return constants.BATCH_EXIT_CODE_SUCCESS logger.info(f'処理日={syor_date}') - # バッチ共通設定に処理日を追加 - batch_context.syor_date = syor_date # 稼働日かかどうかを、実消化&アルトマーク月次バッチ稼働日ファイルをダウンロードして判定 try: arisj_output_day_list_file_path = ConfigBucket().download_arisj_output_day_list() arisj_output_day_calendar = CalendarFile(arisj_output_day_list_file_path) - batch_context.is_not_business_monthly = arisj_output_day_calendar.compare_date(syor_date) + batch_context.is_arisj_output_day = arisj_output_day_calendar.compare_date(syor_date) except Exception as e: logger.exception(f'実消化&アルトマーク月次バッチ稼働日ファイルの読み込みに失敗しました。{e}') return constants.BATCH_EXIT_CODE_SUCCESS - # 調査目的でV実消化稼働日かどうかをログ出力 - logger.debug(f'本日は{"実消化&アルトマーク月次バッチ稼働日です。" if batch_context.is_not_business_monthly else "実消化&アルトマーク月次バッチ非稼働日です。"}') - - # バッチ処理中に更新 - try: - update_batch_processing_flag_in_processing() - except BatchOperationException as e: - logger.exception(f'処理フラグ更新(未処理→処理中) エラー(異常終了){e}') + # 調査目的で実消化&アルトマーク月次バッチ稼働日かどうかをログ出力 + if batch_context.is_arisj_output_day: + logger.info('本日は実消化&アルトマーク月次バッチ稼働日です。') + else: + logger.info('月次バッチは行われませんでした。') return constants.BATCH_EXIT_CODE_SUCCESS try: logger.info('月次バッチ:起動') - jskult_batch_monthly.exec() + output_arisj_file_process.exec() logger.info('月次バッチ:終了') except BatchOperationException as e: logger.exception(f'月次バッチ処理エラー(異常終了){e}') return constants.BATCH_EXIT_CODE_SUCCESS - # 調査目的で月次バッチが行われたかどうかをログ出力 - logger.debug(f'{"月次バッチが行われました。" if batch_context.is_not_business_monthly else "月次バッチが行われませんでした。"}') - - # バッチ処理完了とし、処理日、バッチ処置中フラグ、dump取得状態区分を更新 - logger.info('業務日付更新・バッチステータスリフレッシュ:起動') - try: - update_batch_process_complete() - except BatchOperationException as e: - logger.exception(f'業務日付更新・バッチステータスリフレッシュ エラー(異常終了){e}') - return constants.BATCH_EXIT_CODE_SUCCESS - logger.info('業務日付更新・バッチステータスリフレッシュ:終了') - # 正常終了を保守ユーザーに通知 logger.info('[NOTICE]月次バッチ:終了(正常終了)') return constants.BATCH_EXIT_CODE_SUCCESS diff --git a/ecs/jskult-batch-monthly/src/system_var/constants.py b/ecs/jskult-batch-monthly/src/system_var/constants.py index 8a0ccbb3..aaa8a3c0 100644 --- a/ecs/jskult-batch-monthly/src/system_var/constants.py +++ b/ecs/jskult-batch-monthly/src/system_var/constants.py @@ -1,17 +1,8 @@ # バッチ正常終了コード BATCH_EXIT_CODE_SUCCESS = 0 -# バッチ処理中フラグ:未処理 -BATCH_ACTF_BATCH_UNPROCESSED = '0' # バッチ処理中フラグ:処理中 BATCH_ACTF_BATCH_IN_PROCESSING = '1' -# dump取得状態区分:未処理 -DUMP_STATUS_KBN_UNPROCESSED = '0' -# dump取得状態区分:dump取得正常終了 -DUMP_STATUS_KBN_COMPLETE = '2' # カレンダーファイルのコメントシンボル CALENDAR_COMMENT_SYMBOL = '#' - -# 月曜日(datetime.weekday()で月曜日を表す数字) -WEEKDAY_MONDAY = 0 diff --git a/ecs/jskult-batch-monthly/src/system_var/environment.py b/ecs/jskult-batch-monthly/src/system_var/environment.py index 25afc294..c98503dd 100644 --- a/ecs/jskult-batch-monthly/src/system_var/environment.py +++ b/ecs/jskult-batch-monthly/src/system_var/environment.py @@ -8,14 +8,14 @@ DB_PASSWORD = os.environ['DB_PASSWORD'] DB_SCHEMA = os.environ['DB_SCHEMA'] # AWS -ULTMARC_DATA_BUCKET = os.environ['ULTMARC_DATA_BUCKET'] -ULTMARC_DATA_FOLDER = os.environ['ULTMARC_DATA_FOLDER'] +ARISJ_DATA_BUCKET = os.environ['ARISJ_DATA_BUCKET'] JSKULT_BACKUP_BUCKET = os.environ['JSKULT_BACKUP_BUCKET'] -ULTMARC_BACKUP_FOLDER = os.environ['ULTMARC_BACKUP_FOLDER'] JSKULT_CONFIG_BUCKET = os.environ['JSKULT_CONFIG_BUCKET'] +ARISJ_DATA_FOLDER = os.environ['ARISJ_DATA_FOLDER'] +ARISJ_BACKUP_FOLDER = os.environ['ARISJ_BACKUP_FOLDER'] JSKULT_CONFIG_CALENDAR_FOLDER = os.environ['JSKULT_CONFIG_CALENDAR_FOLDER'] -JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME'] JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME'] +ULTMARC_BACKUP_FOLDER = os.environ['ULTMARC_BACKUP_FOLDER'] # 初期値がある環境変数 LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') From b326bf65a9a1c44b9ea1bdd57f045671a1df2492 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Mon, 3 Jul 2023 11:38:18 +0900 Subject: [PATCH 07/28] =?UTF-8?q?style:=20=E3=83=86=E3=83=BC=E3=83=96?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E3=83=95=E3=82=A9=E3=83=B3=E3=83=88=E3=82=B5?= =?UTF-8?q?=E3=82=A4=E3=82=BA=E8=AA=BF=E6=95=B4=208pt=E2=86=9212pt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-webapp/src/static/css/ultStyle.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ecs/jskult-webapp/src/static/css/ultStyle.css b/ecs/jskult-webapp/src/static/css/ultStyle.css index 8d018b01..382ef4fd 100644 --- a/ecs/jskult-webapp/src/static/css/ultStyle.css +++ b/ecs/jskult-webapp/src/static/css/ultStyle.css @@ -633,14 +633,14 @@ table{ table.tablesorter { font-family:arial; background-color: #CDCDCD; - font-size: 8pt; + font-size: 12pt; text-align: left; } table.tablesorter thead tr th, table.tablesorter tfoot tr th { background-color: #e6EEEE; border: 0.1px solid silver; - font-size: 8pt; + font-size: 12pt; padding: 4px; padding-right: 20px; } From 46304d5b2c47d45aa260922b1effef88c359c0d6 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Mon, 3 Jul 2023 11:41:32 +0900 Subject: [PATCH 08/28] =?UTF-8?q?style:=20=E4=BB=A5=E4=B8=8B=E3=82=92?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C=20=E3=83=BB=E3=80=8CPrev=E3=80=8D=E3=80=8CNe?= =?UTF-8?q?xt=E3=80=8D=E3=83=9C=E3=82=BF=E3=83=B3=E3=81=8C=E4=B8=80?= =?UTF-8?q?=E8=A6=A7=E3=81=AE=E9=A0=85=E7=9B=AE=E5=90=8D=E3=81=A8=E9=87=8D?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=A6=E3=81=84=E3=82=8B=20=E3=83=BB?= =?UTF-8?q?=E4=B8=80=E8=A6=A7=E3=82=92=E3=82=B9=E3=82=AF=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=83=AB=E3=81=99=E3=82=8B=E3=81=A8=E3=83=81=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=82=AF=E3=83=9C=E3=83=83=E3=82=AF=E3=82=B9=E3=81=AE=E5=B9=85?= =?UTF-8?q?=E3=81=8C=E5=A4=89=E3=82=8F=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-webapp/src/static/css/bioStyle.css | 9 +++++++-- ecs/jskult-webapp/src/static/css/ultStyle.css | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ecs/jskult-webapp/src/static/css/bioStyle.css b/ecs/jskult-webapp/src/static/css/bioStyle.css index 8bc72999..c0ab2ca5 100644 --- a/ecs/jskult-webapp/src/static/css/bioStyle.css +++ b/ecs/jskult-webapp/src/static/css/bioStyle.css @@ -1,3 +1,9 @@ +/* Bootstrap 5.10以降、box-sizingのデフォルト値によってテーブルがずれるため、このページ限定的にリセット */ +/* @see https://bootstrap-guide.com/content/reboot#page-defaults */ +*, ::after, ::before { + box-sizing: initial; +} + body { white-space: nowrap; background-color: LightCyan; @@ -75,7 +81,7 @@ table{ .bioScroll_div { overflow: auto; - padding-top: 10px; + margin-top: 1%; height: 250px; width: 1132px; } @@ -215,7 +221,6 @@ table{ .result_tr{ overflow-y: scroll; overflow-x: scroll; - } .result_data{ diff --git a/ecs/jskult-webapp/src/static/css/ultStyle.css b/ecs/jskult-webapp/src/static/css/ultStyle.css index 382ef4fd..e39fa143 100644 --- a/ecs/jskult-webapp/src/static/css/ultStyle.css +++ b/ecs/jskult-webapp/src/static/css/ultStyle.css @@ -1,3 +1,9 @@ +/* Bootstrap 5.10以降、box-sizingのデフォルト値によってテーブルがずれるため、このページ限定的にリセット */ +/* @see https://bootstrap-guide.com/content/reboot#page-defaults */ +*, ::after, ::before { + box-sizing: initial; +} + body { background-color: LightCyan; font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; @@ -39,8 +45,8 @@ table{ .scroll_table{ overflow: auto; white-space: nowrap; - margin-bottom: 2%; - /*スクロール時カラムが動く問題の修正 width: 100%;をコメントアウト*/ + margin-top: 1%; + margin-bottom: 1%; width: 100%; height: 250px; } From 0250080bc6831b804983b121e49ec2606dc3d146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Mon, 3 Jul 2023 13:47:19 +0900 Subject: [PATCH 09/28] =?UTF-8?q?=E5=87=BA=E5=8A=9B=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E7=84=A1=E3=81=97=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/.env.example | 1 - ecs/jskult-batch-monthly/src/aws/s3.py | 29 ++- .../src/batch/common/batch_context.py | 9 + .../src/batch/output_arisj_file_process.py | 168 ++++++------------ .../src/jobctrl_monthly.py | 33 ++-- .../src/system_var/environment.py | 1 - .../calendar/jskult_arisj_output_day_list.txt | 106 +---------- 7 files changed, 120 insertions(+), 227 deletions(-) diff --git a/ecs/jskult-batch-monthly/.env.example b/ecs/jskult-batch-monthly/.env.example index 6bda1a69..d1f67281 100644 --- a/ecs/jskult-batch-monthly/.env.example +++ b/ecs/jskult-batch-monthly/.env.example @@ -7,7 +7,6 @@ DB_SCHEMA=src05 ARISJ_DATA_BUCKET=mbj-newdwh2021-staging-jskult-arisj JSKULT_BACKUP_BUCKET=mbj-newdwh2021-staging-backup-jskult JSKULT_CONFIG_BUCKET=mbj-newdwh2021-staging-config -ULTMARC_BACKUP_FOLDER=************ LOG_LEVEL=INFO ARISJ_DATA_FOLDER=DATA diff --git a/ecs/jskult-batch-monthly/src/aws/s3.py b/ecs/jskult-batch-monthly/src/aws/s3.py index ed337407..8804bba9 100644 --- a/ecs/jskult-batch-monthly/src/aws/s3.py +++ b/ecs/jskult-batch-monthly/src/aws/s3.py @@ -65,9 +65,34 @@ class ConfigBucket(S3Bucket): return temporary_file_path +class ArisjBucket(S3Bucket): + _bucket_name = environment.ARISJ_DATA_BUCKET + _folder = environment.ARISJ_BACKUP_FOLDER + + def list_dat_file(self): + return self._s3_client.list_objects(self._bucket_name, self._folder) + + def s3_arisj_csv_upload(self, arisj_create_csv: str, csv_file_path: str): + # s3にCSVファイルをUPする + Bucket = environment.ARISJ_DATA_BUCKET + folder = environment.ARISJ_DATA_FOLDER + csv_file_name = f'{folder}/{arisj_create_csv}' + s3_client = S3Client() + s3_client.upload_file(csv_file_path, Bucket, csv_file_name) + return + + def backup_dat_file(self, dat_file_key: str, datetime_key: str): + # バックアップバケットにコピー + arisj_backup_bucket = ArisjBackupBucket() + folder = environment.ARISJ_DATA_FOLDER + dat_file_key = f'{folder}/{dat_file_key}' + backup_key = f'{arisj_backup_bucket._folder}/{datetime_key}/{dat_file_key.replace(f"{self._folder}/", "")}' + self._s3_client.copy(self._bucket_name, dat_file_key, arisj_backup_bucket._bucket_name, backup_key) + + class JskUltBackupBucket(S3Bucket): _bucket_name = environment.JSKULT_BACKUP_BUCKET -class UltmarcBackupBucket(JskUltBackupBucket): - _folder = environment.ULTMARC_BACKUP_FOLDER +class ArisjBackupBucket(JskUltBackupBucket): + _folder = environment.ARISJ_BACKUP_FOLDER diff --git a/ecs/jskult-batch-monthly/src/batch/common/batch_context.py b/ecs/jskult-batch-monthly/src/batch/common/batch_context.py index 6a05a423..8c8c12fb 100644 --- a/ecs/jskult-batch-monthly/src/batch/common/batch_context.py +++ b/ecs/jskult-batch-monthly/src/batch/common/batch_context.py @@ -1,5 +1,6 @@ class BatchContext: __instance = None + __syor_date: str # 処理日(yyyy/mm/dd形式) __is_arisj_output_day: bool # 月次バッチ起動日フラグ def __init__(self) -> None: @@ -11,6 +12,14 @@ class BatchContext: cls.__instance = cls() return cls.__instance + @property + def syor_date(self): + return self.__syor_date + + @syor_date.setter + def syor_date(self, syor_date_str: str): + self.__syor_date = syor_date_str + @property def is_arisj_output_day(self): return self.__is_arisj_output_day diff --git a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py index 0deec661..b8645039 100644 --- a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py +++ b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py @@ -3,87 +3,88 @@ from datetime import datetime from src.db.database import Database from src.error.exceptions import BatchOperationException -from src.aws.s3 import S3Client from src.logging.get_logger import get_logger +from src.aws.s3 import ArisjBucket +from src.batch.common.batch_context import BatchContext import tempfile -import os import os.path as path -import logging import csv -logger = get_logger('実消化&アルトマーク月次バッチ') +logger = get_logger('ARIS-J連携データ出力') -create_date_format = datetime.now().strftime('%Y-%m-%d %H:%M:%S') -prg_id = 'PrgId:BI0402' create_date = datetime.now().strftime('%Y%m%d%H%M%S') -aris_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' -res_log = f'D0004{create_date}.log' -sql_err_msg = "MsgID:999999000002 Message:SQL実行エラーです。" -move_err_msg = "MsgID:BI0000000041 Message:S3バケットARISへのCSVデータ、実行ログ移動できませんでした。" +arisj_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' +sql_err_msg = "SQL実行エラーです。" def exec(): """ 実消化&アルトマーク月次バッチ """ try: + logger.info('バッチ処理を開始しました。') - start_msg = "MsgID:BI0000000001 Message:バッチ処理を開始しました。" - cnt_msg = "MsgID: Message: LogText:" + try: + db = Database.get_instance() + # DB接続 + db.connect() + except Exception as e: + logger.info('DB接続エラーです') + raise e - # 実行ログに書き込む - resLog, log_file_path = make_log_data() - resLog.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}') - logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {start_msg}') - - db = Database.get_instance() - # DB接続 - db.connect() # トランザクションの開始 db.begin() # 正常系データの反映 # 過去分は不要のため、デリート - physical_normal_delete(db) + physical_wk_inst_aris_if_delete(db) # 正常系データを取得しWKテーブルに保存する。 - normal_insert_into(db) + wk_inst_aris_if_insert_into(db) # 正常系データの件数を取得 - suc_count = normal_count(db) + suc_count = wk_inst_aris_if_count(db) # 警告系データの反映 # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 - physical_abnormal_delete(db) + physical_wk_inst_aris_if_wrn_delete(db) # 異常系データを取得しWKテーブルに保存する。 - abnormal_insert_into(db) + wk_inst_aris_if_wrn_insert_into(db) # 異常系データの件数を取得 - wrn_count = abnormal_count(db) + wrn_count = wk_inst_aris_if_wrn_count(db) # CSVファイルの作成用のSQL実行 record_csv = csv_data_select(db) # CSVファイル作成 - csv_file_path = make_csv_data(record_csv, resLog) + csv_file_path = make_csv_data(record_csv) # トランザクションの終了 db.commit() - # 実行ログファイルの追記 - # 実行ログに処理件数を書き込む。 + # ログに処理件数を出力 sum_count = suc_count + wrn_count - resLog.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') - logger.info(f'{create_date_format}[DWH][3][INFO]{prg_id} {cnt_msg}(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') + logger.info(f'(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') # CSVファイル移動処理 - s3_csv_upload_data(csv_file_path, resLog) + try: + ArisjBucket().s3_arisj_csv_upload(arisj_create_csv, csv_file_path) + except Exception as e: + logger.info('S3バケットArisjへのCSVデータ、移動できませんでした。') + raise e - # logファイル移動処理 - s3_log_upload_data(log_file_path) + # 処理後ファイルをバックアップ + try: + arisj_bucket = ArisjBucket() + batch_context = BatchContext.get_instance() + arisj_bucket.backup_dat_file(arisj_create_csv, batch_context.syor_date) + except Exception as e: + logger.info('S3バケットArisjバックアップへCSVデータ、コピーできませんでした。') + raise e + + logger.info('バッチ処理を終了しました。') - logger.info('実消化&アルトマーク月次バッチ処理: 終了') except Exception as e: - logger.info(f'{create_date_format}[DWH][5][INFO]') raise BatchOperationException(e) finally: @@ -92,7 +93,7 @@ def exec(): db.disconnect() -def physical_normal_delete(db): +def physical_wk_inst_aris_if_delete(db): # 過去分は不要のため、デリート try: # WKテーブルの過去分削除SQL @@ -102,11 +103,11 @@ def physical_normal_delete(db): db.execute(sql) return except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e -def normal_insert_into(db): +def wk_inst_aris_if_insert_into(db): # 正常系データを取得しWKテーブルに保存する。 try: # 正常系データを取得しWKテーブルに保存SQL @@ -150,11 +151,11 @@ def normal_insert_into(db): db.execute(sql) return except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e -def normal_count(db): +def wk_inst_aris_if_count(db): # 正常系データの件数を取得 try: # 正常系データの件数を取得SQL @@ -164,11 +165,11 @@ def normal_count(db): record_count = db.execute_select(sql) return record_count[0]['countNum'] except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e -def physical_abnormal_delete(db): +def physical_wk_inst_aris_if_wrn_delete(db): # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 try: # 異常系WKテーブルの過去分削除SQL @@ -179,11 +180,11 @@ def physical_abnormal_delete(db): db.execute(sql) return except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e -def abnormal_insert_into(db): +def wk_inst_aris_if_wrn_insert_into(db): # 異常系データを取得しWKテーブルに保存する。 try: # 異常系データを取得しWKテーブルに保存SQL @@ -233,11 +234,11 @@ def abnormal_insert_into(db): db.execute(sql) return except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e -def abnormal_count(db): +def wk_inst_aris_if_wrn_count(db): # 異常系データの件数を取得 try: # 異常系データの件数を取得SQL @@ -249,7 +250,7 @@ def abnormal_count(db): return record_count[0]['countNum'] except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e @@ -266,22 +267,19 @@ def csv_data_select(db): return db.execute_select(sql) except Exception as e: - logger.debug(f'{create_date_format}:{prg_id} {sql_err_msg}') + logger.debug(f'{sql_err_msg}') raise e -def make_csv_data(record_csv: list, resLog): +def make_csv_data(record_csv: list): # 一時ファイルとして保存する(CSVファイル) try: - err_end_msg = "MsgID:BI0000009998 Message:バッチ処理を異常終了しました。" - csv_err_msg = "MsgID:BI0000000040 Message:ワークデータの作成に失敗しました。" - temporary_dir = tempfile.mkdtemp() - csv_file_path = path.join(temporary_dir, aris_create_csv) + csv_file_path = path.join(temporary_dir, arisj_create_csv) head_str = ['TC_HOSPITAL', 'TJ_HOSPITAL', 'TJ_HOSPITALSHORT', 'TK_HOSPITAL', 'TC_PREFECTURE', 'TJ_PREFECTURE', 'TJ_ZIPCODE', 'TJ_CITY', 'TJ_ADDRESS', 'TJ_DEPARTMENT', - 'TJ_TELEPHONENUMBER', 'TC_HOSPITALCAT', 'TC_HOSPITALTYPE', 'TS_UPDATE', ' TD_UPDATE'] + 'TJ_TELEPHONENUMBER', 'TC_HOSPITALCAT', 'TC_HOSPITALTYPE', 'TS_UPDATE', 'TD_UPDATE'] # Shift-JIS、CRLF、価囲いありで書き込む with open(csv_file_path, mode='w', encoding='cp932') as csv_file: @@ -298,64 +296,8 @@ def make_csv_data(record_csv: list, resLog): writer.writerow(csv_data) except Exception as e: - resLog.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}') - resLog.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}') - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {csv_err_msg}') - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {err_end_msg}') + logger.info('ワークデータの作成に失敗しました。') + logger.info('バッチ処理を異常終了しました。') raise e return csv_file_path - - -def make_log_data(): - # 一時ファイルとして保存する(ログファイル) - temporary_dir = tempfile.mkdtemp() - log_file_path = path.join(temporary_dir, res_log) - - # ロガーの生成 - resLog = logging.getLogger('resLog') - # 出力レベルの設定 - resLog.setLevel(logging.INFO) - # ハンドラの生成 - resLog_handler = logging.FileHandler(log_file_path) - # ロガーにハンドラを登録 - resLog.addHandler(resLog_handler) - # フォーマッタの生成 - fmt = logging.Formatter('%(message)s') - # ハンドラにフォーマッタを登録 - resLog_handler.setFormatter(fmt) - - return resLog, log_file_path - - -def s3_csv_upload_data(csv_file_path, resLog): - # s3にCSVファイルをUPする - Bucket = os.environ['ARISJ_DATA_BUCKET'] - folder = os.environ['ARISJ_DATA_FOLDER'] - csv_file_name = f'{folder}/{aris_create_csv}' - s3_client = S3Client() - - try: - s3_client.upload_file(csv_file_path, Bucket, csv_file_name) - except Exception as e: - resLog.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') - raise e - - return - - -def s3_log_upload_data(log_file_path): - # s3にログファイルをUPする - Bucket = os.environ['ARISJ_DATA_BUCKET'] - folder = os.environ['ARISJ_DATA_FOLDER'] - log_file_name = f'{folder}/{res_log}' - s3_client = S3Client() - - try: - s3_client.upload_file(log_file_path, Bucket, log_file_name) - except Exception as e: - logger.info(f'{create_date_format}[DWH][5][INFO]{prg_id} {move_err_msg}') - raise e - - return diff --git a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py index dba5fac4..0534808d 100644 --- a/ecs/jskult-batch-monthly/src/jobctrl_monthly.py +++ b/ecs/jskult-batch-monthly/src/jobctrl_monthly.py @@ -1,6 +1,7 @@ """実消化&アルトマーク 月次バッチ処理""" from src.aws.s3 import ConfigBucket +from src.aws.s3 import ArisjBackupBucket from src.batch.batch_functions import get_batch_statuses from src.batch.common.batch_context import BatchContext from src.batch.common.calendar_file import CalendarFile @@ -9,28 +10,34 @@ from src.logging.get_logger import get_logger from src.system_var import constants from src.batch import output_arisj_file_process -logger = get_logger('月次処理コントロール') +logger = get_logger('月次処理コントロール(ARIS-J)') # バッチ共通設定を取得 batch_context = BatchContext.get_instance() +arisj_bucket = ArisjBackupBucket() def exec(): try: logger.info('月次バッチ:開始') try: - # 月次バッチ処置中フラグ、dump処理状態区分、処理日を取得 + logger.info('処理日取得') + # 月次バッチ処置中フラグ、処理日を取得 batch_processing_flag, syor_date = get_batch_statuses() except BatchOperationException as e: - logger.exception(f'日付テーブル取得(異常終了){e}') + logger.exception(f'日次ジョブ取得エラー(異常終了){e}') return constants.BATCH_EXIT_CODE_SUCCESS # 日次バッチ処理中の場合、後続の処理は行わない + logger.info('日次ジョブ処理中判定') if batch_processing_flag == constants.BATCH_ACTF_BATCH_IN_PROCESSING: - logger.error('日次バッチ処理中のため、月次バッチ処理を終了します。') + logger.error('日次ジョブ処理中エラー(異常終了)') return constants.BATCH_EXIT_CODE_SUCCESS - logger.info(f'処理日={syor_date}') + # バッチ共通設定に処理日を追加 + batch_context.syor_date = syor_date + + logger.info(f'処理日取得={syor_date}') # 稼働日かかどうかを、実消化&アルトマーク月次バッチ稼働日ファイルをダウンロードして判定 try: @@ -38,22 +45,22 @@ def exec(): arisj_output_day_calendar = CalendarFile(arisj_output_day_list_file_path) batch_context.is_arisj_output_day = arisj_output_day_calendar.compare_date(syor_date) except Exception as e: - logger.exception(f'実消化&アルトマーク月次バッチ稼働日ファイルの読み込みに失敗しました。{e}') + logger.exception(f'処理日取得エラー(異常終了){e}') return constants.BATCH_EXIT_CODE_SUCCESS # 調査目的で実消化&アルトマーク月次バッチ稼働日かどうかをログ出力 - if batch_context.is_arisj_output_day: - logger.info('本日は実消化&アルトマーク月次バッチ稼働日です。') - else: - logger.info('月次バッチは行われませんでした。') + if not batch_context.is_arisj_output_day: + logger.info('ARIS-J連携データ出力日でない為、処理終了') return constants.BATCH_EXIT_CODE_SUCCESS + logger.info('ARIS-J連携データ出力日です') + try: - logger.info('月次バッチ:起動') + logger.info('ARIS-J連携データ出力:起動') output_arisj_file_process.exec() - logger.info('月次バッチ:終了') + logger.info('ARIS-J連携データ出力:終了') except BatchOperationException as e: - logger.exception(f'月次バッチ処理エラー(異常終了){e}') + logger.exception(f'ARIS-J連携データ出力(異常終了){e}') return constants.BATCH_EXIT_CODE_SUCCESS # 正常終了を保守ユーザーに通知 diff --git a/ecs/jskult-batch-monthly/src/system_var/environment.py b/ecs/jskult-batch-monthly/src/system_var/environment.py index c98503dd..08d6cd16 100644 --- a/ecs/jskult-batch-monthly/src/system_var/environment.py +++ b/ecs/jskult-batch-monthly/src/system_var/environment.py @@ -15,7 +15,6 @@ ARISJ_DATA_FOLDER = os.environ['ARISJ_DATA_FOLDER'] ARISJ_BACKUP_FOLDER = os.environ['ARISJ_BACKUP_FOLDER'] JSKULT_CONFIG_CALENDAR_FOLDER = os.environ['JSKULT_CONFIG_CALENDAR_FOLDER'] JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_ARISJ_OUTPUT_DAY_LIST_FILE_NAME'] -ULTMARC_BACKUP_FOLDER = os.environ['ULTMARC_BACKUP_FOLDER'] # 初期値がある環境変数 LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') diff --git a/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt b/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt index 2d5f42c0..fe095c8a 100644 --- a/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt +++ b/s3/config/jskult/calendar/jskult_arisj_output_day_list.txt @@ -1,100 +1,12 @@ -2023/06/23 -2023/06/24 -2023/06/25 -2023/06/26 -2023/06/27 -2023/06/28 -2023/06/29 -2023/06/30 -2023/07/01 -2023/07/02 +2023/01/05 +2023/02/01 +2023/03/01 +2023/04/03 +2023/05/01 +2023/06/01 2023/07/03 -2023/07/04 -2023/07/05 -2023/07/06 -2023/07/07 -2023/07/08 -2023/07/09 -2023/07/10 -2023/07/11 -2023/07/12 -2023/07/13 -2023/07/14 -2023/07/15 -2023/07/16 -2023/07/17 -2023/07/18 -2023/07/19 -2023/07/20 -2023/07/21 -2023/07/22 -2023/07/23 -2023/07/24 -2023/07/25 -2023/07/26 -2023/07/27 -2023/07/28 -2023/07/29 -2023/07/30 -2023/07/31 2023/08/01 -2023/08/02 -2023/08/03 -2023/08/04 -2023/08/05 -2023/08/06 -2023/08/07 -2023/08/08 -2023/08/09 -2023/08/10 -2023/08/11 -2023/08/12 -2023/08/13 -2023/08/14 -2023/08/15 -2023/08/16 -2023/08/17 -2023/08/18 -2023/08/19 -2023/08/20 -2023/08/21 -2023/08/22 -2023/08/23 -2023/08/24 -2023/08/25 -2023/08/26 -2023/08/27 -2023/08/28 -2023/08/29 -2023/08/30 -2023/08/31 2023/09/01 -2023/09/02 -2023/09/03 -2023/09/04 -2023/09/05 -2023/09/06 -2023/09/07 -2023/09/08 -2023/09/09 -2023/09/10 -2023/09/11 -2023/09/12 -2023/09/13 -2023/09/14 -2023/09/15 -2023/09/16 -2023/09/17 -2023/09/18 -2023/09/19 -2023/09/20 -2023/09/21 -2023/09/22 -2023/09/23 -2023/09/24 -2023/09/25 -2023/09/26 -2023/09/27 -2023/09/28 -2023/09/29 -2023/09/30 +2023/10/02 +2023/11/01 +2023/12/01 \ No newline at end of file From cca854be178336cc13422e4562ec3f38db130d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Tue, 4 Jul 2023 15:24:05 +0900 Subject: [PATCH 10/28] =?UTF-8?q?=E4=BB=AE=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-daily/.env.example | 3 + ecs/jskult-batch-daily/src/aws/s3.py | 26 ++ .../batch/ultmarc/export_vjsk_csv_process.py | 270 ++++++++++++++++++ .../src/batch/ultmarc/ultmarc_process.py | 13 +- ecs/jskult-batch-daily/src/jobctrl_daily.py | 8 +- .../src/system_var/environment.py | 3 + 6 files changed, 318 insertions(+), 5 deletions(-) create mode 100644 ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py diff --git a/ecs/jskult-batch-daily/.env.example b/ecs/jskult-batch-daily/.env.example index 95aef7fe..4a0eefbe 100644 --- a/ecs/jskult-batch-daily/.env.example +++ b/ecs/jskult-batch-daily/.env.example @@ -11,3 +11,6 @@ ULTMARC_BACKUP_FOLDER=ultmarc JSKULT_CONFIG_BUCKET=********************** JSKULT_CONFIG_CALENDAR_FOLDER=jskult/calendar JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME=jskult_holiday_list.txt +VJSK_BACKUP_FOLDER=vjsk +VJSK_DATA_SEND_FOLDER=send +VJSK_DATA_BUCKET=************* \ No newline at end of file diff --git a/ecs/jskult-batch-daily/src/aws/s3.py b/ecs/jskult-batch-daily/src/aws/s3.py index 68ed0a7c..fab7e222 100644 --- a/ecs/jskult-batch-daily/src/aws/s3.py +++ b/ecs/jskult-batch-daily/src/aws/s3.py @@ -76,6 +76,28 @@ class UltmarcBucket(S3Bucket): self._s3_client.delete_file(self._bucket_name, dat_file_key) +class VjskBucket(S3Bucket): + _bucket_name = environment.VJSK_DATA_BUCKET + _folder = environment.VJSK_DATA_SEND_FOLDER + + def list_dat_file(self): + return self._s3_client.list_objects(self._bucket_name, self._folder) + + def upload_dat_file(self, vjsk_create_csv: str, csv_file_path: str): + # S3バケットにファイルを移動 + csv_file_name = f'{self._folder}/{vjsk_create_csv}' + s3_client = S3Client() + s3_client.upload_file(csv_file_path, self._bucket_name, csv_file_name) + return + + def backup_dat_file(self, dat_file_key: str, datetime_key: str): + # バックアップバケットにコピー + vjsk_backup_bucket = VjskBackupBucket() + dat_key = f'{self._folder}/{dat_file_key}' + backup_key = f'{vjsk_backup_bucket._folder}/{self._folder}/{datetime_key}/{dat_file_key.replace(f"{self._folder}/", "")}' + self._s3_client.copy(self._bucket_name, dat_key, vjsk_backup_bucket._bucket_name, backup_key) + + class ConfigBucket(S3Bucket): _bucket_name = environment.JSKULT_CONFIG_BUCKET @@ -96,3 +118,7 @@ class JskUltBackupBucket(S3Bucket): class UltmarcBackupBucket(JskUltBackupBucket): _folder = environment.ULTMARC_BACKUP_FOLDER + + +class VjskBackupBucket(JskUltBackupBucket): + _folder = environment.VJSK_BACKUP_FOLDER diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py new file mode 100644 index 00000000..27243e4a --- /dev/null +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py @@ -0,0 +1,270 @@ +"""アルトマークデータ処理""" + +from src.aws.s3 import UltmarcBucket, VjskBucket +from src.batch.common.batch_context import BatchContext + +from src.db.database import Database +from src.logging.get_logger import get_logger +import tempfile +import os.path as path +import csv + +logger = get_logger('V実用消化施設データ作成処理') +ultmarc_bucket = UltmarcBucket() +batch_context = BatchContext.get_instance() + +sql_err_msg = "SQL実行エラーです。" +vjsk_csv_file_name = 'ComInst.csv' + + +def exec(): + db = Database.get_instance() + try: + logger.info('バッチ処理を開始しました。') + + try: + # DB接続 + db.connect() + # ファイル単位でトランザクションを行う + db.begin() + except Exception as e: + logger.info('DB接続エラーです。') + raise e + + # CSVファイルの作成用のSQL実行(施設) + record_inst_csv = csv_data_inst_select(db) + # CSVファイルの作成用のSQL実行(薬局) + record_pharm_csv = csv_data_pharm_select(db) + # CSVファイル作成 + csv_file_path = make_csv_data(record_inst_csv, record_pharm_csv) + + vjsk_bucket = VjskBucket() + try: + # s3へデータ移動 + vjsk_bucket.upload_dat_file(vjsk_csv_file_name, csv_file_path) + except Exception as e: + logger.info('S3バケットDWHへCSVデータを作成できませんでした。') + raise e + + try: + # 処理後ファイルをバックアップ + batch_context = BatchContext.get_instance() + vjsk_bucket.backup_dat_file(vjsk_csv_file_name, batch_context.syor_date) + except Exception as e: + logger.info('バックアップバケットへCSVデータをコピーできませんでした。') + raise e + + csv_count = len(record_inst_csv) + len(record_pharm_csv) + logger.info(f'CSV出力件数: {csv_count}。') + logger.info('バッチ処理を正常に終了しました。') + except Exception as e: + raise e + finally: + # 終了時に必ずコミットする + db.commit() + db.disconnect() + return + + +def csv_data_inst_select(db): + # CSVファイルの作成用のSQL実行(施設) + try: + # 施設テーブル検索SQL + sql = """\ + SELECT dcf_dsf_inst_cd, + inst_div_cd, + addr_unknown_reason_cd, + form_inst_name_kana, + inst_name_kana, + form_inst_name_kanji, + inst_name_kanji, + rltd_univ_prnt_cd, + bed_num, + close_flg, + estab_sche_flg, + close_start_ym, + estab_sche_ym, + ward_abolish_flg, + inst_repre_cd, + inst_repre_kana, + inst_repre, + phone_number_non_flg, + unconf_flg, + inst_phone_number, + inst_addr_kana, + inst_addr, + postal_number, + village_cd, + prefc_cd, + city_cd, + addr_display_number, + addr_cnt_kana, + addr_cnt, + manage_cd, + delete_sche_reason_cd, + hp_assrt_cd, + dup_opp_cd, + insp_item_micrb, + insp_item_serum, + insp_item_blood, + insp_item_patho, + insp_item_paras, + insp_item_biochem, + insp_item_ri, + re_exam_cd, + prmit_bed_num_other, + prmit_bed_num_mental, + prmit_bed_num_tuber, + prmit_bed_num_infection, + prmit_bed_num_sum, + prmit_bed_num_gen, + prmit_bed_num_rcup, + prmit_bed_maint_ymd, + inst_pharm_div, + abolish_ymd, + delete_flg, + filler_1, + filler_2, + filler_3, + filler_4, + filler_5, + regist_date, + create_user, + update_date, + update_user, + sys_regist_date, + regist_prgm_id, + sys_update_date, + update_prgm_id + FROM src05.com_inst ORDER BY dcf_dsf_inst_cd + """ + return db.execute_select(sql) + except Exception as e: + logger.debug(f'{sql_err_msg}') + raise e + + +def csv_data_pharm_select(db): + # CSVファイルの作成用のSQL実行(薬局) + try: + # 薬局テーブル検索SQL + sql = """\ + SELECT dcf_dsf_inst_cd, + inst_div_cd, + addr_unknown_reason_cd, + form_inst_name_kana, + inst_name_kana, + form_inst_name_kanji, + inst_name_kanji, + '', + '', + close_flg, + estab_sche_flg, + close_start_ym, + estab_sche_ym, + '', + '', + inst_repre_kana, + inst_repre, + phone_number_non_flg, + unconf_flg, + inst_phone_number, + inst_addr_kana, + inst_addr, + postal_number, + village_cd, + prefc_cd, + city_cd, + addr_display_number, + addr_cnt_kana, + addr_cnt, + manage_cd, + delete_sche_reason_cd, + '', + dup_opp_cd, + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + inst_pharm_div, + abolish_ymd, + delete_flg, + filler_1, + filler_2, + filler_3, + filler_4, + filler_5, + regist_date, + create_user, + update_date, + update_user, + sys_regist_date, + regist_prgm_id, + sys_update_date, + update_prgm_id + FROM src05.com_pharm ORDER BY dcf_dsf_inst_cd + """ + return db.execute_select(sql) + except Exception as e: + logger.debug(f'{sql_err_msg}') + raise e + + +def make_csv_data(record_inst_csv: list, record_pharm_cs: list): + # 一時ファイルとして保存する(CSVファイル) + try: + + temporary_dir = tempfile.mkdtemp() + csv_file_path = path.join(temporary_dir, vjsk_csv_file_name) + + head_str = ['DCF_DSF_INST_CD', 'INST_DIV_CD', 'ADDR_UNKNOWN_REASON_CD', 'FORM_INST_NAME_KANA', 'INST_NAME_KANA', + 'FORM_INST_NAME_KANJI', 'INST_NAME_KANJI', 'RLTD_UNIV_PRNT_CD', 'BED_NUM', 'CLOSE_FLG', 'ESTAB_SCHE_FLG', + 'CLOSE_START_YM', 'ESTAB_SCHE_YM', 'WARD_ABOLISH_FLG', 'INST_REPRE_CD', 'INST_REPRE_KANA', 'INST_REPRE', + 'PHONE_NUMBER_NON_FLG', 'UNCONF_FLG', 'INST_PHONE_NUMBER', 'INST_ADDR_KANA', 'INST_ADDR', 'POSTAL_NUMBER', + 'VILLAGE_CD', 'PREFC_CD', 'CITY_CD', 'ADDR_DISPLAY_NUMBER', 'ADDR_CNT_KANA', 'ADDR_CNT', 'MANAGE_CD', + 'DELETE_SCHE_REASON_CD', 'HP_ASSRT_CD', 'DUP_OPP_CD', 'INSP_ITEM_MICRB', 'INSP_ITEM_SERUM', 'INSP_ITEM_BLOOD', + 'INSP_ITEM_PATHO', 'INSP_ITEM_PARAS', 'INSP_ITEM_BIOCHEM', 'INSP_ITEM_RI', 'RE_EXAM_CD', 'PRMIT_BED_NUM_OTHER', + 'PRMIT_BED_NUM_MENTAL', 'PRMIT_BED_NUM_TUBER', 'PRMIT_BED_NUM_INFECTION', 'PRMIT_BED_NUM_SUM', 'PRMIT_BED_NUM_GEN', + 'PRMIT_BED_NUM_RCUP', 'PRMIT_BED_MAINT_YMD', 'INST_PHARM_DIV', 'ABOLISH_YMD', 'DELETE_FLG', 'FILLER_1', 'FILLER_2', + 'FILLER_3', 'FILLER_4', 'FILLER_5', 'REGIST_DATE', 'CREATE_USER', 'UPDATE_DATE', 'UPDATE_USER', 'SYS_REGIST_DATE', + 'REGIST_PRGM_ID', 'SYS_UPDATE_DATE', 'UPDATE_PRGM_ID'] + + # Shift-JIS、CRLF、価囲いありで書き込む + with open(csv_file_path, mode='w', encoding='cp932') as csv_file: + writer = csv.writer(csv_file, delimiter=',', lineterminator='\n', + quotechar='"', doublequote=True, quoting=csv.QUOTE_ALL, + strict=True + ) + # ヘッダ行書き込み + writer.writerow(head_str) + + # データ部分書き込み(施設) + for record_inst_data in record_inst_csv: + record_inst_value = list(record_inst_data.values()) + csv_data = ['' if n is None else n for n in record_inst_value] + writer.writerow(csv_data) + + # データ部分書き込み(薬局) + for record_pharm_data in record_pharm_cs: + record_pharm_value = list(record_pharm_data.values()) + csv_data = ['' if n is None else n for n in record_pharm_value] + writer.writerow(csv_data) + + except Exception as e: + logger.info('ワークデータの作成に失敗しました。') + logger.info('バッチ処理を異常終了しました。') + raise e + + return csv_file_path diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py index b511a9c8..e0e6ba22 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py @@ -5,6 +5,7 @@ from datetime import datetime from src.aws.s3 import UltmarcBucket from src.batch.common.batch_context import BatchContext from src.batch.ultmarc.datfile import DatFile +from src.batch.ultmarc import export_vjsk_csv_process from src.batch.ultmarc.utmp_tables.ultmarc_table_mapper_factory import \ UltmarcTableMapperFactory from src.db.database import Database @@ -61,11 +62,19 @@ def exec_import(): def exec_export(): - """V実消化用施設・薬局薬店データ作成処理""" + """V実消化用施設データ作成処理""" if not batch_context.is_ultmarc_imported: - logger.info('アルトマーク取込が行われていないため、V実消化用施設・薬局薬店データ作成処理をスキップします。') + logger.info('アルトマーク取込が行われていないため、V実消化用施設データ作成処理をスキップします。') return + try: + logger.info('V実用消化施設データ作成処理: 開始') + export_vjsk_csv_process.exec() + logger.info('V実用消化施設データ作成処理: 終了') + except Exception as e: + raise BatchOperationException(e) + return + def _import_to_ultmarc_table(dat_file: DatFile): db = Database.get_instance() diff --git a/ecs/jskult-batch-daily/src/jobctrl_daily.py b/ecs/jskult-batch-daily/src/jobctrl_daily.py index a98c0d16..d77216ff 100644 --- a/ecs/jskult-batch-daily/src/jobctrl_daily.py +++ b/ecs/jskult-batch-daily/src/jobctrl_daily.py @@ -75,11 +75,13 @@ def exec(): logger.debug(f'{"アルトマーク取込が行われました。" if batch_context.is_ultmarc_imported else "アルトマーク取込が行われませんでした。"}') try: - logger.info('V実消化用施設・薬局薬店データ作成処理:起動') + logger.info('V実消化用施設データ作成処理:起動') +# ***********************実行させるためにtrueにしておく(後で消す)*********************** + batch_context.is_ultmarc_imported = True ultmarc_process.exec_export() - logger.info('V実消化用施設・薬局薬店データ作成処理:終了') + logger.info('V実消化用施設データ作成処理:終了') except BatchOperationException as e: - logger.exception(f'V実消化用施設・薬局薬店データ作成処理エラー(異常終了){e}') + logger.exception(f'V実消化用施設データ作成処理エラー(異常終了){e}') return constants.BATCH_EXIT_CODE_SUCCESS logger.info('日次処理(V実消化)') diff --git a/ecs/jskult-batch-daily/src/system_var/environment.py b/ecs/jskult-batch-daily/src/system_var/environment.py index b1730224..4144319f 100644 --- a/ecs/jskult-batch-daily/src/system_var/environment.py +++ b/ecs/jskult-batch-daily/src/system_var/environment.py @@ -15,6 +15,9 @@ ULTMARC_BACKUP_FOLDER = os.environ['ULTMARC_BACKUP_FOLDER'] JSKULT_CONFIG_BUCKET = os.environ['JSKULT_CONFIG_BUCKET'] JSKULT_CONFIG_CALENDAR_FOLDER = os.environ['JSKULT_CONFIG_CALENDAR_FOLDER'] JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME'] +VJSK_BACKUP_FOLDER = os.environ['VJSK_BACKUP_FOLDER'] +VJSK_DATA_SEND_FOLDER = os.environ['VJSK_DATA_SEND_FOLDER'] +VJSK_DATA_BUCKET = os.environ['VJSK_DATA_BUCKET'] # 初期値がある環境変数 LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') From 92c14d2fa0f2fb499dcdd91b40e0c4d061a549a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Tue, 4 Jul 2023 15:25:21 +0900 Subject: [PATCH 11/28] =?UTF-8?q?=E4=BB=AE=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-daily/src/jobctrl_daily.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ecs/jskult-batch-daily/src/jobctrl_daily.py b/ecs/jskult-batch-daily/src/jobctrl_daily.py index d77216ff..45e297e9 100644 --- a/ecs/jskult-batch-daily/src/jobctrl_daily.py +++ b/ecs/jskult-batch-daily/src/jobctrl_daily.py @@ -76,8 +76,6 @@ def exec(): try: logger.info('V実消化用施設データ作成処理:起動') -# ***********************実行させるためにtrueにしておく(後で消す)*********************** - batch_context.is_ultmarc_imported = True ultmarc_process.exec_export() logger.info('V実消化用施設データ作成処理:終了') except BatchOperationException as e: From b9a2a0c2f7f2545dc7ad3683ce35644e06437615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 09:05:50 +0900 Subject: [PATCH 12/28] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BA=8B=E9=A0=85?= =?UTF-8?q?=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/batch/output_arisj_file_process.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py index b8645039..197db381 100644 --- a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py +++ b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py @@ -283,12 +283,12 @@ def make_csv_data(record_csv: list): # Shift-JIS、CRLF、価囲いありで書き込む with open(csv_file_path, mode='w', encoding='cp932') as csv_file: + # ヘッダ行書き込み + csv_file.write(f"{','.join(head_str)}\n") writer = csv.writer(csv_file, delimiter=',', lineterminator='\n', quotechar='"', doublequote=True, quoting=csv.QUOTE_ALL, strict=True ) - # ヘッダ行書き込み - writer.writerow(head_str) # データ部分書き込み for record_data in record_csv: record_value = list(record_data.values()) From f5de058284bdaea1d842435f217500ee5a9e9b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 09:45:58 +0900 Subject: [PATCH 13/28] =?UTF-8?q?=E4=BB=AE=E5=AE=8C=E6=88=90=EF=BC=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/batch/ultmarc/export_vjsk_csv_process.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py index 27243e4a..a1b2ff23 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py @@ -243,12 +243,12 @@ def make_csv_data(record_inst_csv: list, record_pharm_cs: list): # Shift-JIS、CRLF、価囲いありで書き込む with open(csv_file_path, mode='w', encoding='cp932') as csv_file: + # ヘッダ行書き込み + csv_file.write(f"{','.join(head_str)}\n") writer = csv.writer(csv_file, delimiter=',', lineterminator='\n', quotechar='"', doublequote=True, quoting=csv.QUOTE_ALL, strict=True ) - # ヘッダ行書き込み - writer.writerow(head_str) # データ部分書き込み(施設) for record_inst_data in record_inst_csv: From 0c2b3d22f4cf7e2542c137989e66231c7a7bfd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 10:45:31 +0900 Subject: [PATCH 14/28] =?UTF-8?q?pip=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/Pipfile.lock | 235 ++++++-------------------- 1 file changed, 55 insertions(+), 180 deletions(-) diff --git a/ecs/jskult-batch-monthly/Pipfile.lock b/ecs/jskult-batch-monthly/Pipfile.lock index 3e58b727..10d05022 100644 --- a/ecs/jskult-batch-monthly/Pipfile.lock +++ b/ecs/jskult-batch-monthly/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0b1dbc40a5069476aa66f172175ae24ffae385c335ff8e4794c1b25a111b9e43" + "sha256": "a2be870e254760b62220c10400b05fa66d24b2cc1bcd6f21044735e320a62e53" }, "pipfile-spec": 6, "requires": { @@ -18,19 +18,19 @@ "default": { "boto3": { "hashes": [ - "sha256:7694df61bd6d253d6d9db34adbcd218b8efbe7f894a4a51611f7e0587ae33218", - "sha256:fe49f91e057b241b23a58c74c2f22654216788052ce95b73439fdb18bfd0e155" + "sha256:908f9c277325d68963dfcfce963a05336f0eb19505fc239c0ab9d01f4cba0296", + "sha256:e1e535e9fb23977252f13652ed2fa9b4f2d59a53b04a5f2fad3ee415b6a3b2b0" ], "index": "pypi", - "version": "==1.26.159" + "version": "==1.27.0" }, "botocore": { "hashes": [ - "sha256:86fe4641fd32dc6a5be4a289e00dc180448fc7bc37abac21bd624656985eef62", - "sha256:da1c61757d466b82cc89f379a50662064bcb0beb67cc6efa1fbfc9a341bd08b0" + "sha256:b9cb5b78a289f0615a48d85066f01869029aa41b95993f2c0c55003df037c23f", + "sha256:cac1333f41ec98e6f75bbba3f2c74b9e76aa3847469ecea6e7773a0af0049bee" ], "markers": "python_version >= '3.7'", - "version": "==1.29.159" + "version": "==1.30.0" }, "greenlet": { "hashes": [ @@ -107,11 +107,11 @@ }, "pymysql": { "hashes": [ - "sha256:766b72e4370aba94e6266a4dbd62c51fbc6a894c38de25a41a8a01f0461a2387", - "sha256:aade29b861e81a3c68a9e90d43f3db257940c0208983a0128b82f1a4cef639aa" + "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96", + "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7" ], "index": "pypi", - "version": "==1.1.0rc2" + "version": "==1.1.0" }, "python-dateutil": { "hashes": [ @@ -139,50 +139,50 @@ }, "sqlalchemy": { "hashes": [ - "sha256:0db6734cb5644c55d0262a813b764c6e2cda1e66e939a488b3d6298cdc7344c2", - "sha256:0e4645b260cfe375a0603aa117f0a47680864cf37833129da870919e88b08d8f", - "sha256:131f0c894c6572cb1bdcf97c92d999d3128c4ff1ca13061296057072f61afe13", - "sha256:1e2caba78e7d1f5003e88817b7a1754d4e58f4a8f956dc423bf8e304c568ab09", - "sha256:2de1477af7f48c633b8ecb88245aedd811dca88e88aee9e9d787b388abe74c44", - "sha256:2f3b6c31b915159b96b68372212fa77f69230b0a32acab40cf539d2823954f5a", - "sha256:3ef876615ff4b53e2033022195830ec4941a6e21068611f8d77de60203b90a98", - "sha256:43e69c8c1cea0188b7094e22fb93ae1a1890aac748628b7e925024a206f75368", - "sha256:53081c6fce0d49bb36d05f12dc87e008c9b0df58a163b792c5fc4ac638925f98", - "sha256:5a934eff1a2882137be3384826f997db8441d43b61fda3094923e69fffe474be", - "sha256:5e8522b49e0e640287308b68f71cc338446bbe1c226c8f81743baa91b0246e92", - "sha256:61f2035dea56ff1a429077e481496f813378beb02b823d2e3e7eb05bc1a7a8ca", - "sha256:63ea36c08792a7a8a08958bc806ecff6b491386feeaf14607c3d9d2d9325e67f", - "sha256:6e85e315725807c127ad8ba3d628fdb861cf9ebfb0e10c39a97c01e257cdd71b", - "sha256:7641f6ed2682de84d77c4894cf2e43700f3cf7a729361d7f9cac98febf3d8614", - "sha256:7be04dbe3470fe8dd332fdb48c979887c381ef6c635eddf2dec43d2766111be4", - "sha256:81d867c1be5abd49f7e547c108391f371a9d980ba7ec34666c50d683f782b754", - "sha256:8544c6e62eacb77d5106e2055ef10f2407fc0dbd547e879f8745b2032eefd2bc", - "sha256:8d3cbdb2f07fb0e4b897dc1df39166735e194fb946f28f26f4c9f9801c8b24f7", - "sha256:8d6ef848e5afcd1bda3e9a843751f845c0ca888b61e669237680e913d84ec206", - "sha256:8e2569dac4e3cb85365b91ab569d06a221e0e17e65ce59949d00c3958946282b", - "sha256:90d320fde566b864adbc19abb40ecb80f4e25d6f084639969bb972d5cca16858", - "sha256:91eb8f89fcce8f709f8a4d65d265bc48a80264ee14c7c9e955f3222f19b4b39c", - "sha256:a08a791c75d6154d46914d1e23bd81d9455f2950ec1de81f2723848c593d2c8b", - "sha256:a2e9f50a906d0b81292576a9fb458f8cace904c81a67088f4a2ca9ff2856f55d", - "sha256:a5a2856e12cf5f54301ddf043bcbf0552561d61555e1bcf348b63f42b8e1eec2", - "sha256:b2801f85c5c0293aa710f8aa5262c707a83c1c203962ae5a22b4d9095e71aa9d", - "sha256:b72f4e4def50414164a1d899f2ce4e782a029fad0ed5585981d1611e8ae29a74", - "sha256:bdaf89dd82f4a0e1b8b5ffc9cdc0c9551be6175f7eee5af6a838e92ba2e57100", - "sha256:c5e333b81fe10d14efebd4e9429b7bb865ed9463ca8bef07a7136dfa1fd4a37b", - "sha256:ce1fc3f64fd42d5f763d6b83651471f32920338a1ba107a3186211474861af57", - "sha256:d0c96592f54edd571e00ba6b1ed5df8263328ca1da9e78088c0ebc93c2e6562c", - "sha256:dc97238fa44be86971270943a0c21c19ce18b8d1596919048e57912e8abc02cc", - "sha256:e19546924f0cf2ec930d1faf318b7365e5827276410a513340f31a2b423e96a4", - "sha256:f2938edc512dd1fa48653e14c1655ab46144d4450f0e6b33da7acd8ba77fbfd7", - "sha256:f387b496a4c9474d8580195bb2660264a3f295a04d3a9d00f4fa15e9e597427e", - "sha256:f409f35a0330ab0cb18ece736b86d8b8233c64f4461fcb10993f67afc0ac7e5a", - "sha256:f662cf69484c59f8a3435902c40dfc34d86050bdb15e23d437074ce9f153306b", - "sha256:fbcc51fdbc89fafe4f4fe66f59372a8be88ded04de34ef438ab04f980beb12d4", - "sha256:fc1dae11bd5167f9eb53b3ccad24a79813004612141e76de21cf4c028dc30b34", - "sha256:ff6496ad5e9dc8baeb93a151cc2f599d01e5f8928a2aaf0b09a06428fdbaf553" + "sha256:04383f1e3452f6739084184e427e9d5cb4e68ddc765d52157bf5ef30d5eca14f", + "sha256:125f9f7e62ddf8b590c069729080ffe18b68a20d9882eb0947f72e06274601d7", + "sha256:1822620c89779b85f7c23d535c8e04b79c517739ae07aaed48c81e591ed5498e", + "sha256:21583808d37f126a647652c90332ac1d3a102edf3c94bcc3319edcc0ea2300cc", + "sha256:218fb20c01e95004f50a3062bf4c447dcb360cab8274232f31947e254f118298", + "sha256:2269b1f9b8be47e52b70936069a25a3771eff53367aa5cc59bb94f28a6412e13", + "sha256:234678ed6576531b8e4be255b980f20368bf07241a2e67b84e6b0fe679edb9c4", + "sha256:28da17059ecde53e2d10ba813d38db942b9f6344360b2958b25872d5cb729d35", + "sha256:2c6ff5767d954f6091113fedcaaf49cdec2197ae4c5301fe83d5ae4393c82f33", + "sha256:36a87e26fe8fa8c466fae461a8fcb780d0a1cbf8206900759fc6fe874475a3ce", + "sha256:394ac3adf3676fad76d4b8fcecddf747627f17f0738dc94bac15f303d05b03d4", + "sha256:40a3dc52b2b16f08b5c16b9ee7646329e4b3411e9280e5e8d57b19eaa51cbef4", + "sha256:48111d56afea5699bab72c38ec95561796b81befff9e13d1dd5ce251ab25f51d", + "sha256:48b40dc2895841ea89d89df9eb3ac69e2950a659db20a369acf4259f68e6dc1f", + "sha256:513411d73503a6fc5804f01fae3b3d44f267c1b3a06cfeac02e9286a7330e857", + "sha256:51736cfb607cf4e8fafb693906f9bc4e5ee55be0b096d44bd7f20cd8489b8571", + "sha256:5f40e3a7d0a464f1c8593f2991e5520b2f5b26da24e88000bbd4423f86103d4f", + "sha256:6150560fcffc6aee5ec9a97419ac768c7a9f56baf7a7eb59cb4b1b6a4d463ad9", + "sha256:724355973297bbe547f3eb98b46ade65a67a3d5a6303f17ab59a2dc6fb938943", + "sha256:74ddcafb6488f382854a7da851c404c394be3729bb3d91b02ad86c5458140eff", + "sha256:7830e01b02d440c27f2a5be68296e74ccb55e6a5b5962ffafd360b98930b2e5e", + "sha256:7f31d4e7ca1dd8ca5a27fd5eaa0f9e2732fe769ff7dd35bf7bba179597e4df07", + "sha256:8741d3d401383e54b2aada37cbd10f55c5d444b360eae3a82f74a2be568a7710", + "sha256:910d45bf3673f0e4ef13858674bd23cfdafdc8368b45b948bf511797dbbb401d", + "sha256:aa995b21f853864996e4056d9fde479bcecf8b7bff4beb3555eebbbba815f35d", + "sha256:af7e2ba75bf84b64adb331918188dda634689a2abb151bc1a583e488363fd2f8", + "sha256:b0eaf82cc844f6b46defe15ad243ea00d1e39ed3859df61130c263dc7204da6e", + "sha256:b114a16bc03dfe20b625062e456affd7b9938286e05a3f904a025b9aacc29dd4", + "sha256:b47be4c6281a86670ea5cfbbbe6c3a65366a8742f5bc8b986f790533c60b5ddb", + "sha256:ba03518e64d86f000dc24ab3d3a1aa876bcbaa8aa15662ac2df5e81537fa3394", + "sha256:cc9c2630c423ac4973492821b2969f5fe99d9736f3025da670095668fbfcd4d5", + "sha256:cf07ff9920cb3ca9d73525dfd4f36ddf9e1a83734ea8b4f724edfd9a2c6e82d9", + "sha256:cf175d26f6787cce30fe6c04303ca0aeeb0ad40eeb22e3391f24b32ec432a1e1", + "sha256:d0aeb3afaa19f187a70fa592fbe3c20a056b57662691fd3abf60f016aa5c1848", + "sha256:e186e9e95fb5d993b075c33fe4f38a22105f7ce11cecb5c17b5618181e356702", + "sha256:e2d5c3596254cf1a96474b98e7ce20041c74c008b0f101c1cb4f8261cb77c6d3", + "sha256:e3189432db2f5753b4fde1aa90a61c69976f4e7e31d1cf4611bfe3514ed07478", + "sha256:e3a6b2788f193756076061626679c5c5a6d600ddf8324f986bc72004c3e9d92e", + "sha256:ead58cae2a089eee1b0569060999cb5f2b2462109498a0937cc230a7556945a1", + "sha256:f2f389f77c68dc22cb51f026619291c4a38aeb4b7ecb5f998fd145b2d81ca513", + "sha256:f593170fc09c5abb1205a738290b39532f7380094dc151805009a07ae0e85330" ], "index": "pypi", - "version": "==2.0.16" + "version": "==2.0.17" }, "tenacity": { "hashes": [ @@ -194,11 +194,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:16224afa8cc2b3679dd9e9a1efe719dd2e20a03f0cc2e4cc4c97870ae9622532", - "sha256:3c2c2cd887648efa0ea8f8ba4260a1213058e8e4a25a6a6f4e084740b2c858e2" + "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", + "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" ], "markers": "python_version >= '3.7'", - "version": "==4.7.0rc1" + "version": "==4.7.1" }, "urllib3": { "hashes": [ @@ -218,91 +218,6 @@ "index": "pypi", "version": "==2.0.2" }, - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "sys_platform == 'win32'", - "version": "==0.4.6" - }, - "coverage": { - "extras": [ - "toml" - ], - "hashes": [ - "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f", - "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2", - "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a", - "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a", - "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01", - "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6", - "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7", - "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f", - "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02", - "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c", - "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063", - "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a", - "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5", - "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959", - "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97", - "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6", - "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f", - "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9", - "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5", - "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f", - "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562", - "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe", - "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9", - "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f", - "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb", - "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb", - "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1", - "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb", - "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250", - "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e", - "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511", - "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5", - "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59", - "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2", - "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d", - "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3", - "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4", - "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de", - "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9", - "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833", - "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0", - "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9", - "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d", - "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050", - "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d", - "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6", - "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353", - "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb", - "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e", - "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8", - "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495", - "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2", - "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd", - "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27", - "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1", - "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818", - "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4", - "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e", - "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850", - "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3" - ], - "markers": "python_version >= '3.7'", - "version": "==7.2.7" - }, - "exceptiongroup": { - "hashes": [ - "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e", - "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785" - ], - "markers": "python_version < '3.11'", - "version": "==1.1.1" - }, "flake8": { "hashes": [ "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7", @@ -311,14 +226,6 @@ "index": "pypi", "version": "==6.0.0" }, - "iniconfig": { - "hashes": [ - "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", - "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, "mccabe": { "hashes": [ "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", @@ -327,22 +234,6 @@ "markers": "python_version >= '3.6'", "version": "==0.7.0" }, - "packaging": { - "hashes": [ - "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", - "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" - ], - "markers": "python_version >= '3.7'", - "version": "==23.1" - }, - "pluggy": { - "hashes": [ - "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", - "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" - ], - "markers": "python_version >= '3.7'", - "version": "==1.2.0" - }, "pycodestyle": { "hashes": [ "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053", @@ -359,22 +250,6 @@ "markers": "python_version >= '3.6'", "version": "==3.0.1" }, - "pytest": { - "hashes": [ - "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295", - "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b" - ], - "index": "pypi", - "version": "==7.3.2" - }, - "pytest-cov": { - "hashes": [ - "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", - "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" - ], - "index": "pypi", - "version": "==4.1.0" - }, "tomli": { "hashes": [ "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", From 3fa372b5da8c56adc2a7f785374aad8c6f63d42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 11:24:53 +0900 Subject: [PATCH 15/28] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/batch/output_arisj_file_process.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py index 197db381..9d7d5587 100644 --- a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py +++ b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py @@ -281,10 +281,11 @@ def make_csv_data(record_csv: list): 'TC_PREFECTURE', 'TJ_PREFECTURE', 'TJ_ZIPCODE', 'TJ_CITY', 'TJ_ADDRESS', 'TJ_DEPARTMENT', 'TJ_TELEPHONENUMBER', 'TC_HOSPITALCAT', 'TC_HOSPITALTYPE', 'TS_UPDATE', 'TD_UPDATE'] - # Shift-JIS、CRLF、価囲いありで書き込む with open(csv_file_path, mode='w', encoding='cp932') as csv_file: - # ヘッダ行書き込み + # ヘッダ行書き込み(くくり文字をつけない為にwriteしています) csv_file.write(f"{','.join(head_str)}\n") + + # Shift-JIS、CRLF、価囲いありで書き込む writer = csv.writer(csv_file, delimiter=',', lineterminator='\n', quotechar='"', doublequote=True, quoting=csv.QUOTE_ALL, strict=True From 6df0c43e78a68ff53184b17c841ef8b52105e34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 11:45:29 +0900 Subject: [PATCH 16/28] =?UTF-8?q?ultmarc=5Fprocess=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E3=82=8F=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E3=81=97?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../batch/ultmarc/export_vjsk_csv_process.py | 5 +++-- .../src/batch/ultmarc/ultmarc_process.py | 17 +---------------- ecs/jskult-batch-daily/src/jobctrl_daily.py | 6 +++++- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py index a1b2ff23..ddd2a0ae 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py @@ -241,10 +241,11 @@ def make_csv_data(record_inst_csv: list, record_pharm_cs: list): 'FILLER_3', 'FILLER_4', 'FILLER_5', 'REGIST_DATE', 'CREATE_USER', 'UPDATE_DATE', 'UPDATE_USER', 'SYS_REGIST_DATE', 'REGIST_PRGM_ID', 'SYS_UPDATE_DATE', 'UPDATE_PRGM_ID'] - # Shift-JIS、CRLF、価囲いありで書き込む with open(csv_file_path, mode='w', encoding='cp932') as csv_file: - # ヘッダ行書き込み + # ヘッダ行書き込み(くくり文字を加えない為にwriteで出力する) csv_file.write(f"{','.join(head_str)}\n") + + # Shift-JIS、CRLF、価囲いありで書き込む writer = csv.writer(csv_file, delimiter=',', lineterminator='\n', quotechar='"', doublequote=True, quoting=csv.QUOTE_ALL, strict=True diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py index e0e6ba22..0e2ffe6a 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/ultmarc_process.py @@ -5,7 +5,7 @@ from datetime import datetime from src.aws.s3 import UltmarcBucket from src.batch.common.batch_context import BatchContext from src.batch.ultmarc.datfile import DatFile -from src.batch.ultmarc import export_vjsk_csv_process + from src.batch.ultmarc.utmp_tables.ultmarc_table_mapper_factory import \ UltmarcTableMapperFactory from src.db.database import Database @@ -61,21 +61,6 @@ def exec_import(): raise BatchOperationException(e) -def exec_export(): - """V実消化用施設データ作成処理""" - if not batch_context.is_ultmarc_imported: - logger.info('アルトマーク取込が行われていないため、V実消化用施設データ作成処理をスキップします。') - return - - try: - logger.info('V実用消化施設データ作成処理: 開始') - export_vjsk_csv_process.exec() - logger.info('V実用消化施設データ作成処理: 終了') - except Exception as e: - raise BatchOperationException(e) - return - - def _import_to_ultmarc_table(dat_file: DatFile): db = Database.get_instance() try: diff --git a/ecs/jskult-batch-daily/src/jobctrl_daily.py b/ecs/jskult-batch-daily/src/jobctrl_daily.py index 45e297e9..3b314b26 100644 --- a/ecs/jskult-batch-daily/src/jobctrl_daily.py +++ b/ecs/jskult-batch-daily/src/jobctrl_daily.py @@ -13,6 +13,7 @@ from src.batch.ultmarc import ultmarc_process from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger from src.system_var import constants +from src.batch.ultmarc import export_vjsk_csv_process logger = get_logger('日次処理コントロール') @@ -75,8 +76,11 @@ def exec(): logger.debug(f'{"アルトマーク取込が行われました。" if batch_context.is_ultmarc_imported else "アルトマーク取込が行われませんでした。"}') try: + if not batch_context.is_ultmarc_imported: + logger.info('アルトマーク取込が行われていないため、V実消化用施設データ作成処理をスキップします。') + return logger.info('V実消化用施設データ作成処理:起動') - ultmarc_process.exec_export() + export_vjsk_csv_process.exec() logger.info('V実消化用施設データ作成処理:終了') except BatchOperationException as e: logger.exception(f'V実消化用施設データ作成処理エラー(異常終了){e}') From 819c1543f8c01b4d784b3da2548a7924f34e6a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 13:54:11 +0900 Subject: [PATCH 17/28] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BA=8B=E9=A0=85?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-monthly/src/aws/s3.py | 7 +-- .../src/batch/output_arisj_file_process.py | 51 ++++++++++--------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/ecs/jskult-batch-monthly/src/aws/s3.py b/ecs/jskult-batch-monthly/src/aws/s3.py index 8804bba9..17ed0fe9 100644 --- a/ecs/jskult-batch-monthly/src/aws/s3.py +++ b/ecs/jskult-batch-monthly/src/aws/s3.py @@ -69,10 +69,7 @@ class ArisjBucket(S3Bucket): _bucket_name = environment.ARISJ_DATA_BUCKET _folder = environment.ARISJ_BACKUP_FOLDER - def list_dat_file(self): - return self._s3_client.list_objects(self._bucket_name, self._folder) - - def s3_arisj_csv_upload(self, arisj_create_csv: str, csv_file_path: str): + def upload_arisj_csv_file(self, arisj_create_csv: str, csv_file_path: str): # s3にCSVファイルをUPする Bucket = environment.ARISJ_DATA_BUCKET folder = environment.ARISJ_DATA_FOLDER @@ -81,7 +78,7 @@ class ArisjBucket(S3Bucket): s3_client.upload_file(csv_file_path, Bucket, csv_file_name) return - def backup_dat_file(self, dat_file_key: str, datetime_key: str): + def backup_arisj_csv_file(self, dat_file_key: str, datetime_key: str): # バックアップバケットにコピー arisj_backup_bucket = ArisjBackupBucket() folder = environment.ARISJ_DATA_FOLDER diff --git a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py index 9d7d5587..d3f81597 100644 --- a/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py +++ b/ecs/jskult-batch-monthly/src/batch/output_arisj_file_process.py @@ -12,13 +12,14 @@ import csv logger = get_logger('ARIS-J連携データ出力') -create_date = datetime.now().strftime('%Y%m%d%H%M%S') -arisj_create_csv = f'D0004_ARIS_M_DCF_{create_date}.csv' sql_err_msg = "SQL実行エラーです。" def exec(): """ 実消化&アルトマーク月次バッチ """ + create_date = datetime.now().strftime('%Y%m%d%H%M%S') + arisj_csv_file_name = f'D0004_ARIS_M_DCF_{create_date}.csv' + try: logger.info('バッチ処理を開始しました。') @@ -34,30 +35,30 @@ def exec(): db.begin() # 正常系データの反映 - # 過去分は不要のため、デリート - physical_wk_inst_aris_if_delete(db) + # 前回保管した施設IFワークを削除する + delete_previous_wk_inst_aris_if_record(db) # 正常系データを取得しWKテーブルに保存する。 - wk_inst_aris_if_insert_into(db) + insert_normal_record_into_wk_inst_aris_if(db) # 正常系データの件数を取得 - suc_count = wk_inst_aris_if_count(db) + suc_count = count_wk_inst_aris_if_record(db) # 警告系データの反映 - # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 - physical_wk_inst_aris_if_wrn_delete(db) + # 前回保管した施設IF警告ワークを削除する + delete_previous_wk_inst_aris_if_wrn_record(db) # 異常系データを取得しWKテーブルに保存する。 - wk_inst_aris_if_wrn_insert_into(db) + insert_abnormal_record_into_wk_inst_aris_if_wrn(db) # 異常系データの件数を取得 - wrn_count = wk_inst_aris_if_wrn_count(db) + wrn_count = count_wk_inst_aris_if_wrn_record(db) # CSVファイルの作成用のSQL実行 record_csv = csv_data_select(db) # CSVファイル作成 - csv_file_path = make_csv_data(record_csv) + csv_file_path = make_csv_data(record_csv, arisj_csv_file_name) # トランザクションの終了 db.commit() @@ -66,18 +67,18 @@ def exec(): sum_count = suc_count + wrn_count logger.info(f'(対象件数:{sum_count}/正常件数:{suc_count}/警告件数:{wrn_count})') + arisj_bucket = ArisjBucket() # CSVファイル移動処理 try: - ArisjBucket().s3_arisj_csv_upload(arisj_create_csv, csv_file_path) + arisj_bucket.upload_arisj_csv_file(arisj_csv_file_name, csv_file_path) except Exception as e: logger.info('S3バケットArisjへのCSVデータ、移動できませんでした。') raise e # 処理後ファイルをバックアップ try: - arisj_bucket = ArisjBucket() batch_context = BatchContext.get_instance() - arisj_bucket.backup_dat_file(arisj_create_csv, batch_context.syor_date) + arisj_bucket.backup_arisj_csv_file(arisj_csv_file_name, batch_context.syor_date) except Exception as e: logger.info('S3バケットArisjバックアップへCSVデータ、コピーできませんでした。') raise e @@ -93,8 +94,8 @@ def exec(): db.disconnect() -def physical_wk_inst_aris_if_delete(db): - # 過去分は不要のため、デリート +def delete_previous_wk_inst_aris_if_record(db): + # 前回保管した施設IFワークを削除する try: # WKテーブルの過去分削除SQL sql = """\ @@ -107,7 +108,7 @@ def physical_wk_inst_aris_if_delete(db): raise e -def wk_inst_aris_if_insert_into(db): +def insert_normal_record_into_wk_inst_aris_if(db): # 正常系データを取得しWKテーブルに保存する。 try: # 正常系データを取得しWKテーブルに保存SQL @@ -155,7 +156,7 @@ def wk_inst_aris_if_insert_into(db): raise e -def wk_inst_aris_if_count(db): +def count_wk_inst_aris_if_record(db): # 正常系データの件数を取得 try: # 正常系データの件数を取得SQL @@ -169,8 +170,8 @@ def wk_inst_aris_if_count(db): raise e -def physical_wk_inst_aris_if_wrn_delete(db): - # 過去分は不要のため、DWH.WK_INST_ARIS_IF_WRNをデリートする。 +def delete_previous_wk_inst_aris_if_wrn_record(db): + # 前回保管した施設IF警告ワークを削除する try: # 異常系WKテーブルの過去分削除SQL sql = """\ @@ -184,7 +185,7 @@ def physical_wk_inst_aris_if_wrn_delete(db): raise e -def wk_inst_aris_if_wrn_insert_into(db): +def insert_abnormal_record_into_wk_inst_aris_if_wrn(db): # 異常系データを取得しWKテーブルに保存する。 try: # 異常系データを取得しWKテーブルに保存SQL @@ -238,7 +239,7 @@ def wk_inst_aris_if_wrn_insert_into(db): raise e -def wk_inst_aris_if_wrn_count(db): +def count_wk_inst_aris_if_wrn_record(db): # 異常系データの件数を取得 try: # 異常系データの件数を取得SQL @@ -271,18 +272,18 @@ def csv_data_select(db): raise e -def make_csv_data(record_csv: list): +def make_csv_data(record_csv: list, arisj_csv_file_name: str): # 一時ファイルとして保存する(CSVファイル) try: temporary_dir = tempfile.mkdtemp() - csv_file_path = path.join(temporary_dir, arisj_create_csv) + csv_file_path = path.join(temporary_dir, arisj_csv_file_name) head_str = ['TC_HOSPITAL', 'TJ_HOSPITAL', 'TJ_HOSPITALSHORT', 'TK_HOSPITAL', 'TC_PREFECTURE', 'TJ_PREFECTURE', 'TJ_ZIPCODE', 'TJ_CITY', 'TJ_ADDRESS', 'TJ_DEPARTMENT', 'TJ_TELEPHONENUMBER', 'TC_HOSPITALCAT', 'TC_HOSPITALTYPE', 'TS_UPDATE', 'TD_UPDATE'] with open(csv_file_path, mode='w', encoding='cp932') as csv_file: - # ヘッダ行書き込み(くくり文字をつけない為にwriteしています) + # ヘッダ行書き込み(くくり文字をつけない為にwriterowではなく、writeを使用しています) csv_file.write(f"{','.join(head_str)}\n") # Shift-JIS、CRLF、価囲いありで書き込む From 552f2475e3d96846d5973bf834a2cb6e08798270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 14:10:41 +0900 Subject: [PATCH 18/28] =?UTF-8?q?=E3=83=8D=E3=83=BC=E3=83=9F=E3=83=B3?= =?UTF-8?q?=E3=82=B0=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rt_vjsk_csv_process.py => vjsk_process.py} | 31 +++++++++---------- ecs/jskult-batch-daily/src/jobctrl_daily.py | 4 +-- 2 files changed, 17 insertions(+), 18 deletions(-) rename ecs/jskult-batch-daily/src/batch/ultmarc/{export_vjsk_csv_process.py => vjsk_process.py} (91%) diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/vjsk_process.py similarity index 91% rename from ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py rename to ecs/jskult-batch-daily/src/batch/ultmarc/vjsk_process.py index ddd2a0ae..9c0b83a1 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/export_vjsk_csv_process.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/vjsk_process.py @@ -1,6 +1,6 @@ """アルトマークデータ処理""" -from src.aws.s3 import UltmarcBucket, VjskBucket +from src.aws.s3 import VjskBucket from src.batch.common.batch_context import BatchContext from src.db.database import Database @@ -10,14 +10,13 @@ import os.path as path import csv logger = get_logger('V実用消化施設データ作成処理') -ultmarc_bucket = UltmarcBucket() -batch_context = BatchContext.get_instance() sql_err_msg = "SQL実行エラーです。" -vjsk_csv_file_name = 'ComInst.csv' def exec(): + vjsk_csv_file_name = 'ComInst.csv' + db = Database.get_instance() try: logger.info('バッチ処理を開始しました。') @@ -32,11 +31,11 @@ def exec(): raise e # CSVファイルの作成用のSQL実行(施設) - record_inst_csv = csv_data_inst_select(db) + record_inst = select_inst_record(db) # CSVファイルの作成用のSQL実行(薬局) - record_pharm_csv = csv_data_pharm_select(db) + record_pharm = select_pharm_record(db) # CSVファイル作成 - csv_file_path = make_csv_data(record_inst_csv, record_pharm_csv) + csv_file_path = make_csv_data(record_inst, record_pharm, vjsk_csv_file_name) vjsk_bucket = VjskBucket() try: @@ -54,7 +53,7 @@ def exec(): logger.info('バックアップバケットへCSVデータをコピーできませんでした。') raise e - csv_count = len(record_inst_csv) + len(record_pharm_csv) + csv_count = len(record_inst) + len(record_pharm) logger.info(f'CSV出力件数: {csv_count}。') logger.info('バッチ処理を正常に終了しました。') except Exception as e: @@ -66,8 +65,8 @@ def exec(): return -def csv_data_inst_select(db): - # CSVファイルの作成用のSQL実行(施設) +def select_inst_record(db): + # CSVファイル作成用のSQL実行(施設) try: # 施設テーブル検索SQL sql = """\ @@ -144,8 +143,8 @@ def csv_data_inst_select(db): raise e -def csv_data_pharm_select(db): - # CSVファイルの作成用のSQL実行(薬局) +def select_pharm_record(db): + # CSVファイル作成用のSQL実行(薬局) try: # 薬局テーブル検索SQL sql = """\ @@ -222,7 +221,7 @@ def csv_data_pharm_select(db): raise e -def make_csv_data(record_inst_csv: list, record_pharm_cs: list): +def make_csv_data(record_inst: list, record_pharm: list, vjsk_csv_file_name: str): # 一時ファイルとして保存する(CSVファイル) try: @@ -242,7 +241,7 @@ def make_csv_data(record_inst_csv: list, record_pharm_cs: list): 'REGIST_PRGM_ID', 'SYS_UPDATE_DATE', 'UPDATE_PRGM_ID'] with open(csv_file_path, mode='w', encoding='cp932') as csv_file: - # ヘッダ行書き込み(くくり文字を加えない為にwriteで出力する) + # ヘッダ行書き込み(くくり文字をつけない為にwriterowではなく、writeを使用しています) csv_file.write(f"{','.join(head_str)}\n") # Shift-JIS、CRLF、価囲いありで書き込む @@ -252,13 +251,13 @@ def make_csv_data(record_inst_csv: list, record_pharm_cs: list): ) # データ部分書き込み(施設) - for record_inst_data in record_inst_csv: + for record_inst_data in record_inst: record_inst_value = list(record_inst_data.values()) csv_data = ['' if n is None else n for n in record_inst_value] writer.writerow(csv_data) # データ部分書き込み(薬局) - for record_pharm_data in record_pharm_cs: + for record_pharm_data in record_pharm: record_pharm_value = list(record_pharm_data.values()) csv_data = ['' if n is None else n for n in record_pharm_value] writer.writerow(csv_data) diff --git a/ecs/jskult-batch-daily/src/jobctrl_daily.py b/ecs/jskult-batch-daily/src/jobctrl_daily.py index 3b314b26..0e92bd1b 100644 --- a/ecs/jskult-batch-daily/src/jobctrl_daily.py +++ b/ecs/jskult-batch-daily/src/jobctrl_daily.py @@ -13,7 +13,7 @@ from src.batch.ultmarc import ultmarc_process from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger from src.system_var import constants -from src.batch.ultmarc import export_vjsk_csv_process +from src.batch.ultmarc import vjsk_process logger = get_logger('日次処理コントロール') @@ -80,7 +80,7 @@ def exec(): logger.info('アルトマーク取込が行われていないため、V実消化用施設データ作成処理をスキップします。') return logger.info('V実消化用施設データ作成処理:起動') - export_vjsk_csv_process.exec() + vjsk_process.exec() logger.info('V実消化用施設データ作成処理:終了') except BatchOperationException as e: logger.exception(f'V実消化用施設データ作成処理エラー(異常終了){e}') From afd5db75e5e2bac621e0925d35869357cf2eb08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 16:32:49 +0900 Subject: [PATCH 19/28] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BA=8B=E9=A0=85?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...cess.py => output_vjsk_inst_pharm_data.py} | 69 ++++++++++--------- ecs/jskult-batch-daily/src/jobctrl_daily.py | 7 +- 2 files changed, 38 insertions(+), 38 deletions(-) rename ecs/jskult-batch-daily/src/batch/ultmarc/{vjsk_process.py => output_vjsk_inst_pharm_data.py} (84%) diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/vjsk_process.py b/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py similarity index 84% rename from ecs/jskult-batch-daily/src/batch/ultmarc/vjsk_process.py rename to ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py index 9c0b83a1..1fb338b7 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/vjsk_process.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py @@ -1,4 +1,4 @@ -"""アルトマークデータ処理""" +"""output_vjsk_inst_pharm_data""" from src.aws.s3 import VjskBucket from src.batch.common.batch_context import BatchContext @@ -9,7 +9,7 @@ import tempfile import os.path as path import csv -logger = get_logger('V実用消化施設データ作成処理') +logger = get_logger('V実消化用施設データ作成処理') sql_err_msg = "SQL実行エラーです。" @@ -17,15 +17,20 @@ sql_err_msg = "SQL実行エラーです。" def exec(): vjsk_csv_file_name = 'ComInst.csv' + # バッチ共通設定を取得 + batch_context = BatchContext.get_instance() + + if not batch_context.is_ultmarc_imported: + logger.info('アルトマーク取込が行われていないため、V実消化用施設データ作成処理をスキップします。') + return + db = Database.get_instance() try: - logger.info('バッチ処理を開始しました。') + logger.info('処理開始') try: # DB接続 db.connect() - # ファイル単位でトランザクションを行う - db.begin() except Exception as e: logger.info('DB接続エラーです。') raise e @@ -42,7 +47,7 @@ def exec(): # s3へデータ移動 vjsk_bucket.upload_dat_file(vjsk_csv_file_name, csv_file_path) except Exception as e: - logger.info('S3バケットDWHへCSVデータを作成できませんでした。') + logger.info('S3バケットにCSVデータを作成できませんでした。') raise e try: @@ -54,13 +59,11 @@ def exec(): raise e csv_count = len(record_inst) + len(record_pharm) - logger.info(f'CSV出力件数: {csv_count}。') - logger.info('バッチ処理を正常に終了しました。') + logger.info(f'CSV出力件数: {csv_count}') + logger.info('正常終了') except Exception as e: raise e finally: - # 終了時に必ずコミットする - db.commit() db.disconnect() return @@ -155,14 +158,14 @@ def select_pharm_record(db): inst_name_kana, form_inst_name_kanji, inst_name_kanji, - '', - '', + '' AS rltd_univ_prnt_cd, + '' AS bed_num, close_flg, estab_sche_flg, close_start_ym, estab_sche_ym, - '', - '', + '' AS ward_abolish_flg, + '' AS inst_repre_cd, inst_repre_kana, inst_repre, phone_number_non_flg, @@ -179,24 +182,24 @@ def select_pharm_record(db): addr_cnt, manage_cd, delete_sche_reason_cd, - '', + '' AS hp_assrt_cd, dup_opp_cd, - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', + '' AS insp_item_micrb, + '' AS insp_item_serum, + '' AS insp_item_blood, + '' AS insp_item_patho, + '' AS insp_item_paras, + '' AS insp_item_biochem, + '' AS insp_item_ri, + '' AS re_exam_cd, + '' AS prmit_bed_num_other, + '' AS prmit_bed_num_mental, + '' AS prmit_bed_num_tuber, + '' AS prmit_bed_num_infection, + '' AS prmit_bed_num_sum, + '' AS prmit_bed_num_gen, + '' AS prmit_bed_num_rcup, + '' AS prmit_bed_maint_ymd, inst_pharm_div, abolish_ymd, delete_flg, @@ -240,7 +243,7 @@ def make_csv_data(record_inst: list, record_pharm: list, vjsk_csv_file_name: str 'FILLER_3', 'FILLER_4', 'FILLER_5', 'REGIST_DATE', 'CREATE_USER', 'UPDATE_DATE', 'UPDATE_USER', 'SYS_REGIST_DATE', 'REGIST_PRGM_ID', 'SYS_UPDATE_DATE', 'UPDATE_PRGM_ID'] - with open(csv_file_path, mode='w', encoding='cp932') as csv_file: + with open(csv_file_path, mode='w', encoding='UTF-8') as csv_file: # ヘッダ行書き込み(くくり文字をつけない為にwriterowではなく、writeを使用しています) csv_file.write(f"{','.join(head_str)}\n") @@ -264,7 +267,7 @@ def make_csv_data(record_inst: list, record_pharm: list, vjsk_csv_file_name: str except Exception as e: logger.info('ワークデータの作成に失敗しました。') - logger.info('バッチ処理を異常終了しました。') + logger.info('CSVデータの作成に失敗しました。') raise e return csv_file_path diff --git a/ecs/jskult-batch-daily/src/jobctrl_daily.py b/ecs/jskult-batch-daily/src/jobctrl_daily.py index 0e92bd1b..e6751a47 100644 --- a/ecs/jskult-batch-daily/src/jobctrl_daily.py +++ b/ecs/jskult-batch-daily/src/jobctrl_daily.py @@ -13,7 +13,7 @@ from src.batch.ultmarc import ultmarc_process from src.error.exceptions import BatchOperationException from src.logging.get_logger import get_logger from src.system_var import constants -from src.batch.ultmarc import vjsk_process +from src.batch.ultmarc import output_vjsk_inst_pharm_data logger = get_logger('日次処理コントロール') @@ -76,11 +76,8 @@ def exec(): logger.debug(f'{"アルトマーク取込が行われました。" if batch_context.is_ultmarc_imported else "アルトマーク取込が行われませんでした。"}') try: - if not batch_context.is_ultmarc_imported: - logger.info('アルトマーク取込が行われていないため、V実消化用施設データ作成処理をスキップします。') - return logger.info('V実消化用施設データ作成処理:起動') - vjsk_process.exec() + output_vjsk_inst_pharm_data.exec() logger.info('V実消化用施設データ作成処理:終了') except BatchOperationException as e: logger.exception(f'V実消化用施設データ作成処理エラー(異常終了){e}') From ac5ee0e20bc8bc8bfa5567532f7bff5159ba3793 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 5 Jul 2023 17:04:54 +0900 Subject: [PATCH 20/28] =?UTF-8?q?feat:=20=E3=81=82=E3=82=8B=E3=81=A8?= =?UTF-8?q?=E3=83=9E=E3=83=BC=E3=82=AF=E3=81=AE=E3=83=89=E3=83=AD=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=83=80=E3=82=A6=E3=83=B3=E3=81=AE=E9=AB=98=E3=81=95?= =?UTF-8?q?=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-webapp/src/static/css/ultStyle.css | 1 + 1 file changed, 1 insertion(+) diff --git a/ecs/jskult-webapp/src/static/css/ultStyle.css b/ecs/jskult-webapp/src/static/css/ultStyle.css index e39fa143..c31553f1 100644 --- a/ecs/jskult-webapp/src/static/css/ultStyle.css +++ b/ecs/jskult-webapp/src/static/css/ultStyle.css @@ -32,6 +32,7 @@ table{ .search_dropdown{ width: 100%; + height: 1.8em; } .search_longtextbox{ From a30577289111705726e673a0b631fff1e527af3d Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 5 Jul 2023 18:03:03 +0900 Subject: [PATCH 21/28] =?UTF-8?q?feat:=20=E3=83=9A=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=8D=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE=E3=83=87?= =?UTF-8?q?=E3=82=B6=E3=82=A4=E3=83=B3=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/static/css/pagenation.css | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/ecs/jskult-webapp/src/static/css/pagenation.css b/ecs/jskult-webapp/src/static/css/pagenation.css index 3edbf3b2..72e4aecc 100644 --- a/ecs/jskult-webapp/src/static/css/pagenation.css +++ b/ecs/jskult-webapp/src/static/css/pagenation.css @@ -3,10 +3,6 @@ padding-top: 10px; } -/* .paginationjs { - width: 100%; -} */ - .paginationjs > .paginationjs-nav.J-paginationjs-nav{ position: absolute; right: 0; @@ -19,10 +15,12 @@ div.paginationjs-pages ul { } .paginationjs-pages > ul > li > a { - padding: 6px 18px; + padding: 6px 9px; color: white; - background-color: gainsboro; - border: 1px solid; + background-color: whitesmoke; + border: 1px solid #bbb; + border-radius: 3px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) } .paginationjs-pages > ul > li > a:hover { color: black; @@ -31,27 +29,38 @@ div.paginationjs-pages ul { } .paginationjs-pages > ul > li.active > a { color: white; - background-color: gray; + background-color: #666666; + box-shadow: none; } .paginationjs-pages > ul > li.active > a:hover { color: white; - background-color: gray; + background-color: #666666; cursor: text; } .paginationjs-pages > ul > li.disabled > a { color: white; - background-color: gray; - cursor: text; + background-color: #666666; + box-shadow: none; } .paginationjs-pages > ul > li.disabled > a:hover { color: white; - background-color: gray; + background-color: #666666; cursor: text; } -.paginationjs-page { +.paginationjs-page,.paginationjs-prev,.paginationjs-next { + text-decoration: underline; margin: 0 4px; } + +.paginationjs-page:hover,.paginationjs-prev:hover,.paginationjs-next:hover { + text-decoration: none; +} + +.paginationjs-page.active,.paginationjs-prev.disabled,.paginationjs-next.disabled { + text-decoration: none; +} + .paginationjs-pages > ul { display: flex; align-items: baseline; From 518c84695e59af7fecfdf50f9244b53834809065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Wed, 5 Jul 2023 18:05:44 +0900 Subject: [PATCH 22/28] =?UTF-8?q?=E5=90=8D=E7=A7=B0=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-daily/src/aws/s3.py | 44 +++++++++---------- .../ultmarc/output_vjsk_inst_pharm_data.py | 8 ++-- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/ecs/jskult-batch-daily/src/aws/s3.py b/ecs/jskult-batch-daily/src/aws/s3.py index 8cf6c3cf..86ffc169 100644 --- a/ecs/jskult-batch-daily/src/aws/s3.py +++ b/ecs/jskult-batch-daily/src/aws/s3.py @@ -1,4 +1,3 @@ -import io import os import os.path as path import tarfile @@ -80,28 +79,6 @@ class UltmarcBucket(S3Bucket): self._s3_client.delete_file(self._bucket_name, dat_file_key) -class VjskBucket(S3Bucket): - _bucket_name = environment.VJSK_DATA_BUCKET - _folder = environment.VJSK_DATA_SEND_FOLDER - - def list_dat_file(self): - return self._s3_client.list_objects(self._bucket_name, self._folder) - - def upload_dat_file(self, vjsk_create_csv: str, csv_file_path: str): - # S3バケットにファイルを移動 - csv_file_name = f'{self._folder}/{vjsk_create_csv}' - s3_client = S3Client() - s3_client.upload_file(csv_file_path, self._bucket_name, csv_file_name) - return - - def backup_dat_file(self, dat_file_key: str, datetime_key: str): - # バックアップバケットにコピー - vjsk_backup_bucket = VjskBackupBucket() - dat_key = f'{self._folder}/{dat_file_key}' - backup_key = f'{vjsk_backup_bucket._folder}/{self._folder}/{datetime_key}/{dat_file_key.replace(f"{self._folder}/", "")}' - self._s3_client.copy(self._bucket_name, dat_key, vjsk_backup_bucket._bucket_name, backup_key) - - class ConfigBucket(S3Bucket): _bucket_name = environment.JSKULT_CONFIG_BUCKET @@ -139,7 +116,7 @@ class VjskBackupBucket(JskUltBackupBucket): class VjskReceiveBucket(S3Bucket): - _bucket_name = environment.JSKULT_DATA_BUCKET + _bucket_name = environment.VJSK_DATA_BUCKET _recv_folder = environment.JSKULT_DATA_FOLDER_RECV _s3_file_list = None @@ -176,3 +153,22 @@ class VjskReceiveBucket(S3Bucket): self._s3_client.copy(self._bucket_name, backup_from_file_path, jskult_backup_bucket._bucket_name, backup_key) self._s3_client.delete_file(self._bucket_name, backup_from_file_path) + + +class VjskSendBucket(S3Bucket): + _bucket_name = environment.VJSK_DATA_BUCKET + _send_folder = environment.VJSK_DATA_SEND_FOLDER + + def upload_vjsk_csv_file(self, vjsk_create_csv: str, csv_file_path: str): + # S3バケットにファイルを移動 + csv_file_name = f'{self._send_folder}/{vjsk_create_csv}' + s3_client = S3Client() + s3_client.upload_file(csv_file_path, self._bucket_name, csv_file_name) + return + + def backup_vjsk_csv_file(self, dat_file_key: str, datetime_key: str): + # バックアップバケットにコピー + vjsk_backup_bucket = VjskBackupBucket() + dat_key = f'{self._send_folder}/{dat_file_key}' + backup_key = f'{vjsk_backup_bucket._folder}/{self._send_folder}/{datetime_key}/{dat_file_key.replace(f"{self._send_folder}/", "")}' + self._s3_client.copy(self._bucket_name, dat_key, vjsk_backup_bucket._bucket_name, backup_key) diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py b/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py index 1fb338b7..f72e8d92 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py @@ -1,6 +1,6 @@ """output_vjsk_inst_pharm_data""" -from src.aws.s3 import VjskBucket +from src.aws.s3 import VjskSendBucket from src.batch.common.batch_context import BatchContext from src.db.database import Database @@ -42,10 +42,10 @@ def exec(): # CSVファイル作成 csv_file_path = make_csv_data(record_inst, record_pharm, vjsk_csv_file_name) - vjsk_bucket = VjskBucket() + vjsk_bucket = VjskSendBucket() try: # s3へデータ移動 - vjsk_bucket.upload_dat_file(vjsk_csv_file_name, csv_file_path) + vjsk_bucket.upload_vjsk_csv_file(vjsk_csv_file_name, csv_file_path) except Exception as e: logger.info('S3バケットにCSVデータを作成できませんでした。') raise e @@ -53,7 +53,7 @@ def exec(): try: # 処理後ファイルをバックアップ batch_context = BatchContext.get_instance() - vjsk_bucket.backup_dat_file(vjsk_csv_file_name, batch_context.syor_date) + vjsk_bucket.backup_vjsk_csv_file(vjsk_csv_file_name, batch_context.syor_date) except Exception as e: logger.info('バックアップバケットへCSVデータをコピーできませんでした。') raise e From 4427e9362e2c80681ff8fdda5e0fb4fb847f5488 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 5 Jul 2023 18:16:08 +0900 Subject: [PATCH 23/28] =?UTF-8?q?fix:=20=E4=B8=8D=E8=A6=81=E3=81=AAJS?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=82=92=E6=95=B4=E7=90=86=E3=81=97=E3=81=9F?= =?UTF-8?q?=E3=81=AA=E3=81=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../static/function/businessLogicScript.js | 72 ------------------- .../src/templates/docSearch.html | 16 +++-- .../src/templates/instSearch.html | 16 +++-- 3 files changed, 22 insertions(+), 82 deletions(-) diff --git a/ecs/jskult-webapp/src/static/function/businessLogicScript.js b/ecs/jskult-webapp/src/static/function/businessLogicScript.js index 36171aad..f410d5ab 100644 --- a/ecs/jskult-webapp/src/static/function/businessLogicScript.js +++ b/ecs/jskult-webapp/src/static/function/businessLogicScript.js @@ -128,28 +128,6 @@ function autoModifyDate($this){ $this.value = strFormat; } -// 他のページで共通化しよう -// ページが読み込まれたときにsendクラスのボタンを押せないようにする -// 初期値をdisabledにしときゃいい -$(function(){ - $(".send").prop('disabled',true); -}); - -// 検索結果のところのボタンをチェックが1個でも付いたら押せるようにして、チェックがなければ押せないようにする関数 -// 条件:チェックボックスのクラス名に"selectedページ数"というのがついていること -// 条件:ボタンにクラス名 send がついていること -function resultBtDisablead(){ - var selected = ".selected" + tableCurrentPage; - var cnt1 = $(selected + ' :checked').length; - selected += " input.checkbox"; - - if(cnt1 == 0) { - $(".send").prop('disabled',true); - } - else { - $(".send").prop('disabled',false); - } -} // 前のスペースを許さない入力チェック function checkSpaceForm($this) @@ -186,13 +164,6 @@ function checkPassForm($this) $this.value=str; } -// 廃止予定 -function DisplayErrorDialog(strMesssage) { - $("#errorTxt").html(strMesssage); - $("#error").dialog("open"); -} - -/* ult.jsから移植 */ // チェックボックス全選択関数 // 条件:チェックボックスのクラス名に"selected"というのがついていること // 条件:ボタンにクラス名 send がついていること @@ -208,46 +179,3 @@ function allOff(){ $(".selected").prop("checked", false); $(".send").prop('disabled',true); } - -// 検索結果のところのボタンをチェックが1個でも付いたら押せるようにして、チェックがなければ押せないようにする関数 -// 条件:チェックボックスのクラス名に"selected"というのがついていること -// 条件:ボタンにクラス名 send がついていること -function resultBtDisablead(){ - var cnt1 = $('.checkNum input:checkbox:checked').length; - console.log(cnt1); - if(cnt1 == 0) { - $(".send").prop('disabled',true); - } - else { - $(".send").prop('disabled',false); - } -} - -// Enter押下時にsubmitさせなくする -$(function() { - $(document).on("keypress", "input:not(.allow_submit)", function(event) { - return event.which !== 13; - }); -}); - -// 数字-以外を許さない入力チェック -function checkNumberForm($this) -{ - var str=$this.value; - while(str.match(/[^\d\-]/)) - { - str=str.replace(/[^\d\-]/,""); - } - $this.value=str; -} - -// 数字以外を許さない入力チェック -function checkNumberOnlyForm($this) -{ - var str=$this.value; - while(str.match(/[^\d]/)) - { - str=str.replace(/[^\d]/,""); - } - $this.value=str; -} \ No newline at end of file diff --git a/ecs/jskult-webapp/src/templates/docSearch.html b/ecs/jskult-webapp/src/templates/docSearch.html index 365e2745..292dd409 100644 --- a/ecs/jskult-webapp/src/templates/docSearch.html +++ b/ecs/jskult-webapp/src/templates/docSearch.html @@ -12,6 +12,12 @@ FixedMidashi.create(); // ボタン、テキストボックス初期化 formBtDisabled(); + // Enter押下時にsubmitさせなくする + $(function() { + $(document).on("keypress", "input:not(.allow_submit)", function(event) { + return event.which !== 13; + }); + }); } @@ -112,8 +118,8 @@
- - + + @@ -231,7 +237,7 @@ return `
-
${td} @@ -241,8 +247,8 @@ }) } - // チェックボックスのチェックされている場合、施設情報ボタンを活性化させる - function resultBtDisablead(){ + // チェックボックスのチェックされている場合、医師情報ボタンを活性化させる + function resultBtDisabled(){ var checkboxes = $('input[name="data"]:checked').length; if(checkboxes == 0) { $(".info_bt").prop('disabled',true); diff --git a/ecs/jskult-webapp/src/templates/instSearch.html b/ecs/jskult-webapp/src/templates/instSearch.html index 361977ae..8a866777 100644 --- a/ecs/jskult-webapp/src/templates/instSearch.html +++ b/ecs/jskult-webapp/src/templates/instSearch.html @@ -12,6 +12,12 @@ FixedMidashi.create(); // ボタン、テキストボックス初期化 formBtDisabled(); + // Enter押下時にsubmitさせなくする + $(function() { + $(document).on("keypress", "input:not(.allow_submit)", function(event) { + return event.which !== 13; + }); + }); } @@ -112,8 +118,8 @@ - - + + @@ -228,7 +234,7 @@ return `
-
${td} @@ -238,7 +244,7 @@ } // チェックボックスのチェックされている場合、施設情報ボタンを活性化させる - function resultBtDisablead(){ + function resultBtDisabled(){ var checkboxes = $('input[name="data"]:checked').length; if(checkboxes == 0) { $(".info_bt").prop('disabled',true); @@ -248,7 +254,7 @@ } } - // // 検索結果のうち、チェックされている行のデータを非表示項目に詰め込む + // 検索結果のうち、チェックされている行のデータを非表示項目に詰め込む function CheckBoxListProcessing() { let vals = []; // 配列を定義 From 5595717d0c47f2ca951b37deb6efb9f9b98ef59f Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 5 Jul 2023 19:06:25 +0900 Subject: [PATCH 24/28] =?UTF-8?q?style:=20=E3=83=9A=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=8D=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=A8=E3=83=AA?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=81=AE=E9=96=93=E3=82=92=E9=96=8B=E3=81=91?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-webapp/src/static/css/bioStyle.css | 6 ---- ecs/jskult-webapp/src/static/css/ultStyle.css | 29 ------------------- .../src/templates/docSearch.html | 2 +- 3 files changed, 1 insertion(+), 36 deletions(-) diff --git a/ecs/jskult-webapp/src/static/css/bioStyle.css b/ecs/jskult-webapp/src/static/css/bioStyle.css index c0ab2ca5..26bf416e 100644 --- a/ecs/jskult-webapp/src/static/css/bioStyle.css +++ b/ecs/jskult-webapp/src/static/css/bioStyle.css @@ -113,12 +113,6 @@ table{ width : 450px; } -.docSearchScroll_div { - overflow: auto; - height: 200px; - width: 1132px; -} - .transition{ text-align: right; margin-right: 60px; diff --git a/ecs/jskult-webapp/src/static/css/ultStyle.css b/ecs/jskult-webapp/src/static/css/ultStyle.css index c31553f1..af29f38a 100644 --- a/ecs/jskult-webapp/src/static/css/ultStyle.css +++ b/ecs/jskult-webapp/src/static/css/ultStyle.css @@ -403,29 +403,6 @@ table{ width: 100%; } -.docSearchScroll{ - overflow: auto; - white-space: nowrap; - margin-bottom: 2%; - width: 100%; - height: 270px; -} - -.docSearchScroll::-webkit-scrollbar { - height: 5px; - width: 10px; -} - -.docSearchScroll::-webkit-scrollbar-track { - border-radius: 5px; - background: #eee; -} - -.docSearchScroll::-webkit-scrollbar-thumb { - border-radius: 5px; - background: #666; -} - .allOnOffButton{ width: 6%; } @@ -558,12 +535,6 @@ table{ width : 450px; } -.docSearchScroll_div { - overflow: auto; - height: 200px; - width: 1132px; -} - /*共通:施設詳細、医師詳細*/ .transition{ text-align: right; diff --git a/ecs/jskult-webapp/src/templates/docSearch.html b/ecs/jskult-webapp/src/templates/docSearch.html index 292dd409..21da4a9c 100644 --- a/ecs/jskult-webapp/src/templates/docSearch.html +++ b/ecs/jskult-webapp/src/templates/docSearch.html @@ -127,7 +127,7 @@ -
+
From a114aacf9510e75fce2fd2bf4e21adaaa1d89cf2 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Thu, 6 Jul 2023 10:41:16 +0900 Subject: [PATCH 25/28] =?UTF-8?q?feat:=20=E3=83=AA=E3=83=9D=E3=82=B8?= =?UTF-8?q?=E3=83=88=E3=83=AA=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=83=AD=E3=82=B0=E5=87=BA=E5=8A=9B=E3=82=92?= =?UTF-8?q?logger=E3=81=AB=E7=B5=B1=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/model/db/ultmarc_trt_course.py | 2 +- .../model/view/ultmarc_doctor_info_view_model.py | 4 ++-- .../src/repositories/inst_master_repository.py | 7 ++++--- .../src/repositories/prefc_master_repository.py | 7 ++++--- .../repositories/ultmarc_doctor_repository.py | 16 +++++++++------- .../ultmarc_dr_wrkplace_his_repository.py | 6 ++++-- .../ultmarc_dr_wrkplace_repository.py | 9 +++++---- .../src/repositories/ultmarc_inst_repository.py | 14 ++++++++------ .../ultmarc_inst_trt_course_repository.py | 6 ++++-- .../repositories/ultmarc_sosiety_repository.py | 6 ++++-- .../ultmarc_specialist_license_repository.py | 6 ++++-- .../ultmarc_trt_course_repository.py | 14 ++++++++------ .../src/services/ultmarc_view_service.py | 6 +++--- 13 files changed, 60 insertions(+), 43 deletions(-) diff --git a/ecs/jskult-webapp/src/model/db/ultmarc_trt_course.py b/ecs/jskult-webapp/src/model/db/ultmarc_trt_course.py index 788d9748..12ced11c 100644 --- a/ecs/jskult-webapp/src/model/db/ultmarc_trt_course.py +++ b/ecs/jskult-webapp/src/model/db/ultmarc_trt_course.py @@ -5,5 +5,5 @@ from src.util.sanitize import sanitize @sanitize -class UltmarcTrtCourseDBModel(BaseDBModel): +class UltmarcDrTrtCourseDBModel(BaseDBModel): trt_course_name: Optional[str] diff --git a/ecs/jskult-webapp/src/model/view/ultmarc_doctor_info_view_model.py b/ecs/jskult-webapp/src/model/view/ultmarc_doctor_info_view_model.py index 5de18e11..f517e4a3 100644 --- a/ecs/jskult-webapp/src/model/view/ultmarc_doctor_info_view_model.py +++ b/ecs/jskult-webapp/src/model/view/ultmarc_doctor_info_view_model.py @@ -10,7 +10,7 @@ from src.model.db.ultmarc_doctor_wrkplace_his import \ from src.model.db.ultmarc_sosiety import UltmarcSosietyDBModel from src.model.db.ultmarc_specialist_license import \ UltmarcSpecialistLicenseDBModel -from src.model.db.ultmarc_trt_course import UltmarcTrtCourseDBModel +from src.model.db.ultmarc_trt_course import UltmarcDrTrtCourseDBModel from src.system_var import environment @@ -18,7 +18,7 @@ class UltmarcDoctorInfoViewModel(BaseModel): subtitle: str = '医師情報' is_batch_processing: Optional[bool] doctor_info_data: Optional[UltmarcDoctorInfoDBModel] - trt_coursed_data: Optional[list[UltmarcTrtCourseDBModel]] + trt_coursed_data: Optional[list[UltmarcDrTrtCourseDBModel]] sosiety_data: Optional[list[UltmarcSosietyDBModel]] specialist_license_data: Optional[list[UltmarcSpecialistLicenseDBModel]] doctor_wrkplace_data: Optional[list[UltmarcDoctorWrkplaceDBModel]] diff --git a/ecs/jskult-webapp/src/repositories/inst_master_repository.py b/ecs/jskult-webapp/src/repositories/inst_master_repository.py index d4b18505..4de6b732 100644 --- a/ecs/jskult-webapp/src/repositories/inst_master_repository.py +++ b/ecs/jskult-webapp/src/repositories/inst_master_repository.py @@ -1,6 +1,9 @@ +from src.logging.get_logger import get_logger from src.model.db.inst_div_master import InstDivMasterModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_施設区分取得') + class InstDivMasterRepository(BaseRepository): @@ -21,9 +24,7 @@ class InstDivMasterRepository(BaseRepository): models = [InstDivMasterModel(**r) for r in result_data] return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] getOroshiData DB Error. ") - print(f"[ERROR] ErrorMessage: {e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/prefc_master_repository.py b/ecs/jskult-webapp/src/repositories/prefc_master_repository.py index c304f59f..e83e5d78 100644 --- a/ecs/jskult-webapp/src/repositories/prefc_master_repository.py +++ b/ecs/jskult-webapp/src/repositories/prefc_master_repository.py @@ -1,6 +1,9 @@ +from src.logging.get_logger import get_logger from src.model.db.prefc_master import PrefcMasterModel from src.repositories.base_repository import BaseRepository +logger = get_logger('都道府県マスタ取得') + class PrefcMasterRepository(BaseRepository): @@ -23,9 +26,7 @@ class PrefcMasterRepository(BaseRepository): models = [PrefcMasterModel(**r) for r in result_data] return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] getOroshiData DB Error. ") - print(f"[ERROR] ErrorMessage: {e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_doctor_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_doctor_repository.py index 901078ab..03ee8271 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_doctor_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_doctor_repository.py @@ -1,11 +1,15 @@ +import mojimoji + from src.db import sql_condition as condition from src.db.sql_condition import SQLCondition +from src.logging.get_logger import get_logger from src.model.db.ultmarc_doctor import UltmarcDoctorDBModel from src.model.db.ultmarc_doctor_info import UltmarcDoctorInfoDBModel from src.model.request.ultmarc_doctor import UltmarcDoctorSearchModel from src.repositories.base_repository import BaseRepository from src.util.string_util import is_not_empty -import mojimoji + +logger = get_logger('COM_医師取得') class UltmarcDoctorRepository(BaseRepository): @@ -56,8 +60,7 @@ class UltmarcDoctorRepository(BaseRepository): return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() @@ -79,7 +82,7 @@ class UltmarcDoctorRepository(BaseRepository): if is_not_empty(parameter.dr_name_kana): # 必ず部分一致で検索 # ひらがなを全角カタカナへ変換 - zenkaku_katakana = ''.join([chr(n+96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) + zenkaku_katakana = ''.join([chr(n + 96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) for n in [ord(c) for c in parameter.dr_name_kana]]) # 全角カタカナを半角カタカナへ変換 hankaku_katakana = mojimoji.zen_to_han(zenkaku_katakana) @@ -101,7 +104,7 @@ class UltmarcDoctorRepository(BaseRepository): if is_not_empty(parameter.form_inst_name_kana): # 必ず部分一致で検索 # ひらがなを全角カタカナへ変換 - zenkaku_katakana = ''.join([chr(n+96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) + zenkaku_katakana = ''.join([chr(n + 96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) for n in [ord(c) for c in parameter.form_inst_name_kana]]) # 全角カタカナを半角カタカナへ変換 hankaku_katakana = mojimoji.zen_to_han(zenkaku_katakana) @@ -178,8 +181,7 @@ class UltmarcDoctorRepository(BaseRepository): return None return models[0] except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_his_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_his_repository.py index 1fab4d45..daa82533 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_his_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_his_repository.py @@ -1,7 +1,10 @@ +from src.logging.get_logger import get_logger from src.model.db.ultmarc_doctor_wrkplace_his import \ UltmarcDoctorWrkplaceHisDBModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_医師勤務先履歴取得') + class UltmarcDoctorWrkplaceHisRepository(BaseRepository): @@ -35,8 +38,7 @@ class UltmarcDoctorWrkplaceHisRepository(BaseRepository): return None return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_repository.py index b05ce6fd..4798c467 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_dr_wrkplace_repository.py @@ -1,8 +1,11 @@ +from src.logging.get_logger import get_logger from src.model.db.ultmarc_doctor_wrkplace import UltmarcDoctorWrkplaceDBModel from src.model.db.ultmarc_doctor_wrkplace_count import \ UltmarcDoctorWrkplaceCountDBModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_医師勤務先取得') + class UltmarcDoctorWrkplaceRepository(BaseRepository): @@ -34,8 +37,7 @@ class UltmarcDoctorWrkplaceRepository(BaseRepository): return None return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() @@ -56,8 +58,7 @@ class UltmarcDoctorWrkplaceRepository(BaseRepository): return 0 return models[0].count except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_inst_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_inst_repository.py index 2522006f..ef1cab76 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_inst_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_inst_repository.py @@ -1,11 +1,15 @@ +import mojimoji + from src.db import sql_condition as condition from src.db.sql_condition import SQLCondition +from src.logging.get_logger import get_logger from src.model.db.ultmarc_inst import UltmarcInstDBModel from src.model.db.ultmarc_inst_info import UltmarcInstInfoDBModel from src.model.request.ultmarc_inst import UltmarcInstSearchModel from src.repositories.base_repository import BaseRepository from src.util.string_util import is_not_empty -import mojimoji + +logger = get_logger('COM_施設取得') class UltmarcInstRepository(BaseRepository): @@ -43,8 +47,7 @@ class UltmarcInstRepository(BaseRepository): return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() @@ -72,7 +75,7 @@ class UltmarcInstRepository(BaseRepository): if is_not_empty(parameter.form_inst_name_kana): # 部分一致検索 # ひらがなを全角カタカナへ変換 - zenkaku_katakana = ''.join([chr(n+96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) + zenkaku_katakana = ''.join([chr(n + 96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) for n in [ord(c) for c in parameter.form_inst_name_kana]]) # 全角カタカナを半角カタカナへ変換 hankaku_katakana = mojimoji.zen_to_han(zenkaku_katakana) @@ -187,8 +190,7 @@ class UltmarcInstRepository(BaseRepository): return None return models[0] except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_inst_trt_course_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_inst_trt_course_repository.py index eaee391a..4b3c0385 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_inst_trt_course_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_inst_trt_course_repository.py @@ -1,6 +1,9 @@ +from src.logging.get_logger import get_logger from src.model.db.ultmarc_inst_trt_course import UltmarcInstTrtCourseDBModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_施設診療科目取得') + class UltmarcInstTrtCourseRepository(BaseRepository): @@ -24,8 +27,7 @@ class UltmarcInstTrtCourseRepository(BaseRepository): return None return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_sosiety_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_sosiety_repository.py index e3c9ac13..0cd55e8c 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_sosiety_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_sosiety_repository.py @@ -1,6 +1,9 @@ +from src.logging.get_logger import get_logger from src.model.db.ultmarc_sosiety import UltmarcSosietyDBModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_学会取得') + class UltmarcSosietyRepository(BaseRepository): @@ -23,8 +26,7 @@ class UltmarcSosietyRepository(BaseRepository): return None return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_specialist_license_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_specialist_license_repository.py index a4927b44..7024b616 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_specialist_license_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_specialist_license_repository.py @@ -1,7 +1,10 @@ +from src.logging.get_logger import get_logger from src.model.db.ultmarc_specialist_license import \ UltmarcSpecialistLicenseDBModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_専門医資格取得') + class UltmarcSpecialistLicenseRepository(BaseRepository): @@ -25,8 +28,7 @@ class UltmarcSpecialistLicenseRepository(BaseRepository): return None return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py index c76032a3..a5a1c9f4 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py @@ -1,8 +1,11 @@ -from src.model.db.ultmarc_trt_course import UltmarcTrtCourseDBModel +from src.logging.get_logger import get_logger +from src.model.db.ultmarc_trt_course import UltmarcDrTrtCourseDBModel from src.repositories.base_repository import BaseRepository +logger = get_logger('COM_医師診療科目取得') -class UltmarcTrtCourseRepository(BaseRepository): + +class UltmarcDrTrtCourseRepository(BaseRepository): FETCH_SQL = """\ SELECT trt_course_name @@ -13,19 +16,18 @@ class UltmarcTrtCourseRepository(BaseRepository): ORDER BY com_trt_course.trt_course_cd """ - def fetch_many(self, id) -> list[UltmarcTrtCourseDBModel]: + def fetch_many(self, id) -> list[UltmarcDrTrtCourseDBModel]: try: self._database.connect() query = self.FETCH_SQL result = self._database.execute_select(query, {'id': id}) - models = [UltmarcTrtCourseDBModel(**r) for r in result] + models = [UltmarcDrTrtCourseDBModel(**r) for r in result] if len(models) == 0: return None return models except Exception as e: - # TODO: ファイルへの書き出しはloggerでやる - print(f"[ERROR] DB Error : Exception={e.args}") + logger.exception(f"DB Error : Exception={e.args}") raise e finally: self._database.disconnect() diff --git a/ecs/jskult-webapp/src/services/ultmarc_view_service.py b/ecs/jskult-webapp/src/services/ultmarc_view_service.py index 5c441421..24cf1d75 100644 --- a/ecs/jskult-webapp/src/services/ultmarc_view_service.py +++ b/ecs/jskult-webapp/src/services/ultmarc_view_service.py @@ -23,7 +23,7 @@ from src.repositories.ultmarc_sosiety_repository import \ from src.repositories.ultmarc_specialist_license_repository import \ UltmarcSpecialistLicenseRepository from src.repositories.ultmarc_trt_course_repository import \ - UltmarcTrtCourseRepository + UltmarcDrTrtCourseRepository from src.services.base_service import BaseService @@ -33,7 +33,7 @@ class UltmarcViewService(BaseService): 'prefc_repository': PrefcMasterRepository, 'inst_div_repository': InstDivMasterRepository, 'ultmarc_inst_repository': UltmarcInstRepository, - 'ultmarc_trt_course_repository': UltmarcTrtCourseRepository, + 'ultmarc_trt_course_repository': UltmarcDrTrtCourseRepository, 'ultmarc_inst_trt_course_repository': UltmarcInstTrtCourseRepository, 'ultmarc_sosiety_repository': UltmarcSosietyRepository, 'ultmarc_doctor_wrkplace_repository': UltmarcDoctorWrkplaceRepository, @@ -45,7 +45,7 @@ class UltmarcViewService(BaseService): prefc_repository: PrefcMasterRepository inst_div_repository: InstDivMasterRepository ultmarc_inst_repository: UltmarcInstRepository - ultmarc_trt_course_repository: UltmarcTrtCourseRepository + ultmarc_trt_course_repository: UltmarcDrTrtCourseRepository ultmarc_inst_trt_course_repository: UltmarcInstTrtCourseRepository ultmarc_sosiety_repository: UltmarcSosietyRepository ultmarc_doctor_wrkplace_repository: UltmarcDoctorWrkplaceRepository From 7fa640a4c1dd61dfef37c1dda977c6ebe6929053 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Thu, 6 Jul 2023 11:42:20 +0900 Subject: [PATCH 26/28] =?UTF-8?q?style:=20=E3=82=BF=E3=83=96=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=83=87=E3=83=B3=E3=83=88=E2=86=92=E3=82=B9=E3=83=9A?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E3=82=A4=E3=83=B3=E3=83=87=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ultmarc_trt_course_repository.py | 2 +- ecs/jskult-webapp/src/static/css/bioStyle.css | 244 ++++----- .../src/static/css/masterMainte.css | 146 ++--- .../src/static/css/menuStyle.css | 44 +- ecs/jskult-webapp/src/static/css/ultStyle.css | 484 ++++++++-------- .../static/function/businessLogicScript.js | 20 +- ecs/jskult-webapp/src/templates/docInfo.html | 422 +++++++------- .../src/templates/docSearch.html | 424 +++++++------- ecs/jskult-webapp/src/templates/instInfo.html | 518 +++++++++--------- .../src/templates/instSearch.html | 388 ++++++------- 10 files changed, 1346 insertions(+), 1346 deletions(-) diff --git a/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py b/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py index a5a1c9f4..a88ffbbe 100644 --- a/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py +++ b/ecs/jskult-webapp/src/repositories/ultmarc_trt_course_repository.py @@ -11,7 +11,7 @@ class UltmarcDrTrtCourseRepository(BaseRepository): SELECT trt_course_name FROM src05.com_dr LEFT JOIN src05.com_dr_trt_course ON com_dr.dcf_pcf_dr_cd = com_dr_trt_course.dcf_pcf_dr_cd - LEFT JOIN src05.com_trt_course ON com_dr_trt_course.trt_course_cd = com_trt_course.trt_course_cd + LEFT JOIN src05.com_trt_course ON com_dr_trt_course.trt_course_cd = com_trt_course.trt_course_cd WHERE com_dr.dcf_pcf_dr_cd = :id ORDER BY com_trt_course.trt_course_cd """ diff --git a/ecs/jskult-webapp/src/static/css/bioStyle.css b/ecs/jskult-webapp/src/static/css/bioStyle.css index 26bf416e..7ecde3c5 100644 --- a/ecs/jskult-webapp/src/static/css/bioStyle.css +++ b/ecs/jskult-webapp/src/static/css/bioStyle.css @@ -5,99 +5,99 @@ } body { - white-space: nowrap; - background-color: LightCyan; - font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; + white-space: nowrap; + background-color: LightCyan; + font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; } h1 { - font-size: 155%; - margin-left: 2%; - margin-top: 0%; - margin-bottom: 0%; + font-size: 155%; + margin-left: 2%; + margin-top: 0%; + margin-bottom: 0%; } .title { - width: 800px; + width: 800px; } table{ - border-collapse : collapse; + border-collapse : collapse; } .search_table { - margin-bottom: 30px; - padding-bottom: 15px; - border-bottom: solid 1px gray; - width: 1132px; + margin-bottom: 30px; + padding-bottom: 15px; + border-bottom: solid 1px gray; + width: 1132px; } ._form { - width: 1132px; - margin-left: 10px; - margin-right: 20px; + width: 1132px; + margin-left: 10px; + margin-right: 20px; } .back_bt { - padding-bottom: 10px; + padding-bottom: 10px; } ._form input[type=text] { - width: 193px; - height: 25px; + width: 193px; + height: 25px; } ._form input[type=checkbox] { - width: 13px; - height: 13px; + width: 13px; + height: 13px; } ._form select { - width: 193px; - height: 25px; + width: 193px; + height: 25px; } .result_info { - text-align: right; + text-align: right; } .search_tb { - padding-right: 25px; + padding-right: 25px; } .search_bt { - /* width: 60px; */ - margin-left: 10px; + /* width: 60px; */ + margin-left: 10px; } .clear_bt{ - margin-left: 120px; - /* width: 60px */ + margin-left: 120px; + /* width: 60px */ } .search_dropdown { - width: 175px; + width: 175px; } .bioScroll_div { - overflow: auto; - margin-top: 1%; - height: 250px; - width: 1132px; + overflow: auto; + margin-top: 1%; + height: 250px; + width: 1132px; } .noLine{ - text-decoration: none; + text-decoration: none; } .resultAreaMsg { - margin-top: 5%; - text-align: center; - font-size: 150%; + margin-top: 5%; + text-align: center; + font-size: 150%; } .search_btTd { - text-align: right; + text-align: right; } .selection { @@ -109,70 +109,70 @@ table{ } .search_middleTd { - padding-right: 25px; - width : 450px; + padding-right: 25px; + width : 450px; } .transition{ - text-align: right; - margin-right: 60px; + text-align: right; + margin-right: 60px; } .transition_bt{ - width: 110px; - height: 40px; - margin-left: 15px; - margin-right: 15px; + width: 110px; + height: 40px; + margin-left: 15px; + margin-right: 15px; } .instutionInfo_table{ - width: 1132px; - margin-bottom: 50px; + width: 1132px; + margin-bottom: 50px; } .institution_column { - width : 160px; - background : rgb(225, 233, 250); - border : solid 1px; + width : 160px; + background : rgb(225, 233, 250); + border : solid 1px; } .institution_data { - background : rgb(244, 244, 244); - border : solid 1px; - padding-left : 0.5em; - padding-right : 0.5em; + background : rgb(244, 244, 244); + border : solid 1px; + padding-left : 0.5em; + padding-right : 0.5em; } .data_width_long { - width : 500px; + width : 500px; } .data_width_middle { - width : 300px; + width : 300px; } .data_width_short { - width : 100px; + width : 100px; } .checkbox_margin { - margin-left : 20px; + margin-left : 20px; } .border_top_none { - border-top-style:none; + border-top-style:none; } .border_bottom_none { - border-bottom-style:none; + border-bottom-style:none; } .textbox_margin { - margin-left : 20px; + margin-left : 20px; } .textbox_margin_short { - margin-left : 5px; + margin-left : 5px; } .label_margin { @@ -181,110 +181,110 @@ table{ } .trt_course{ - width: 70px; + width: 70px; } .small_tb{ - width: 100px; + width: 100px; } .docBelongScroll_div { - overflow: auto; - height: 100px; - width: 500px; - margin: 0px 30px 0px 30px; + overflow: auto; + height: 100px; + width: 500px; + margin: 0px 30px 0px 30px; } .rightPadding_table{ - padding-right: 50px; + padding-right: 50px; } .verticalBar_td{ - width: 1px; - height: 150px; - background-color: gray; + width: 1px; + height: 150px; + background-color: gray; } .docPlaceScroll_div { - overflow: auto; - height: 150px; - width: 700px; - margin: 0px 30px 0px 30px; + overflow: auto; + height: 150px; + width: 700px; + margin: 0px 30px 0px 30px; } .result_tr{ - overflow-y: scroll; - overflow-x: scroll; + overflow-y: scroll; + overflow-x: scroll; } .result_data{ - overflow-y: scroll; - overflow-x: scroll; - width: 50px; + overflow-y: scroll; + overflow-x: scroll; + width: 50px; } /* tablesoter */ table.tablesorter { - font-family:arial; - background-color: #CDCDCD; - font-size: 12pt; - text-align: left; + font-family:arial; + background-color: #CDCDCD; + font-size: 12pt; + text-align: left; } table.tablesorter thead tr th, table.tablesorter tfoot tr th { - background-color: #e6EEEE; - border: 0.1px solid silver; - font-size: 12pt; - padding: 4px; - padding-right: 20px; + background-color: #e6EEEE; + border: 0.1px solid silver; + font-size: 12pt; + padding: 4px; + padding-right: 20px; } table.tablesorter thead tr .header { - background-image: url(bg.gif); - background-repeat: no-repeat; - background-position: center right; - cursor: pointer; + background-image: url(bg.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; } table.tablesorter tbody td { - color: #3D3D3D; - padding: 4px; - background-color: #FFF; - border: 0.1px solid silver; - vertical-align: top; + color: #3D3D3D; + padding: 4px; + background-color: #FFF; + border: 0.1px solid silver; + vertical-align: top; } table.tablesorter tbody td div{ - float: right; + float: right; } table.tablesorter tbody tr.odd td { - background-color:#F0F0F6; + background-color:#F0F0F6; } table.tablesorter thead tr .headerSortUp { - background-image: url(asc.gif); + background-image: url(asc.gif); } table.tablesorter thead tr .headerSortDown { - background-image: url(desc.gif); + background-image: url(desc.gif); } table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp { - background-color: #8dbdd8; + background-color: #8dbdd8; } #loading { - z-index: 10000; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: #FFF; - overflow-x: hidden; - overflow-y: auto; - outline: 0; - text-align: center; - display: none; - opacity: 0.7; + z-index: 10000; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #FFF; + overflow-x: hidden; + overflow-y: auto; + outline: 0; + text-align: center; + display: none; + opacity: 0.7; } #loading_content { - position: absolute; - top: 50%; - left: 50%; + position: absolute; + top: 50%; + left: 50%; } \ No newline at end of file diff --git a/ecs/jskult-webapp/src/static/css/masterMainte.css b/ecs/jskult-webapp/src/static/css/masterMainte.css index a59c1681..3c15e03d 100644 --- a/ecs/jskult-webapp/src/static/css/masterMainte.css +++ b/ecs/jskult-webapp/src/static/css/masterMainte.css @@ -1,153 +1,153 @@ body{ - background-color: LightCyan; - font-family : "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; + background-color: LightCyan; + font-family : "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; } h1{ - margin-left : 1%; + margin-left : 1%; } /*ヘッダー*/ .headerTable{ - width: 100%; + width: 100%; } .headerTdLeft{ - width: 80%; + width: 80%; } .headerTdRight{ - text-align: right; - padding-right: 2%; - width: 20%; + text-align: right; + padding-right: 2%; + width: 20%; } .buttonSize{ - width: 85px; + width: 85px; } /*////////////////////////*/ /*施設担当者データCSVダウンロード*/ /*////////////////////////*/ .searchColumnTd{ - width: 14%; + width: 14%; } .searchTextboxTd{ - width: 18%; + width: 18%; } .searchTable{ - margin-left: 3%; - margin-right: 3%; - margin-bottom: 1%; - padding-bottom: 1%; - border-bottom: solid 1px gray; - width: 94%; + margin-left: 3%; + margin-right: 3%; + margin-bottom: 1%; + padding-bottom: 1%; + border-bottom: solid 1px gray; + width: 94%; } .searchLabelTd{ - text-align: right; - width: 10%; + text-align: right; + width: 10%; } .searchInputTd{ - width: 19%; + width: 19%; } .searchTextbox{ - width: 90%; - margin-left: 2.5%; - margin-right: 2.5%; - margin-top: 0.8%; - margin-bottom: 0.8%; + width: 90%; + margin-left: 2.5%; + margin-right: 2.5%; + margin-top: 0.8%; + margin-bottom: 0.8%; } .searchDateTextbox{ - width: 37%; - margin-left: 2.5%; - margin-right: 2.5%; - margin-top: 0.8%; - margin-bottom: 0.8%; + width: 37%; + margin-left: 2.5%; + margin-right: 2.5%; + margin-top: 0.8%; + margin-bottom: 0.8%; } .searchButtonTd{ - text-align: right; - padding-top: 1%; + text-align: right; + padding-top: 1%; } .csvOutputMessage{ - margin-left: 3%; + margin-left: 3%; } .errorColor{ - color: red; + color: red; } /*//////////////////////////*/ /*施設担当者データExcelアップロード*/ /*//////////////////////////*/ .inputTable{ - margin-left: 3%; - margin-right: 3%; - margin-bottom: 1%; - padding-bottom: 1%; - border-bottom: solid 1px gray; - width: 94%; + margin-left: 3%; + margin-right: 3%; + margin-bottom: 1%; + padding-bottom: 1%; + border-bottom: solid 1px gray; + width: 94%; } .inputLabelTd{ - width: 10%; + width: 10%; } .inputTd{ - width:20%; + width:20%; } .inputButtonTd{ - width: 50%; - text-align: right; + width: 50%; + text-align: right; } .dataCntDisp{ - text-align: right; - margin-right: 3%; + text-align: right; + margin-right: 3%; } table.inputData { - font-family:arial; - background-color: #CDCDCD; - font-size: 12pt; - text-align: left; - white-space: nowrap; - border: 0.1px solid silver; - padding: 4px; - padding-right: 20px; - border-collapse: collapse; - margin-left: 3%; - width: 94%; + font-family:arial; + background-color: #CDCDCD; + font-size: 12pt; + text-align: left; + white-space: nowrap; + border: 0.1px solid silver; + padding: 4px; + padding-right: 20px; + border-collapse: collapse; + margin-left: 3%; + width: 94%; } table.inputData tbody th { - color: #3D3D3D; - padding: 4px; - background-color: #e6EEEE; - border: 0.1px solid silver; - vertical-align: top; + color: #3D3D3D; + padding: 4px; + background-color: #e6EEEE; + border: 0.1px solid silver; + vertical-align: top; } table.inputData tbody td { - color: #3D3D3D; - padding: 4px; - background-color: #FFF; - border: 0.1px solid silver; - vertical-align: top; + color: #3D3D3D; + padding: 4px; + background-color: #FFF; + border: 0.1px solid silver; + vertical-align: top; } .footerMsg{ - margin-left: 3%; + margin-left: 3%; } @@ -155,10 +155,10 @@ table.inputData tbody td { /*データ上書きコピー */ /*//////////////////////////*/ .tableOverRide{ - margin-right: 3%; - margin-left: 3%; - margin-bottom: 2%; - border-bottom: solid 1px gray; - width: 94%; + margin-right: 3%; + margin-left: 3%; + margin-bottom: 2%; + border-bottom: solid 1px gray; + width: 94%; } diff --git a/ecs/jskult-webapp/src/static/css/menuStyle.css b/ecs/jskult-webapp/src/static/css/menuStyle.css index 3a07d9fc..cabd5197 100644 --- a/ecs/jskult-webapp/src/static/css/menuStyle.css +++ b/ecs/jskult-webapp/src/static/css/menuStyle.css @@ -1,49 +1,49 @@ body{ - background-color: LightCyan; - background-size: 220%,220%; - font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; + background-color: LightCyan; + background-size: 220%,220%; + font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; } .background{ - margin-top: 5%; - padding: 2%; - background-color: white; - width: 40%; - border-radius: 25px; - box-shadow:5px 5px rgba(0,0,0,0.4);; + margin-top: 5%; + padding: 2%; + background-color: white; + width: 40%; + border-radius: 25px; + box-shadow:5px 5px rgba(0,0,0,0.4);; } .btn_width { - width: 80%; + width: 80%; } .form_login{ - width: 80%; - font-size: 180%; - margin: 1%; + width: 80%; + font-size: 180%; + margin: 1%; } .form_login::-webkit-input-placeholder{ - color: gray; + color: gray; } .form_login:-ms-input-placeholder{ - color: gray; + color: gray; } .form_login::-moz-placeholder{ - color: gray; + color: gray; } .logout_p{ - font-size: 160%; + font-size: 160%; } .notUseBioMsg,.notUseMainteMsg{ - font-size: 143%; - color: red; + font-size: 143%; + color: red; } .batchMsg{ - color: red; - font-size: 120%; - text-align: center; + color: red; + font-size: 120%; + text-align: center; } \ No newline at end of file diff --git a/ecs/jskult-webapp/src/static/css/ultStyle.css b/ecs/jskult-webapp/src/static/css/ultStyle.css index af29f38a..f5eea0e0 100644 --- a/ecs/jskult-webapp/src/static/css/ultStyle.css +++ b/ecs/jskult-webapp/src/static/css/ultStyle.css @@ -5,480 +5,480 @@ } body { - background-color: LightCyan; - font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; + background-color: LightCyan; + font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif; } h1 { - font-size: 150%; - margin-left: 2%; - margin-top: 0%; - margin-bottom: 0%; + font-size: 150%; + margin-left: 2%; + margin-top: 0%; + margin-bottom: 0%; } table{ - border-collapse : collapse; + border-collapse : collapse; } .header_bt{ - width: 8%; - margin-bottom: 0.8%; - margin-left: 78.5%; + width: 8%; + margin-bottom: 0.8%; + margin-left: 78.5%; } .search_textbox{ - width: 100%; + width: 100%; } .search_dropdown{ - width: 100%; - height: 1.8em; + width: 100%; + height: 1.8em; } .search_longtextbox{ - width: 100% + width: 100% } .instSearchResult { - width: 100%; + width: 100%; } .scroll_table{ - overflow: auto; - white-space: nowrap; - margin-top: 1%; - margin-bottom: 1%; - width: 100%; - height: 250px; + overflow: auto; + white-space: nowrap; + margin-top: 1%; + margin-bottom: 1%; + width: 100%; + height: 250px; } .scroll_table::-webkit-scrollbar { - height: 5px; - width: 10px; + height: 5px; + width: 10px; } .scroll_table::-webkit-scrollbar-track { - border-radius: 5px; - background: #eee; + border-radius: 5px; + background: #eee; } .scroll_table::-webkit-scrollbar-thumb { - border-radius: 5px; - background: #666; + border-radius: 5px; + background: #666; } .ult_bt { - width: 20%; - height: 80%; + width: 20%; + height: 80%; } .info_bt{ - width: 10% + width: 10% } .search_bt{ - margin-left: 3%; - margin-top: 0.8%; - margin-bottom: 0.8%; + margin-left: 3%; + margin-top: 0.8%; + margin-bottom: 0.8%; } .notFind{ - margin-top: 5%; - text-align: center; - font-size: 150%; + margin-top: 5%; + text-align: center; + font-size: 150%; } .search_table { - margin-bottom: 1%; - padding-bottom: 1%; - border-bottom: solid 1px gray; - width: 100%; + margin-bottom: 1%; + padding-bottom: 1%; + border-bottom: solid 1px gray; + width: 100%; } .search_tb { - padding-right: 2%; - padding-top: 0.2%; - padding-bottom: 0.2%; + padding-right: 2%; + padding-top: 0.2%; + padding-bottom: 0.2%; } .leftSearch_tb{ - width: 35%; + width: 35%; } .batchMsg{ - color: red; - font-size: 120%; - text-align: center; + color: red; + font-size: 120%; + text-align: center; } ._form { - width: 95%; - margin-left: 3%; + width: 95%; + margin-left: 3%; } .result_info { - text-align: right; + text-align: right; } /*施設検索一覧ヘッダー*/ .instSearchHeaderTable{ - width: 100%; + width: 100%; } .instSearchHeaderTd{ - width: 24%; + width: 24%; } .instSearchHeaderTdCenter{ - text-align: center; - width: 50%; + text-align: center; + width: 50%; } .instSearchHeaderTdRight{ - text-align: right; - padding-right: 2%; + text-align: right; + padding-right: 2%; } .instSearchButchMsg{ - /* font-size: 80%; */ - color: red; + /* font-size: 80%; */ + color: red; } .instSearchHeader_bt{ - width: 40%; + width: 40%; } /*施設詳細*/ .instInfoTable{ - margin-top: 1%; - margin-left: 5%; - margin-right: 2%; - margin-bottom: 2%; - width: 93%; + margin-top: 1%; + margin-left: 5%; + margin-right: 2%; + margin-bottom: 2%; + width: 93%; } .instInfoTableHalf1{ - margin-top: 1%; - margin-left: 5%; - margin-right: 2%; - width: 93%; + margin-top: 1%; + margin-left: 5%; + margin-right: 2%; + width: 93%; } .instInfoTableHalf2{ - margin-top: -0.05%; - margin-left: 5%; - margin-right: 2%; - margin-bottom: 2%; - width: 93%; + margin-top: -0.05%; + margin-left: 5%; + margin-right: 2%; + margin-bottom: 2%; + width: 93%; } .instInfoColumn { - width : 9%; - height: 40px; - background : rgb(225, 233, 250); - border : solid 1px; + width : 9%; + height: 40px; + background : rgb(225, 233, 250); + border : solid 1px; } .instData { - background : rgb(244, 244, 244); - border : solid 1px; - padding-left : 0.5%; - padding-right : 0.5%; - padding-top: 0.25%; - padding-bottom: 0.25%; + background : rgb(244, 244, 244); + border : solid 1px; + padding-left : 0.5%; + padding-right : 0.5%; + padding-top: 0.25%; + padding-bottom: 0.25%; } .instDataMid{ - /*NO5修正前 width: 51%;*/ - width: 20%; + /*NO5修正前 width: 51%;*/ + width: 20%; } /*NO5にて追加 START*/ .instDataLarge{ - width: 85%; + width: 85%; } .instDataLeft{ - width: 20%; + width: 20%; } .instDataCenter{ - width: 7%; + width: 7%; } .instDataRight{ - width: 25%; + width: 25%; } /*NO5にて追加 END*/ .instDataSmallTextbox{ - width: 45%; + width: 45%; } /*NO5にて追加 START*/ .instDataCenterTextbox{ - width: 80%; + width: 80%; } /*NO5にて追加 END*/ .instInfoTextbox{ - width: 98%; - padding-right: 1%; - padding-left: 1%; + width: 98%; + padding-right: 1%; + padding-left: 1%; } .instCdTextbox{ - /*NO5修正前 width: 13%;*/ - width: 35%; - margin-left: 0.5%; - margin-right: 2%; + /*NO5修正前 width: 13%;*/ + width: 35%; + margin-left: 0.5%; + margin-right: 2%; } .delReasonCdTextbox{ - /*NO5修正前 width: 2%;*/ - width: 5%; - margin-left: 0.5%; - margin-right: 1%; + /*NO5修正前 width: 2%;*/ + width: 5%; + margin-left: 0.5%; + margin-right: 1%; } .delReasonTextbox{ - /*NO5修正前 width: 43%;*/ - width: 88%; - margin-left: 0.5%; - margin-right: 2%; + /*NO5修正前 width: 43%;*/ + width: 88%; + margin-left: 0.5%; + margin-right: 2%; } .manageTextbox{ - width: 40%; + width: 40%; } .textboxMargin { - margin-left : 0.1%; + margin-left : 0.1%; } .transitionBt{ - width: 98%; - height: 30px; + width: 98%; + height: 30px; } .instHeaderTable{ - margin-left: 40%; + margin-left: 40%; } .instHeaderTd{ - width: 10%; - font-size: 140%; - text-align: center; - padding-right: 2%; + width: 10%; + font-size: 140%; + text-align: center; + padding-right: 2%; } .trtCourseTextbox{ - width: 6%; + width: 6%; } .bedTd{ - width: 46%; + width: 46%; } .bedTextbox{ - width: 70%; + width: 70%; } .xSmallTd{ - width: 9%; + width: 9%; } .xSmallTextbox{ - width: 75%; + width: 75%; } .reExamTd{ - width: 13%; + width: 13%; } .repreTd{ - width: 50%; + width: 50%; } .repreTextbox{ - width: 95%; + width: 95%; } .trtTextbox{ - width: 5%; - margin-right: 1.2%; + width: 5%; + margin-right: 1.2%; } .parentCdTextBox{ - width: 15%; + width: 15%; } .parentNameTextBox{ - width: 75%; + width: 75%; } .hpInfoColumn{ - width : 12%; - height: 40px; - background : rgb(225, 233, 250); - border : solid 1px; + width : 12%; + height: 40px; + background : rgb(225, 233, 250); + border : solid 1px; } .hpAssrtTd{ - width: 12%; + width: 12%; } .hpAssrtTextbox{ - width: 85%; + width: 85%; } .border_bottom_none { - border-bottom-style:none; + border-bottom-style:none; } .numberBox{ - text-align: right; + text-align: right; } /*医師検索*/ /*ヘッダー*/ .docHeaderTable{ - width: 100%; + width: 100%; } .docHeaderTd{ - width: 24%; + width: 24%; } .docHeaderTdCenter{ - text-align: center; - width: 50%; + text-align: center; + width: 50%; } .docHeaderTdRight{ - text-align: right; - padding-right: 2%; + text-align: right; + padding-right: 2%; } .docButchMsg{ - /* font-size: 80%; */ - color: red; + /* font-size: 80%; */ + color: red; } .docHeader_bt{ - width: 40%; + width: 40%; } /* アルトマーク課題管理表No.2の修正 8% → 10% */ /* アルトマーク課題管理表No.8の修正 10% → 14% */ .docSearchColumnTd{ - width: 14%; + width: 14%; } .docSearchTextboxTd{ - width: 18%; + width: 18%; } .docSearchTextbox_td{ - width: 94%; + width: 94%; } .docSearchTextbox{ - width: 90%; - margin-right: 5%; - margin-top: 0.8%; - margin-bottom: 0.8%; + width: 90%; + margin-right: 5%; + margin-top: 0.8%; + margin-bottom: 0.8%; } .docSearchTableDivOne{ - width: 100%; + width: 100%; } .docSearchTableDivTwo{ - margin-bottom: 1%; - padding-bottom: 1%; - border-bottom: solid 1px gray; - width: 100%; + margin-bottom: 1%; + padding-bottom: 1%; + border-bottom: solid 1px gray; + width: 100%; } .allOnOffButton{ - width: 6%; + width: 6%; } /*医師情報*/ .docInfoTable{ - margin-top: 1%; - margin-left: 5%; - margin-right: 2%; - margin-bottom: 1%; - width: 93%; - border-bottom: solid 1px gray; + margin-top: 1%; + margin-left: 5%; + margin-right: 2%; + margin-bottom: 1%; + width: 93%; + border-bottom: solid 1px gray; } .docInfoTd{ - padding-bottom: 0.5%; + padding-bottom: 0.5%; } .docInfoTextBox{ - margin-left: 0.5%; - margin-right: 2%; - width: 8%; + margin-left: 0.5%; + margin-right: 2%; + width: 8%; } .docInfoTrtTextBox{ - margin-left: 0.5%; + margin-left: 0.5%; } .docBelongTable{ - margin-left: 1%; - width: 98%; - border-bottom: solid 1px gray; + margin-left: 1%; + width: 98%; + border-bottom: solid 1px gray; } .docBelongTd{ - width: 49%; - height: 150px; + width: 49%; + height: 150px; } .docSocietyTable{ - width: 100%; + width: 100%; } .scroll{ - overflow: auto; - height: 120px; - width: 90%; - margin-left: 7%; - margin-bottom: 4%; + overflow: auto; + height: 120px; + width: 90%; + margin-left: 7%; + margin-bottom: 4%; } .scroll::-webkit-scrollbar { - height: 5px; - width: 10px; + height: 5px; + width: 10px; } .scroll::-webkit-scrollbar-track { - border-radius: 5px; - background: #eee; + border-radius: 5px; + background: #eee; } .scroll::-webkit-scrollbar-thumb { - border-radius: 5px; - background: #666; + border-radius: 5px; + background: #666; } .rightBoderLine{ - border-right: solid 1px gray; + border-right: solid 1px gray; } .wrkplaceH1{ - margin-top: 0.3%; + margin-top: 0.3%; } .wrkplaceTable{ - width: 100%; + width: 100%; } @@ -492,17 +492,17 @@ table{ .clear_bt{ - margin-left: 120px; - width: 60px + margin-left: 120px; + width: 60px } .back_bt{ - margin-left: 1042px; - width: 80px + margin-left: 1042px; + width: 80px } .noLine{ - text-decoration: none; + text-decoration: none; } @@ -511,13 +511,13 @@ table{ /*共通:アルトマーク施設検索,医師検索,施設詳細*/ .maxWidth_tb { - width: 100%; + width: 100%; } /*アルトマーク施設検索,医師検索共通*/ .search_btTd { - text-align: right; + text-align: right; } .selection { @@ -531,14 +531,14 @@ table{ /*医師検索*/ .search_middleTd { - padding-right: 25px; - width : 450px; + padding-right: 25px; + width : 450px; } /*共通:施設詳細、医師詳細*/ .transition{ - text-align: right; - margin-right: 60px; + text-align: right; + margin-right: 60px; } @@ -546,18 +546,18 @@ table{ .data_width_middle { - width : 300px; + width : 300px; } .border_top_none { - border-top-style:none; + border-top-style:none; } .textbox_margin_short { - margin-left : 5px; + margin-left : 5px; } .label_margin { @@ -568,82 +568,82 @@ table{ /*医師詳細*/ .docInfo_table{ - margin-bottom: 30px; - border-bottom: solid 1px gray; - width: 1132px; + margin-bottom: 30px; + border-bottom: solid 1px gray; + width: 1132px; } .small_tb{ - width: 100px; + width: 100px; } .docBelongScroll_div { - overflow: auto; - height: 100px; - width: 500px; - margin: 0px 30px 0px 30px; + overflow: auto; + height: 100px; + width: 500px; + margin: 0px 30px 0px 30px; } .rightPadding_table{ - padding-right: 50px; + padding-right: 50px; } .docPlaceScroll_div { - overflow: auto; - height: 150px; - width: 700px; - margin: 0px 30px 0px 30px; + overflow: auto; + height: 150px; + width: 700px; + margin: 0px 30px 0px 30px; } .result_tr{ - overflow-y: scroll; - overflow-x: scroll; + overflow-y: scroll; + overflow-x: scroll; } .result_data{ - overflow-y: scroll; - overflow-x: scroll; - width: 50px; + overflow-y: scroll; + overflow-x: scroll; + width: 50px; } /* tablesoter */ table.tablesorter { - font-family:arial; - background-color: #CDCDCD; - font-size: 12pt; - text-align: left; + font-family:arial; + background-color: #CDCDCD; + font-size: 12pt; + text-align: left; } table.tablesorter thead tr th, table.tablesorter tfoot tr th { - background-color: #e6EEEE; - border: 0.1px solid silver; - font-size: 12pt; - padding: 4px; - padding-right: 20px; + background-color: #e6EEEE; + border: 0.1px solid silver; + font-size: 12pt; + padding: 4px; + padding-right: 20px; } table.tablesorter thead tr .header { - background-image: url(bg.gif); - background-repeat: no-repeat; - background-position: center right; - cursor: pointer; + background-image: url(bg.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; } table.tablesorter tbody td { - color: #3D3D3D; - padding: 4px; - background-color: #FFF; - border: 0.1px solid silver; - vertical-align: top; + color: #3D3D3D; + padding: 4px; + background-color: #FFF; + border: 0.1px solid silver; + vertical-align: top; } table.tablesorter tbody tr.odd td { - background-color:#F0F0F6; + background-color:#F0F0F6; } table.tablesorter thead tr .headerSortUp { - background-image: url(asc.gif); + background-image: url(asc.gif); } table.tablesorter thead tr .headerSortDown { - background-image: url(desc.gif); + background-image: url(desc.gif); } table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp { - background-color: #8dbdd8; + background-color: #8dbdd8; } diff --git a/ecs/jskult-webapp/src/static/function/businessLogicScript.js b/ecs/jskult-webapp/src/static/function/businessLogicScript.js index f410d5ab..7ce3b9ba 100644 --- a/ecs/jskult-webapp/src/static/function/businessLogicScript.js +++ b/ecs/jskult-webapp/src/static/function/businessLogicScript.js @@ -96,7 +96,7 @@ function enableDatePicker() { // 日付入力チェック // 引数:チェックするテキストボックスNo function autoModifyDate($this){ - // 日付フォーマットチェック + // 日付フォーマットチェック if($this.value === "" || (!$this.value.match(/^\d{4}\/\d{2}\/\d{2}$/) && !$this.value.match(/^\d{4}\d{2}\d{2}$/))) @@ -110,22 +110,22 @@ function autoModifyDate($this){ // yyyyMMddの場合→yyyy/MM/dd const datePatternMatches = strFormat.match(/^(\d{4})(\d{2})(\d{2})$/); if (datePatternMatches){ - strFormat = `${datePatternMatches[1]}/${datePatternMatches[2]}/${datePatternMatches[3]}`; + strFormat = `${datePatternMatches[1]}/${datePatternMatches[2]}/${datePatternMatches[3]}`; } // yyyy/00/00~yyyy/00/00の場合→yyyy/01/01~yyyy/12/31 // yyyy/MM/00~yyyy/MM/01の場合→yyyy/MM/01~yyyy/MM/末日 - // 開始日の場合 - if ($this.name.includes('from')){ + // 開始日の場合 + if ($this.name.includes('from')){ strFormat = strFormat.replace("00/00", "01/01"); strFormat = strFormat.replace("00", "01"); } // 終了日の場合 - else if ($this.name.includes('to')){ + else if ($this.name.includes('to')){ strFormat = strFormat.replace("00/00", "12/31"); const date = new Date(strFormat.slice(0, 4), strFormat.slice(5, 7), 0).getDate(); strFormat = strFormat.replace("00", date.toString()); } - $this.value = strFormat; + $this.value = strFormat; } @@ -168,14 +168,14 @@ function checkPassForm($this) // 条件:チェックボックスのクラス名に"selected"というのがついていること // 条件:ボタンにクラス名 send がついていること function allOn(){ - $(".selected").prop("checked", true); - $(".send").prop('disabled',false); + $(".selected").prop("checked", true); + $(".send").prop('disabled',false); } // チェックボックス全解除関数 // 条件:チェックボックスのクラス名に"selectedページ数"というのがついていること // 条件:ボタンにクラス名 send がついていること function allOff(){ - $(".selected").prop("checked", false); - $(".send").prop('disabled',true); + $(".selected").prop("checked", false); + $(".send").prop('disabled',true); } diff --git a/ecs/jskult-webapp/src/templates/docInfo.html b/ecs/jskult-webapp/src/templates/docInfo.html index 8f9beb21..71b82b75 100644 --- a/ecs/jskult-webapp/src/templates/docInfo.html +++ b/ecs/jskult-webapp/src/templates/docInfo.html @@ -4,228 +4,228 @@ {% with subtitle = ultmarc.subtitle %} {% include '_header.html' %} {% endwith %} - 医師情報 - - - + } + + -
- - - - - -

{{ultmarc.subtitle}}

- {% if ultmarc.is_batch_processing %} -
日次バッチ処理中のため、データが正しく表示されない可能性があります
- {% endif %} -
+ + + + + + +

{{ultmarc.subtitle}}

+ {% if ultmarc.is_batch_processing %} +
日次バッチ処理中のため、データが正しく表示されない可能性があります
+ {% endif %} +
- - - - - - - - - - - - - - - -
- - - {{ultmarc.is_page_num_view()}}/{{ultmarc.post_cnt}} - - -
- -
+ + + + + + + - - - - - - - - - - - - - - - - - - - +
医師コード:氏名(漢字):氏名(カナ):
性別:生年月日:
- 出身大学: - - 出身県: - - 卒年: - - 登録年: - - 開業年: - -
+ + + + + + + + + + + + + + + + + + - - - - -
医師コード:氏名(漢字):氏名(カナ):
性別:生年月日:
+ 出身大学: + + 出身県: + + 卒年: + + 登録年: + + 開業年: + +
- 診療科目: - {% for trt_coursed_data in ultmarc.trt_coursed_data %} - - {% endfor %} - {% for i in range(5-ultmarc.is_input_trt_course_data_size())%} - - {% endfor %} -
- - - - - - - - -
-

所属学会

-
- - - - - - - - - {% for sosiety_data in ultmarc.sosiety_data %} - - - - - {% endfor %} - -
コード所属学会
{{sosiety_data.sosiety_cd or ' '}}{{sosiety_data.sosiety_name or ' '}}
-
-
-

所属学会専門医

-
- - - - - - - - - {% for specialist_license_data in ultmarc.specialist_license_data %} - - - - - {% endfor %} - -
コード専門医資格名
{{specialist_license_data.specialist_cd or ' '}}{{specialist_license_data.specialist_license_name or ' '}}
-
-
- -

勤務先履歴

-
- - - - - - - - - - - - - - - {% for doctor_wrkplace_data in ultmarc.doctor_wrkplace_data %} - {% if doctor_wrkplace_data.dcf_dsf_inst_cd %} - - - - - - - - - - {% endif %} - {% endfor %} - {% for doctor_wrkplace_his_data in ultmarc.doctor_wrkplace_his_data %} - {% if doctor_wrkplace_his_data.dcf_dsf_inst_cd %} - - - - - - - - - - {% endif %} - {% endfor %} - -
ULT施設コード勤務先略名所属部科名役職名職位開始年月日終了年月日
- {{doctor_wrkplace_data.dcf_dsf_inst_cd or ''}}{{doctor_wrkplace_data.inst_name_kanji or ''}}{{doctor_wrkplace_data.blng_sec_name or ''}}{{doctor_wrkplace_data.univ_post_name or ''}}{{doctor_wrkplace_data.post_name or ''}}{{ultmarc.is_input_aply_start_ymd_format(doctor_wrkplace_data.aply_start_ymd)}}9999/99/99
- {{doctor_wrkplace_his_data.dcf_dsf_inst_cd or ''}}{{doctor_wrkplace_his_data.inst_name_kanji or ''}}{{doctor_wrkplace_his_data.blng_sec_name or ''}}{{doctor_wrkplace_his_data.univ_post_name or ''}}{{doctor_wrkplace_his_data.post_name or ''}}{{ultmarc.is_input_his_aply_start_ymd_format(doctor_wrkplace_his_data.aply_start_ymd)}}{{ultmarc.is_input_his_aply_end_ymd_format(doctor_wrkplace_his_data.aply_end_ymd)}}
-
+ + + 診療科目: + {% for trt_coursed_data in ultmarc.trt_coursed_data %} + + {% endfor %} + {% for i in range(5-ultmarc.is_input_trt_course_data_size())%} + + {% endfor %} + + + + + + + + + + + + +
+

所属学会

+
+ + + + + + + + + {% for sosiety_data in ultmarc.sosiety_data %} + + + + + {% endfor %} + +
コード所属学会
{{sosiety_data.sosiety_cd or ' '}}{{sosiety_data.sosiety_name or ' '}}
+
+
+

所属学会専門医

+
+ + + + + + + + + {% for specialist_license_data in ultmarc.specialist_license_data %} + + + + + {% endfor %} + +
コード専門医資格名
{{specialist_license_data.specialist_cd or ' '}}{{specialist_license_data.specialist_license_name or ' '}}
+
+
+ +

勤務先履歴

+
+ + + + + + + + + + + + + + + {% for doctor_wrkplace_data in ultmarc.doctor_wrkplace_data %} + {% if doctor_wrkplace_data.dcf_dsf_inst_cd %} + + + + + + + + + + {% endif %} + {% endfor %} + {% for doctor_wrkplace_his_data in ultmarc.doctor_wrkplace_his_data %} + {% if doctor_wrkplace_his_data.dcf_dsf_inst_cd %} + + + + + + + + + + {% endif %} + {% endfor %} + +
ULT施設コード勤務先略名所属部科名役職名職位開始年月日終了年月日
+ {{doctor_wrkplace_data.dcf_dsf_inst_cd or ''}}{{doctor_wrkplace_data.inst_name_kanji or ''}}{{doctor_wrkplace_data.blng_sec_name or ''}}{{doctor_wrkplace_data.univ_post_name or ''}}{{doctor_wrkplace_data.post_name or ''}}{{ultmarc.is_input_aply_start_ymd_format(doctor_wrkplace_data.aply_start_ymd)}}9999/99/99
+ {{doctor_wrkplace_his_data.dcf_dsf_inst_cd or ''}}{{doctor_wrkplace_his_data.inst_name_kanji or ''}}{{doctor_wrkplace_his_data.blng_sec_name or ''}}{{doctor_wrkplace_his_data.univ_post_name or ''}}{{doctor_wrkplace_his_data.post_name or ''}}{{ultmarc.is_input_his_aply_start_ymd_format(doctor_wrkplace_his_data.aply_start_ymd)}}{{ultmarc.is_input_his_aply_end_ymd_format(doctor_wrkplace_his_data.aply_end_ymd)}}
+
\ No newline at end of file diff --git a/ecs/jskult-webapp/src/templates/docSearch.html b/ecs/jskult-webapp/src/templates/docSearch.html index 21da4a9c..7f6cc551 100644 --- a/ecs/jskult-webapp/src/templates/docSearch.html +++ b/ecs/jskult-webapp/src/templates/docSearch.html @@ -6,191 +6,191 @@ {% endwith %} - + // Enter押下時にsubmitさせなくする + $(function() { + $(document).on("keypress", "input:not(.allow_submit)", function(event) { + return event.which !== 13; + }); + }); + } + - - - - - - -

{{ultmarc.subtitle}}

- {% if ultmarc.is_batch_processing %} -
日次バッチ処理中のため、データが正しく表示されない可能性があります
- {% endif %} -
-
+ + + - \ No newline at end of file diff --git a/ecs/jskult-webapp/src/templates/instInfo.html b/ecs/jskult-webapp/src/templates/instInfo.html index d93b619c..00f8e9ab 100644 --- a/ecs/jskult-webapp/src/templates/instInfo.html +++ b/ecs/jskult-webapp/src/templates/instInfo.html @@ -6,282 +6,282 @@ {% endwith %} - - + } + + -

+

{{ultmarc.subtitle}}

- {% if ultmarc.is_batch_processing %} -
日次バッチ処理中のため、データが正しく表示されない可能性があります
- {% endif %} + {% if ultmarc.is_batch_processing %} +
日次バッチ処理中のため、データが正しく表示されない可能性があります
+ {% endif %} - - - - - - - - - - - - - - - + - - - - -
- - -
- - - {{ultmarc.is_page_num_view()}}/{{ultmarc.post_cnt}} - - -
- -
+ + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
施設コード - - 未確認 - 施設コード変換先 - - 休院店開始年月 - - 休院店 -
削除予定理由 - - 削除日 - - 開業予定年月 - - 開業 -
正式施設名(カナ)
正式施設名(漢字)
略式施設名(カナ)施設区分名
略式施設名(漢字)経営体 - - -
郵便番号 - - 住所不明 - 施設電話番号 - - 電話なし -
住所(カナ)
住所(漢字)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
施設コード + + 未確認 + 施設コード変換先 + + 休院店開始年月 + + 休院店 +
削除予定理由 + + 削除日 + + 開業予定年月 + + 開業 +
正式施設名(カナ)
正式施設名(漢字)
略式施設名(カナ)施設区分名
略式施設名(漢字)経営体 + + +
郵便番号 + + 住所不明 + 施設電話番号 + + 電話なし +
住所(カナ)
住所(漢字)

- - - - - - - - - - - - + + + + + + +
病院種別再審査区分関連大学親名 - - -
診療科目 - {% if ultmarc.inst_trt_coursed_data != None %} - {% for inst_trt_course_data in ultmarc.inst_trt_coursed_data %} - - {% endfor %} - {% endif %} - {% for i in range(60-ultmarc.is_input_inst_trt_course_data_size()) %} - - {% endfor %} + + + + + + + + + + + + - - - - - - -
病院種別再審査区分関連大学親名 + + +
診療科目 + {% if ultmarc.inst_trt_coursed_data != None %} + {% for inst_trt_course_data in ultmarc.inst_trt_coursed_data %} + + {% endfor %} + {% endif %} + {% for i in range(60-ultmarc.is_input_inst_trt_course_data_size()) %} + + {% endfor %} -
検査工程 - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
特務医務室許可病床数 - - - - - - - - - - - - - - - - - - - - - -
一般療養精神感染症結核その他合計
-
病棟閉鎖  一部病棟閉鎖
病床数(定員)メンテ年月日
- - - - - - - - - - - - - - - - - - - - -
代表者個人コード
施設代表者(カナ)
施設代表者(漢字)
修正年月日
+
検査工程 + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
特務医務室許可病床数 + + + + + + + + + + + + + + + + + + + + + +
一般療養精神感染症結核その他合計
+
病棟閉鎖  一部病棟閉鎖
病床数(定員)メンテ年月日
+ + + + + + + + + + + + + + + + + + + + +
代表者個人コード
施設代表者(カナ)
施設代表者(漢字)
修正年月日
\ No newline at end of file diff --git a/ecs/jskult-webapp/src/templates/instSearch.html b/ecs/jskult-webapp/src/templates/instSearch.html index 8a866777..93018a91 100644 --- a/ecs/jskult-webapp/src/templates/instSearch.html +++ b/ecs/jskult-webapp/src/templates/instSearch.html @@ -6,189 +6,189 @@ {% endwith %} - + // Enter押下時にsubmitさせなくする + $(function() { + $(document).on("keypress", "input:not(.allow_submit)", function(event) { + return event.which !== 13; + }); + }); + } + - - - - - + + + +

{{ultmarc.subtitle}}

+ + + + + - - -

{{ultmarc.subtitle}}

{% if ultmarc.is_batch_processing %}
日次バッチ処理中のため、データが正しく表示されない可能性があります
{% endif %} -
- - +
+ + +
+ - -
- - - - + + + + + + - - - - -
- - - - - - - - - - - - - - - - -
ULT施設コード削除ULT施設名(漢字)ULT施設住所(漢字)郵便番号施設電話番号施設区分名病院種別都道府県
- {% if ultmarc.is_form_submitted() and ultmarc.is_data_overflow_max_length() %} -
- 検索件数が500件を超えています 検索項目を見直してください -
- {% endif %} - {% if ultmarc.is_form_submitted() and ultmarc.is_data_empty() %} -
- 対象のデータが存在しません -
- {% endif %} -
+ + + + +
+ + + + + + + + + + + + + + + + +
ULT施設コード削除ULT施設名(漢字)ULT施設住所(漢字)郵便番号施設電話番号施設区分名病院種別都道府県
+ {% if ultmarc.is_form_submitted() and ultmarc.is_data_overflow_max_length() %} +
+ 検索件数が500件を超えています 検索項目を見直してください +
+ {% endif %} + {% if ultmarc.is_form_submitted() and ultmarc.is_data_empty() %} +
+ 対象のデータが存在しません +
+ {% endif %} +
- - -
+ + + - + \ No newline at end of file From a8de16a3bd5492ac1a5538fa77079486e3b3f394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Thu, 6 Jul 2023 13:03:58 +0900 Subject: [PATCH 27/28] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BA=8B=E9=A0=85?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-daily/src/aws/s3.py | 4 ++-- .../src/batch/ultmarc/output_vjsk_inst_pharm_data.py | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/ecs/jskult-batch-daily/src/aws/s3.py b/ecs/jskult-batch-daily/src/aws/s3.py index 86ffc169..764b600c 100644 --- a/ecs/jskult-batch-daily/src/aws/s3.py +++ b/ecs/jskult-batch-daily/src/aws/s3.py @@ -159,14 +159,14 @@ class VjskSendBucket(S3Bucket): _bucket_name = environment.VJSK_DATA_BUCKET _send_folder = environment.VJSK_DATA_SEND_FOLDER - def upload_vjsk_csv_file(self, vjsk_create_csv: str, csv_file_path: str): + def upload_inst_pharm_csv_file(self, vjsk_create_csv: str, csv_file_path: str): # S3バケットにファイルを移動 csv_file_name = f'{self._send_folder}/{vjsk_create_csv}' s3_client = S3Client() s3_client.upload_file(csv_file_path, self._bucket_name, csv_file_name) return - def backup_vjsk_csv_file(self, dat_file_key: str, datetime_key: str): + def backup_inst_pharm_csv_file(self, dat_file_key: str, datetime_key: str): # バックアップバケットにコピー vjsk_backup_bucket = VjskBackupBucket() dat_key = f'{self._send_folder}/{dat_file_key}' diff --git a/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py b/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py index f72e8d92..838dae34 100644 --- a/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py +++ b/ecs/jskult-batch-daily/src/batch/ultmarc/output_vjsk_inst_pharm_data.py @@ -45,15 +45,14 @@ def exec(): vjsk_bucket = VjskSendBucket() try: # s3へデータ移動 - vjsk_bucket.upload_vjsk_csv_file(vjsk_csv_file_name, csv_file_path) + vjsk_bucket.upload_inst_pharm_csv_file(vjsk_csv_file_name, csv_file_path) except Exception as e: logger.info('S3バケットにCSVデータを作成できませんでした。') raise e try: # 処理後ファイルをバックアップ - batch_context = BatchContext.get_instance() - vjsk_bucket.backup_vjsk_csv_file(vjsk_csv_file_name, batch_context.syor_date) + vjsk_bucket.backup_inst_pharm_csv_file(vjsk_csv_file_name, batch_context.syor_date) except Exception as e: logger.info('バックアップバケットへCSVデータをコピーできませんでした。') raise e @@ -142,7 +141,7 @@ def select_inst_record(db): """ return db.execute_select(sql) except Exception as e: - logger.debug(f'{sql_err_msg}') + logger.debug(sql_err_msg) raise e @@ -220,7 +219,7 @@ def select_pharm_record(db): """ return db.execute_select(sql) except Exception as e: - logger.debug(f'{sql_err_msg}') + logger.debug(sql_err_msg) raise e @@ -266,7 +265,6 @@ def make_csv_data(record_inst: list, record_pharm: list, vjsk_csv_file_name: str writer.writerow(csv_data) except Exception as e: - logger.info('ワークデータの作成に失敗しました。') logger.info('CSVデータの作成に失敗しました。') raise e From 732557cb47eb1a7862c9a68b6659ee6014d7758d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E9=96=93?= Date: Mon, 10 Jul 2023 19:12:01 +0900 Subject: [PATCH 28/28] =?UTF-8?q?staging=E3=81=A7=E3=81=AE=E5=AE=9F?= =?UTF-8?q?=E8=A1=8C=E3=81=AE=E7=82=BA=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/jskult-batch-daily/.env.example | 2 +- ecs/jskult-batch-daily/src/aws/s3.py | 2 +- ecs/jskult-batch-daily/src/system_var/environment.py | 2 +- .../tests/batch/vjsk/vjsk_file_check/conftest.py | 4 ++-- ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_load/conftest.py | 4 ++-- s3/config/jskult/task_settings/batch_daily_task_settings.env | 3 ++- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ecs/jskult-batch-daily/.env.example b/ecs/jskult-batch-daily/.env.example index 1683e935..1e15cdb0 100644 --- a/ecs/jskult-batch-daily/.env.example +++ b/ecs/jskult-batch-daily/.env.example @@ -15,7 +15,7 @@ JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME=jskult_holiday_list.txt VJSK_DATA_SEND_FOLDER=send VJSK_DATA_BUCKET=************* JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILE_NAME=jskult_wholesaler_stock_input_day_list.txt -JSKULT_DATA_FOLDER_RECV=********************** +VJSK_DATA_RECEIVE_FOLDER=********************** # 連携データ抽出期間 SALES_LAUNDERING_EXTRACT_DATE_PERIOD=0 # 洗替対象テーブル名 diff --git a/ecs/jskult-batch-daily/src/aws/s3.py b/ecs/jskult-batch-daily/src/aws/s3.py index 764b600c..a4ebc30a 100644 --- a/ecs/jskult-batch-daily/src/aws/s3.py +++ b/ecs/jskult-batch-daily/src/aws/s3.py @@ -117,7 +117,7 @@ class VjskBackupBucket(JskUltBackupBucket): class VjskReceiveBucket(S3Bucket): _bucket_name = environment.VJSK_DATA_BUCKET - _recv_folder = environment.JSKULT_DATA_FOLDER_RECV + _recv_folder = environment.VJSK_DATA_RECEIVE_FOLDER _s3_file_list = None diff --git a/ecs/jskult-batch-daily/src/system_var/environment.py b/ecs/jskult-batch-daily/src/system_var/environment.py index dd45ae01..42ed6073 100644 --- a/ecs/jskult-batch-daily/src/system_var/environment.py +++ b/ecs/jskult-batch-daily/src/system_var/environment.py @@ -19,7 +19,7 @@ JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME = os.environ['JSKULT_CONFIG_CALEND VJSK_DATA_SEND_FOLDER = os.environ['VJSK_DATA_SEND_FOLDER'] VJSK_DATA_BUCKET = os.environ['VJSK_DATA_BUCKET'] JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILE_NAME = os.environ['JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILE_NAME'] -JSKULT_DATA_FOLDER_RECV = os.environ['JSKULT_DATA_FOLDER_RECV'] +VJSK_DATA_RECEIVE_FOLDER = os.environ['VJSK_DATA_RECEIVE_FOLDER'] # 初期値がある環境変数 LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') diff --git a/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_file_check/conftest.py b/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_file_check/conftest.py index c315147a..dccdd0df 100644 --- a/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_file_check/conftest.py +++ b/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_file_check/conftest.py @@ -15,12 +15,12 @@ def s3_client(): @pytest.fixture def bucket_name(): - return os.environ["JSKULT_DATA_BUCKET"] + return os.environ["VJSK_DATA_BUCKET"] @pytest.fixture def receive_folder(): - return os.environ["JSKULT_DATA_FOLDER_RECV"] + return os.environ["VJSK_DATA_RECEIVE_FOLDER"] # TODO 共通fixtureにして15個固定でput/delete、各個別fixtureで15個から引き算でdeleteする diff --git a/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_load/conftest.py b/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_load/conftest.py index ea29eb63..dc77a65f 100644 --- a/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_load/conftest.py +++ b/ecs/jskult-batch-daily/tests/batch/vjsk/vjsk_load/conftest.py @@ -15,12 +15,12 @@ def s3_client(): @pytest.fixture def bucket_name(): - return os.environ["JSKULT_DATA_BUCKET"] + return os.environ["VJSK_DATA_BUCKET"] @pytest.fixture def receive_folder(): - return os.environ["JSKULT_DATA_FOLDER_RECV"] + return os.environ["VJSK_DATA_RECEIVE_FOLDER"] @pytest.fixture diff --git a/s3/config/jskult/task_settings/batch_daily_task_settings.env b/s3/config/jskult/task_settings/batch_daily_task_settings.env index 2590fe79..12c1e83c 100644 --- a/s3/config/jskult/task_settings/batch_daily_task_settings.env +++ b/s3/config/jskult/task_settings/batch_daily_task_settings.env @@ -7,10 +7,11 @@ ULTMARC_BACKUP_FOLDER=ultmarc VJSK_BACKUP_FOLDER=vjsk JSKULT_CONFIG_CALENDAR_FOLDER=jskult/calendar JSKULT_CONFIG_CALENDAR_HOLIDAY_LIST_FILE_NAME=jskult_holiday_list.txt -JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILENAME=jskult_wholesaler_stock_input_day_list.txt +JSKULT_CONFIG_CALENDAR_WHOLESALER_STOCK_FILE_NAME=jskult_wholesaler_stock_input_day_list.txt SALES_LAUNDERING_EXTRACT_DATE_PERIOD=0 SALES_LAUNDERING_TARGET_TABLE_NAME=src05.sales_lau DB_CONNECTION_MAX_RETRY_ATTEMPT=4 DB_CONNECTION_RETRY_INTERVAL_INIT=5 DB_CONNECTION_RETRY_INTERVAL_MIN_SECONDS=5 DB_CONNECTION_RETRY_INTERVAL_MAX_SECONDS=50 +SALES_LAUNDERING_TARGET_YEAR_OFFSET=5 \ No newline at end of file