Merge pull request #158 feature-NEWDWH2021-1010 into develop

This commit is contained in:
下田雅人 2023-04-12 15:21:31 +09:00
commit 32020c6858
78 changed files with 2677 additions and 150 deletions

View File

@ -3,4 +3,8 @@ DB_PORT=************
DB_USERNAME=************
DB_PASSWORD=************
DB_SCHEMA=src05
LOG_LEVEL=INFO
LOG_LEVEL=INFO
ULTMARC_DATA_BUCKET=****************
ULTMARC_DATA_FOLDER=recv
ULTMARC_BACKUP_BUCKET=****************
ULTMARC_BACKUP_FOLDER=ultmarc

View File

@ -1,4 +1,10 @@
__pycache__
.vscode/settings.json
.env
# python
__pycache__
# python test
.pytest_cache
.coverage
.report/

View File

@ -5,7 +5,7 @@
"version": "0.2.0",
"configurations": [
{
"name": "Batch Sample",
"name": "(DEBUG)jskult batch daily",
"type": "python",
"request": "launch",
"program": "entrypoint.py",

View File

@ -12,7 +12,20 @@
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.linting.flake8Args": ["--max-line-length=120"],
"python.linting.flake8Args": [
"--max-line-length=200",
"--ignore=F541"
],
"python.formatting.provider": "autopep8",
"python.formatting.autopep8Args": ["--max-line-length", "120"]
"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
}

View File

@ -3,6 +3,10 @@ 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 = "*"
PyMySQL = "*"
@ -12,6 +16,8 @@ tenacity = "*"
[dev-packages]
autopep8 = "*"
flake8 = "*"
pytest = "*"
pytest-cov = "*"
[requires]
python_version = "3.9"

View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "1b9b3da586499b64915b0cf14217a1bcfb26c5e3e1c6fbfc9cce99242bc4faed"
"sha256": "9bce8f43bcad5d6ae8e5a558b8ade00a83f6e1671993e91b0a883fffa6b95df9"
},
"pipfile-spec": 6,
"requires": {
@ -18,19 +18,19 @@
"default": {
"boto3": {
"hashes": [
"sha256:043f8981d10c4e7c48736df4381dac557b46c5b369b0a450d8f3d7f5fdd24db5",
"sha256:b00f416832bc59863b96175045d2ebe067d9222289bce677c48fd72c006eaaad"
"sha256:816a198a6cc4f283af6b21439d85be6dbe4b73c2232dd906c6bafb4fece28d19",
"sha256:9de90a2c0b853f84436b032b28947fc8a765dc462573a8d543b13f16c6579b40"
],
"index": "pypi",
"version": "==1.26.102"
"version": "==1.26.107"
},
"botocore": {
"hashes": [
"sha256:4bae8f502507da18ff37c61cb18745cfb11d87a61dd0ea27e346adadff92aa3f",
"sha256:58b11c630d2044ea732ba4c403d29fab51e954465f9b3f7099cbf5ac0ce7ab47"
"sha256:ee1e43e6cd0864cc6811ba3f05123647612ee3f07a286a4c94f5885aa86d6922",
"sha256:f63942b4b7248c0b3d6ecbc2852cf0787c23ace2a91a012f7ee0b3ae3eb08f4f"
],
"markers": "python_version >= '3.7'",
"version": "==1.29.102"
"version": "==1.29.107"
},
"greenlet": {
"hashes": [
@ -140,50 +140,50 @@
},
"sqlalchemy": {
"hashes": [
"sha256:013f4f330001e84a2b0ef1f2c9bd73169c79d582e54e1a144be1be1dbc911711",
"sha256:0789e199fbce8cb1775337afc631ed12bcc5463dd77d7a06b8dafd758cde51f8",
"sha256:0b698440c477c00bdedff87348b19a79630a235864a8f4378098d61079c16ce9",
"sha256:0eac488be90dd3f7a655d2e34fa59e1305fccabc4abfbd002e3a72ae10bd2f89",
"sha256:14854bdb2a35af536d14f77dfa8dbc20e1bb1972996d64c4147e0d3165c9aaf5",
"sha256:18795e87601b4244fd08b542cd6bff9ef674b17bcd34e4a3c9935398e2cc762c",
"sha256:32f508fef9c5a7d19411d94ef64cf5405e42c4689e51ddbb81ac9a7be045cce8",
"sha256:33f73cc45ffa050f5c3b60ff4490e0ae9e02701461c1600d5ede1b008076b1b9",
"sha256:38e26cf6b9b4c6c37846f7e31b42e4d664b35f055691265f07e06aeb6167c494",
"sha256:3da3dff8d9833a7d7f66a3c45a79a3955f775c79f47bb7eea266d0b4c267b17a",
"sha256:432cfd77642771ee7ea0dd0f3fb664f18506a3625eab6e6d5d1d771569171270",
"sha256:4339110be209fea37a2bb4f35f1127c7562a0393e9e6df5d9a65cc4f5c167cb6",
"sha256:486015a58c9a67f65a15b4f19468b35b97cee074ae55386a9c240f1da308fbfe",
"sha256:494db0026918e3f707466a1200a5dedbf254a4bce01a3115fd95f04ba8258f09",
"sha256:57b80e877eb6ec63295835f8a3b86ca3a44829f80c4748e1b019e03adea550fc",
"sha256:5f7c40ec2e3b31293184020daba95850832bea523a08496ac89b27a5276ec804",
"sha256:6d44ff7573016fc26311b5a5c54d5656fb9e0c39e138bc8b81cb7c8667485203",
"sha256:774965c41b71c8ebe3c5728bf5b9a948231fc3a0422d9fdace0686f5bb689ad6",
"sha256:7917632606fc5d4be661dcde45cc415df835e594e2c50cc999a44f24b6bf6d92",
"sha256:9020125e3be677c64d4dda7048e247343f1663089cf268a4cc98c957adb7dbe0",
"sha256:921485d1f69ed016e1f756de67d02ad4f143eb6b92b9776bfff78786d8978ab5",
"sha256:94556a2a7fc3de094ea056b62845e2e6e271e26d1e1b2540a1cd2d2506257a10",
"sha256:a4c1e1582492c66dfacc9eab52738f3e64d9a2a380e412668f75aa06e540f649",
"sha256:a65a8fd09bdffd63fa23b39cd902e6a4ca23d86ecfe129513e43767a1f3e91fb",
"sha256:a6f7d1debb233f1567d700ebcdde0781a0b63db0ef266246dfbf75ae41bfdf85",
"sha256:b0995b92612979d208189245bf87349ad9243b97b49652347a28ddee0803225a",
"sha256:b8ab8f90f4a13c979e6c41c9f011b655c1b9ae2df6cffa8fa2c7c4d740f3512e",
"sha256:bc370d53fee7408330099c4bcc2573a107757b203bc61f114467dfe586a0c7bd",
"sha256:c38641f5c3714505d65dbbd8fb1350408b9ad8461769ec8e440e1177f9c92d1d",
"sha256:cc337b96ec59ef29907eeadc2ac11188739281568f14c719e61550ca6d201a41",
"sha256:ce076e25f1170000b4ecdc57a1ff8a70dbe4a5648ec3da0563ef3064e8db4f15",
"sha256:cebd161f964af58290596523c65e41a5a161a99f7212b1ae675e288a4b5e0a7c",
"sha256:d2e7411d5ea164c6f4d003f5d4f5e72e202956aaa7496b95bb4a4c39669e001c",
"sha256:e735a635126b2338dfd3a0863b675437cb53d85885a7602b8cffb24345df33ed",
"sha256:e7e61e2e4dfe175dc3510889e44eda1c32f55870d6950ef40519640cb266704d",
"sha256:e90f0be674e0845c5c1ccfa5e31c9ee28fd406546a61afc734355cc7ea1f8f8b",
"sha256:ea1c63e61b5c13161c8468305f0a5837c80aae2070e33654c68dd12572b638eb",
"sha256:ea9461f6955f3cf9eff6eeec271686caed7792c76f5b966886a36a42ea46e6b2",
"sha256:f15c54713a8dd57a01c974c9f96476688f6f6374d348819ed7e459535844b614",
"sha256:fb649c5473f79c9a7b6133f53a31f4d87de14755c79224007eb7ec76e628551e",
"sha256:fc67667c8e8c04e5c3250ab2cd51df40bc7c28c7c253d0475b377eff86fe4bb0"
"sha256:07950fc82f844a2de67ddb4e535f29b65652b4d95e8b847823ce66a6d540a41d",
"sha256:0a865b5ec4ba24f57c33b633b728e43fde77b968911a6046443f581b25d29dd9",
"sha256:0b49f1f71d7a44329a43d3edd38cc5ee4c058dfef4487498393d16172007954b",
"sha256:13f984a190d249769a050634b248aef8991acc035e849d02b634ea006c028fa8",
"sha256:1b69666e25cc03c602d9d3d460e1281810109e6546739187044fc256c67941ef",
"sha256:1d06e119cf79a3d80ab069f064a07152eb9ba541d084bdaee728d8a6f03fd03d",
"sha256:246712af9fc761d6c13f4f065470982e175d902e77aa4218c9cb9fc9ff565a0c",
"sha256:34eb96c1de91d8f31e988302243357bef3f7785e1b728c7d4b98bd0c117dafeb",
"sha256:4c3020afb144572c7bfcba9d7cce57ad42bff6e6115dffcfe2d4ae6d444a214f",
"sha256:4f759eccb66e6d495fb622eb7f4ac146ae674d829942ec18b7f5a35ddf029597",
"sha256:68ed381bc340b4a3d373dbfec1a8b971f6350139590c4ca3cb722fdb50035777",
"sha256:6b72dccc5864ea95c93e0a9c4e397708917fb450f96737b4a8395d009f90b868",
"sha256:6e84ab63d25d8564d7a8c05dc080659931a459ee27f6ed1cf4c91f292d184038",
"sha256:734805708632e3965c2c40081f9a59263c29ffa27cba9b02d4d92dfd57ba869f",
"sha256:78612edf4ba50d407d0eb3a64e9ec76e6efc2b5d9a5c63415d53e540266a230a",
"sha256:7e472e9627882f2d75b87ff91c5a2bc45b31a226efc7cc0a054a94fffef85862",
"sha256:865392a50a721445156809c1a6d6ab6437be70c1c2599f591a8849ed95d3c693",
"sha256:8d118e233f416d713aac715e2c1101e17f91e696ff315fc9efbc75b70d11e740",
"sha256:8d3ece5960b3e821e43a4927cc851b6e84a431976d3ffe02aadb96519044807e",
"sha256:93c78d42c14aa9a9e0866eacd5b48df40a50d0e2790ee377af7910d224afddcf",
"sha256:95719215e3ec7337b9f57c3c2eda0e6a7619be194a5166c07c1e599f6afc20fa",
"sha256:9838bd247ee42eb74193d865e48dd62eb50e45e3fdceb0fdef3351133ee53dcf",
"sha256:aa5c270ece17c0c0e0a38f2530c16b20ea05d8b794e46c79171a86b93b758891",
"sha256:ac6a0311fb21a99855953f84c43fcff4bdca27a2ffcc4f4d806b26b54b5cddc9",
"sha256:ad5363a1c65fde7b7466769d4261126d07d872fc2e816487ae6cec93da604b6b",
"sha256:b3e5864eba71a3718236a120547e52c8da2ccb57cc96cecd0480106a0c799c92",
"sha256:bbda1da8d541904ba262825a833c9f619e93cb3fd1156be0a5e43cd54d588dcd",
"sha256:c6e27189ff9aebfb2c02fd252c629ea58657e7a5ff1a321b7fc9c2bf6dc0b5f3",
"sha256:c8239ce63a90007bce479adf5460d48c1adae4b933d8e39a4eafecfc084e503c",
"sha256:d209594e68bec103ad5243ecac1b40bf5770c9ebf482df7abf175748a34f4853",
"sha256:d5327f54a9c39e7871fc532639616f3777304364a0bb9b89d6033ad34ef6c5f8",
"sha256:db4bd1c4792da753f914ff0b688086b9a8fd78bb9bc5ae8b6d2e65f176b81eb9",
"sha256:e4780be0f19e5894c17f75fc8de2fe1ae233ab37827125239ceb593c6f6bd1e2",
"sha256:e4a019f723b6c1e6b3781be00fb9e0844bc6156f9951c836ff60787cc3938d76",
"sha256:e62c4e762d6fd2901692a093f208a6a6575b930e9458ad58c2a7f080dd6132da",
"sha256:e730603cae5747bc6d6dece98b45a57d647ed553c8d5ecef602697b1c1501cf2",
"sha256:ebc4eeb1737a5a9bdb0c24f4c982319fa6edd23cdee27180978c29cbb026f2bd",
"sha256:ee2946042cc7851842d7a086a92b9b7b494cbe8c3e7e4627e27bc912d3a7655e",
"sha256:f005245e1cb9b8ca53df73ee85e029ac43155e062405015e49ec6187a2e3fb44",
"sha256:f49c5d3c070a72ecb96df703966c9678dda0d4cb2e2736f88d15f5e1203b4159",
"sha256:f61ab84956dc628c8dfe9d105b6aec38afb96adae3e5e7da6085b583ff6ea789"
],
"index": "pypi",
"version": "==2.0.7"
"version": "==2.0.9"
},
"tenacity": {
"hashes": [
@ -211,6 +211,14 @@
}
},
"develop": {
"attrs": {
"hashes": [
"sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836",
"sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"
],
"markers": "python_version >= '3.6'",
"version": "==22.2.0"
},
"autopep8": {
"hashes": [
"sha256:86e9303b5e5c8160872b2f5ef611161b2893e9bfe8ccc7e2f76385947d57a2f1",
@ -219,6 +227,74 @@
"index": "pypi",
"version": "==2.0.2"
},
"coverage": {
"extras": [
"toml"
],
"hashes": [
"sha256:006ed5582e9cbc8115d2e22d6d2144a0725db542f654d9d4fda86793832f873d",
"sha256:046936ab032a2810dcaafd39cc4ef6dd295df1a7cbead08fe996d4765fca9fe4",
"sha256:0484d9dd1e6f481b24070c87561c8d7151bdd8b044c93ac99faafd01f695c78e",
"sha256:0ce383d5f56d0729d2dd40e53fe3afeb8f2237244b0975e1427bfb2cf0d32bab",
"sha256:186e0fc9cf497365036d51d4d2ab76113fb74f729bd25da0975daab2e107fd90",
"sha256:2199988e0bc8325d941b209f4fd1c6fa007024b1442c5576f1a32ca2e48941e6",
"sha256:299bc75cb2a41e6741b5e470b8c9fb78d931edbd0cd009c58e5c84de57c06731",
"sha256:3668291b50b69a0c1ef9f462c7df2c235da3c4073f49543b01e7eb1dee7dd540",
"sha256:36dd42da34fe94ed98c39887b86db9d06777b1c8f860520e21126a75507024f2",
"sha256:38004671848b5745bb05d4d621526fca30cee164db42a1f185615f39dc997292",
"sha256:387fb46cb8e53ba7304d80aadca5dca84a2fbf6fe3faf6951d8cf2d46485d1e5",
"sha256:3eb55b7b26389dd4f8ae911ba9bc8c027411163839dea4c8b8be54c4ee9ae10b",
"sha256:420f94a35e3e00a2b43ad5740f935358e24478354ce41c99407cddd283be00d2",
"sha256:4ac0f522c3b6109c4b764ffec71bf04ebc0523e926ca7cbe6c5ac88f84faced0",
"sha256:4c752d5264053a7cf2fe81c9e14f8a4fb261370a7bb344c2a011836a96fb3f57",
"sha256:4f01911c010122f49a3e9bdc730eccc66f9b72bd410a3a9d3cb8448bb50d65d3",
"sha256:4f68ee32d7c4164f1e2c8797535a6d0a3733355f5861e0f667e37df2d4b07140",
"sha256:4fa54fb483decc45f94011898727802309a109d89446a3c76387d016057d2c84",
"sha256:507e4720791977934bba016101579b8c500fb21c5fa3cd4cf256477331ddd988",
"sha256:53d0fd4c17175aded9c633e319360d41a1f3c6e352ba94edcb0fa5167e2bad67",
"sha256:55272f33da9a5d7cccd3774aeca7a01e500a614eaea2a77091e9be000ecd401d",
"sha256:5764e1f7471cb8f64b8cda0554f3d4c4085ae4b417bfeab236799863703e5de2",
"sha256:57b77b9099f172804e695a40ebaa374f79e4fb8b92f3e167f66facbf92e8e7f5",
"sha256:5afdad4cc4cc199fdf3e18088812edcf8f4c5a3c8e6cb69127513ad4cb7471a9",
"sha256:5cc0783844c84af2522e3a99b9b761a979a3ef10fb87fc4048d1ee174e18a7d8",
"sha256:5e1df45c23d4230e3d56d04414f9057eba501f78db60d4eeecfcb940501b08fd",
"sha256:6146910231ece63facfc5984234ad1b06a36cecc9fd0c028e59ac7c9b18c38c6",
"sha256:797aad79e7b6182cb49c08cc5d2f7aa7b2128133b0926060d0a8889ac43843be",
"sha256:7c20b731211261dc9739bbe080c579a1835b0c2d9b274e5fcd903c3a7821cf88",
"sha256:817295f06eacdc8623dc4df7d8b49cea65925030d4e1e2a7c7218380c0072c25",
"sha256:81f63e0fb74effd5be736cfe07d710307cc0a3ccb8f4741f7f053c057615a137",
"sha256:872d6ce1f5be73f05bea4df498c140b9e7ee5418bfa2cc8204e7f9b817caa968",
"sha256:8c99cb7c26a3039a8a4ee3ca1efdde471e61b4837108847fb7d5be7789ed8fd9",
"sha256:8dbe2647bf58d2c5a6c5bcc685f23b5f371909a5624e9f5cd51436d6a9f6c6ef",
"sha256:8efb48fa743d1c1a65ee8787b5b552681610f06c40a40b7ef94a5b517d885c54",
"sha256:92ebc1619650409da324d001b3a36f14f63644c7f0a588e331f3b0f67491f512",
"sha256:9d22e94e6dc86de981b1b684b342bec5e331401599ce652900ec59db52940005",
"sha256:ba279aae162b20444881fc3ed4e4f934c1cf8620f3dab3b531480cf602c76b7f",
"sha256:bc4803779f0e4b06a2361f666e76f5c2e3715e8e379889d02251ec911befd149",
"sha256:bfe7085783cda55e53510482fa7b5efc761fad1abe4d653b32710eb548ebdd2d",
"sha256:c448b5c9e3df5448a362208b8d4b9ed85305528313fca1b479f14f9fe0d873b8",
"sha256:c90e73bdecb7b0d1cea65a08cb41e9d672ac6d7995603d6465ed4914b98b9ad7",
"sha256:d2b96123a453a2d7f3995ddb9f28d01fd112319a7a4d5ca99796a7ff43f02af5",
"sha256:d52f0a114b6a58305b11a5cdecd42b2e7f1ec77eb20e2b33969d702feafdd016",
"sha256:d530191aa9c66ab4f190be8ac8cc7cfd8f4f3217da379606f3dd4e3d83feba69",
"sha256:d683d230b5774816e7d784d7ed8444f2a40e7a450e5720d58af593cb0b94a212",
"sha256:db45eec1dfccdadb179b0f9ca616872c6f700d23945ecc8f21bb105d74b1c5fc",
"sha256:db8c2c5ace167fd25ab5dd732714c51d4633f58bac21fb0ff63b0349f62755a8",
"sha256:e2926b8abedf750c2ecf5035c07515770944acf02e1c46ab08f6348d24c5f94d",
"sha256:e627dee428a176ffb13697a2c4318d3f60b2ccdde3acdc9b3f304206ec130ccd",
"sha256:efe1c0adad110bf0ad7fb59f833880e489a61e39d699d37249bdf42f80590169"
],
"markers": "python_version >= '3.7'",
"version": "==7.2.2"
},
"exceptiongroup": {
"hashes": [
"sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e",
"sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"
],
"markers": "python_version < '3.11'",
"version": "==1.1.1"
},
"flake8": {
"hashes": [
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
@ -227,6 +303,14 @@
"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",
@ -235,6 +319,22 @@
"markers": "python_version >= '3.6'",
"version": "==0.7.0"
},
"packaging": {
"hashes": [
"sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2",
"sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"
],
"markers": "python_version >= '3.7'",
"version": "==23.0"
},
"pluggy": {
"hashes": [
"sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159",
"sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"
],
"markers": "python_version >= '3.6'",
"version": "==1.0.0"
},
"pycodestyle": {
"hashes": [
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053",
@ -251,6 +351,22 @@
"markers": "python_version >= '3.6'",
"version": "==3.0.1"
},
"pytest": {
"hashes": [
"sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e",
"sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"
],
"index": "pypi",
"version": "==7.2.2"
},
"pytest-cov": {
"hashes": [
"sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b",
"sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"
],
"index": "pypi",
"version": "==4.0.0"
},
"tomli": {
"hashes": [
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",

View File

@ -7,67 +7,212 @@
## 環境情報
- Python 3.9
- MySQL 8.x
- MySQL 8.23
- VSCode
## 環境構築
- Pythonの構築
- Merck_NewDWH開発2021のWiki、[Python環境構築](https://nds-tyo.backlog.com/alias/wiki/1874930)を参照
- 「Pipenvの導入」までを行っておくこと
- 構築完了後、プロジェクト配下で以下のコマンドを実行し、Pythonの仮想環境を作成する
- `pipenv install --python <pyenvでインストールしたpythonバージョン>`
- この手順で出力される仮想環境のパスは、後述するVSCodeの設定手順で使用するため、控えておく
- Python の構築
- MySQLの環境構築
- Windowsの場合、以下のリンクからダウンロードする
- Merck_NewDWH 開発 2021 の Wiki、[Python 環境構築](https://nds-tyo.backlog.com/alias/wiki/1874930)を参照
- 「Pipenv の導入」までを行っておくこと
- 構築完了後、プロジェクト配下で以下のコマンドを実行し、Python の仮想環境を作成する
- `pipenv install --dev --python <pyenvでインストールしたpythonバージョン>`
- この手順で出力される仮想環境のパスは、後述する VSCode の設定手順で使用するため、控えておく
- MySQL の環境構築
- Windows の場合、以下のリンクからダウンロードする
- <https://dev.mysql.com/downloads/installer/>
- Dockerを利用する場合、「newsdwh-tools」リポジトリのMySQL設定を使用すると便利
- Docker を利用する場合、「newsdwh-tools」リポジトリの MySQL 設定を使用すると便利
- 「crm-table-to-ddl」フォルダ内で以下のコマンドを実行すると
- `docker-compose up -d`
- Dockerの構築手順は、[Dockerのセットアップ手順](https://nds-tyo.backlog.com/alias/wiki/1754332)を参照のこと
- 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コマンドを使用して復元する
- [ローカル開発用データ](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の設定
- 環境変数を設定する。設定内容は PRJ メンバーより共有を受けてください
- VSCode の設定
- 「.vscode/recommended_settings.json」ファイルをコピーし、「settings.json」ファイルを作成する
- 「python.defaultInterpreterPath」を、Pythonの構築手順で作成した仮想環境のパスに変更する
- 「python.defaultInterpreterPath」を、Python の構築手順で作成した仮想環境のパスに変更する
## 実行
- VSCode上で「F5」キーを押下すると、バッチ処理が起動する。
- VSCode 上で「F5」キーを押下すると、バッチ処理が起動する。
- 「entrypoint.py」が、バッチ処理のエントリーポイント。
- 実際の処理は、「src/jobctrl_daily.py」で行っている。
## 単体テスト
アルトマーク取込処理は、単体テストコードを使用してテスト自動化を行う
### テスト準備
- VSCodeで以下の拡張機能をインストールする
- Python
- Python Test Explorer for Visual Studio Code
- Test Explorer UI
- VSCode 上でショートカット「ctrl」+「shift」+「P」でコマンドパレットを開く
- コマンドパレットの検索窓に「Python」と入力し、「Python: テストを構成する」を押下する
- 現在のワークスペースを選び、「pytest」を選択する
- 「tests」フォルダを選択する
- バックグランドで、pytest モジュールのインストールが始まれば成功
### テスト用のサブコマンド一覧
- `pipenv run`のあとに、サブコマンドとしてユーザー定義スクリプトを実行できる
- `Pipfile`内の「scripts」セクションに宣言されている
| コマンド | 概要 |
| ---------------- | -------------------------------------------------------------------------------------------- |
| test:ultmarc | tests/batch/ultmarc フォルダ配下のユニットテストを実行する |
| test:ultmarc:cov | tests/batch/ultmarc フォルダ配下のユニットテストを実行し、テストカバレッジを取得する(C1, C2) |
### テスト共通関数の仕様
- tests/testing_utility.py内の共通関数の仕様について記載する
#### create_ultmarc_test_data_from_csv
- 引数
- file_path: str
- 戻り値
- src.batch.ultmarc.datfile.DatFileのインスタンス
- 処理概要
- CSVファイルから、アルトマークのインプットデータを作成する
- データフォーマットは以下
- 文字コード: UTF-8
- 改行コードLF
- ヘッダ: なし
- 値囲い: ダブルクォート
- アルトマークデータと文字コードを合わせるため、指定されたファイルを一時ディレクトリに、文字コード「cp932」で書き出してからテストデータとして読み込む
- テストデータそのものはUTF-8の文字コードで作成すること
### create_db_data_from_csv
- 引数
- file_path: str
- 戻り値
- テーブルのレコードに相当する辞書のリスト
- 処理概要
- CSVファイルから、アルトマークテーブルに相当するテストデータを作成する
- テストの初期データ、期待値データを作成するのに利用する
- データフォーマットは以下
- 文字コード: UTF-8
- 改行コードLF
- ヘッダ: なし
- 値囲い: ダブルクォート
- ファイル内の、以下の形式のデータを自動的に変換する
- `NULL`
- `None`に変換される
- `yyyy-mm-dd`もしくは、`yyyy/mm/dd`の文字
- Date型に変換される
- `yyyy-mm-dd hh:mm:ss`もしくは、`yyyy/mm/dd hh:mm:ss`の文字
- DateTime型に変換される
### create_insert_sql_with_parameter
- 引数
- table_name: str テーブル名
- column_names: list[str] カラム名のリスト
- test_data: list[str]: 値のリスト
- 戻り値
- INSERT文とバインドパラメータ辞書
- 処理概要
- 引数を使用して、`src.db.Database#execute`メソッドで実行可能な形でINSERT文、バインドパラメータを作成する
### create_delete_sql_with_parameter
- 引数
- table_name: str テーブル名
- column_names: list[str] カラム名のリスト
- test_data: list[str]: 値のリスト
- 戻り値
- DELETE文とバインドパラメータ辞書
- 処理概要
- 引数を使用して、`src.db.Database#execute`メソッドで実行可能な形でDELETE文、バインドパラメータを作成する
### create_ultmarc_table_mapper_sut
- 引数
- line: src.batch.ultmarc.datfile.DatFileLine アルトマークデータファイルの1行
- db: src.db.Database データベース操作クラス
- 戻り値
- マッパークラス
- 処理概要
- src.batch.ultmarc.utmp_tables.ultmarc_table_mapper_factory.UltmarcTableMapperFactoryを通じて、テスト対象のマッパークラスを生成して返す
### assert_table_results
- 引数
- actual_rows: list[dict] テスト結果の辞書リスト
- expect_rows: list[dict] 期待値の辞書リスト
- ignore_col_name: list 比較を無視するDBのカラム名. Default None.
- 戻り値
- なし
- 処理概要
- テスト結果データと期待値データを突き合わせ、期待値どおりとなっているかを確認する
- ignore_col_nameに指定したカラムは、呼び出し元のテストコード内で個別に突き合わせする
## フォルダ構成
```text
.
├── Pipfile -- Pythonモジュールの依存関係を管理するファイル
├── Dockerfile -- Dockerイメージを作成するためのファイル
├── Pipfile -- Pythonモジュールの依存関係を管理するファイル
├── Pipfile.lock -- Pythonモジュールの依存関係バージョン固定用ファイル
├── README.md -- 当ファイル
├── entrypoint.py -- バッチ処理のエントリーポイントになるpythonファイル
└── src -- ソースコードの保管場所
├── batch -- バッチ処理関連ソース置き場
│ ├── batch_functions.py -- バッチ処理共通関数置き場
│ ├── datachange -- 実績洗替関連ソース置き場
│ │ └── emp_chg_inst_lau.py -- 施設担当者マスタ洗替
│ └── jissekiaraigae.py -- 実績洗替処理のエントリーポイント
├── db
│ └── database.py -- データベース操作共通処理
├── error
│ └── exceptions.py -- カスタム例外
├── jobctrl_daily.py -- 日次バッチ処理のエントリーポイント。「entrypoint.py」 から呼ばれる。
├── logging
│ └── get_logger.py -- ログ出力の共通処理
├── system_var
│ └── environment.py -- 環境変数
└── time
└── elapsed_time.py -- 実行時間計測用
├── Pipfile -- Pythonモジュールの依存関係を管理するファイル
├── Dockerfile -- Dockerイメージを作成するためのファイル
├── Pipfile -- Pythonモジュールの依存関係を管理するファイル
├── Pipfile.lock -- Pythonモジュールの依存関係バージョン固定用ファイル
├── README.md -- 当ファイル
├── entrypoint.py -- バッチ処理のエントリーポイントになるpythonファイル
├── src -- ソースコードの保管場所
│ ├── aws -- AWS関連処理
│ │ └── s3.py -- S3クライアントとバケット処理
│ ├── batch -- バッチ処理関連ソース置き場
│ │ ├── batch_functions.py -- バッチ処理共通関数置き場
│ │ ├── datachange -- 実績洗替関連ソース置き場
│ │ │ └── emp_chg_inst_lau.py -- 施設担当者マスタ洗替
│ │ └── jissekiaraigae.py -- 実績洗替処理のエントリーポイント
│ │ └── ultmarc -- アルトマーク関連処理
│ │ ├── ultmarc_process.py -- アルトマーク関連処理のエントリーポイント
│ │ ├── datfile.py -- データファイル読込
│ │ └── utmp_tables -- アルトマークテーブルへの登録関連
│ │ ├── table_mapper -- テーブルへのデータマッピング処理
│ │ │ ├── concrete -- テーブルマッパーのマッピング処理を行う具象クラス(全テーブル分)
│ │ │ │ ├── com_alma_mapper.py
│ │ │ │ ├── ...
│ │ │ │ └── null_mapper.py -- テスト用、空振りするマッパークラス
│ │ │ └── ultmarc_table_mapper.py -- テーブルへの登録処理を行う抽象クラス
│ │ ├── tables -- アルトマークデータのDTOクラス(全テーブル分)
│ │ │ ├── com_alma.py
│ │ │ ├── ...
│ │ │ └── ultmarc_table.py -- アルトマークテーブルの抽象クラス
│ │ └── ultmarc_table_mapper_factory.py -- テーブルマッパー生成クラス
│ ├── db
│ │ └── database.py -- データベース操作共通処理
│ ├── error
│ │ └── exceptions.py -- カスタム例外
│ ├── jobctrl_daily.py -- 日次バッチ処理のエントリーポイント。「entrypoint.py」 から呼ばれる。
│ ├── logging
│ │ └── get_logger.py -- ログ出力の共通処理
│ ├── system_var
│ │ └── environment.py -- 環境変数
│ └── time
│ └── elapsed_time.py -- 実行時間計測用
└── tests -- ユニットテストのルートディレクト
├── batch
│ └── ultmarc -- アルトマーク関連のユニットテストを格納する
│ └── utmp_tables
│ └── table_mapper -- 以下、マッパークラス単位でフォルダを切る
│ └── com_alma
│ ├── test_com_alma_mapper.py -- テストコード本体
│ ├── com_alma_insert.csv -- S3に配置される想定のテストCSVデータ。ケースごとに用意する。
│ ...
│ ├── db_com_alma_before_update.csv -- テスト時に事前にDBに登録しておくデータ。CSVで用意する。
│ ...
│ ├── expect_com_alma_insert.csv -- テストの期待値データ。CSVで用意する。
│ ...
├── conftest.py -- テスト内で共通利用できるフィクスチャを宣言する(執筆時点ではDBのみ)
└── testing_utility.py -- テストの共通関数
```

View File

@ -0,0 +1,3 @@
[pytest]
log_format = %(levelname)s %(asctime)s %(message)s
log_date_format = %Y-%m-%d %H:%M:%S

View File

@ -0,0 +1,84 @@
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)
def delete_dat_file(self, dat_file_key: str):
self._s3_client.delete_file(self._bucket_name, dat_file_key)
class JskUltBackupBucket(S3Bucket):
_bucket_name = environment.ULTMARC_BACKUP_BUCKET
class UltmarcBackupBucket(JskUltBackupBucket):
_folder = environment.ULTMARC_BACKUP_FOLDER

View File

@ -53,4 +53,4 @@ def logging_sql(logger, sql):
logger (logging.Logger): ロガー
sql (str): SQL文
"""
logger.debug(f'\n{"-"*15}\n{textwrap.dedent(sql)[1:-1]}\n{"-"*15}')
logger.debug(f'\n{"-"*15}\n{textwrap.dedent(sql)[1:-1]}\n{"-"*15}')

View File

@ -0,0 +1,10 @@
class BatchConfig:
# 処理日(yyyy/mm/dd形式)
syor_date: str
__instance = None
@classmethod
def get_instance(cls):
if cls.__instance is None:
cls.__instance = cls()
return cls.__instance

View File

@ -1,18 +1,21 @@
from src.batch.batch_functions import get_syor_date_as_date_format, logging_sql
from src.batch.batch_functions import logging_sql
from src.batch.common.batch_config import BatchConfig
from src.db.database import Database
from src.error.exceptions import BatchOperationException
from src.logging.get_logger import get_logger
from src.time.elapsed_time import ElapsedTime
logger = get_logger('48-施設担当者マスタ洗替')
batch_config = BatchConfig.get_instance()
def batch_process():
db = Database.get_instance()
db.connect()
logger.info('##########################')
logger.info('START Changing Employee in charge of institution PGM.')
# 日付テーブルを取得
syor_date = get_syor_date_as_date_format(db)
# 業務日付を取得
syor_date = batch_config.syor_date
# `emp_chg_inst_lau`をTruncate
truncate_emp_chg_inst_lau(db)
# emp_chg_inst から、`emp_chg_inst_lau`へInsert
@ -37,6 +40,7 @@ def truncate_emp_chg_inst_lau(db: Database):
logger.info("Table `emp_chg_inst_lau` was truncated!")
return
def insert_into_emp_chg_inst_lau_from_emp_chg_inst(db: Database):
logger.info("##########################")
try:
@ -44,7 +48,7 @@ def insert_into_emp_chg_inst_lau_from_emp_chg_inst(db: Database):
sql = """
INSERT INTO
src05.emp_chg_inst_lau
SELECT
SELECT
inst_cd,
ta_cd,emp_cd,
bu_cd,
@ -69,9 +73,10 @@ def insert_into_emp_chg_inst_lau_from_emp_chg_inst(db: Database):
logger.info("Error! Insert into `emp_chg_inst_lau` from `emp_chg_inst` was failed!!!")
raise BatchOperationException(e)
logger.info("Success! Insert into `emp_chg_inst_lau` from `emp_chg_inst` was inserted!")
return
def update_emp_chg_inst_lau_from_vop_hco_merge_v(db: Database, syor_date: str):
# vop_hco_merge_vはデータが作られないため、この洗い替え処理は基本空振りする
logger.info("##########################")
@ -94,7 +99,7 @@ def update_emp_chg_inst_lau_from_vop_hco_merge_v(db: Database, syor_date: str):
if count == 0:
logger.info('vop_hco_merge_v Table Data is not exists!')
return
logger.info('vop_hco_merge_v Table Data is exists!')
# vop_hco_merge_v から、emp_chg_inst_lauをUpdateします
result = db.execute_select(
@ -102,11 +107,11 @@ def update_emp_chg_inst_lau_from_vop_hco_merge_v(db: Database, syor_date: str):
SELECT
v_inst_cd,
v_inst_cd_merg
FROM
FROM
src05.vop_hco_merge_v
WHERE
STR_TO_DATE(apply_dt, '%Y-%m-%d') <= :syor_date
ORDER BY
ORDER BY
STR_TO_DATE(apply_dt, '%Y-%m-%d') ASC
""",
{'syor_date': syor_date}
@ -153,7 +158,7 @@ def update_dcf_inst_merge_from_emp_chg_inst_lau(db: Database, syor_date: str):
muko_flg = '0'
AND dcf_inst_cd_new IS NOT NULL
AND enabled_flg = 'Y'
AND STR_TO_DATE(CONCAT(tekiyo_month, '01'), '%Y%m%d') <= :syor_date -- TODO: tekiyo_monthはいっぴにする
AND STR_TO_DATE(CONCAT(tekiyo_month, '01'), '%Y%m%d') <= :syor_date
""",
{'syor_date': syor_date}
)
@ -164,27 +169,27 @@ def update_dcf_inst_merge_from_emp_chg_inst_lau(db: Database, syor_date: str):
if count == 0:
logger.info('dcf_inst_merge Table Data is not exists!')
return
logger.info('dcf_inst_merge Table Data is exists!')
# dcf_inst_mergeから、emp_chg_inst_lauをUpdate
logger.info("##########################")
logger.info("#### UPDATE DATA #########")
logger.info("##########################")
logger.info("##########################")
try:
elapsed_time = ElapsedTime()
update_sql = """
UPDATE
src05.emp_chg_inst_lau el,
(
SELECT
SELECT
dcf_inst_cd,
dcf_inst_cd_new
dcf_inst_cd_new
FROM
src05.dcf_inst_merge
WHERE
muko_flg = '0'
AND dcf_inst_cd_new IS NOT NULL
AND enabled_flg = 'Y'
WHERE
muko_flg = '0'
AND dcf_inst_cd_new IS NOT NULL
AND enabled_flg = 'Y'
AND STR_TO_DATE(CONCAT(tekiyo_month, '01'), '%Y%m%d') <= :syor_date
) dm
SET
@ -204,5 +209,5 @@ def update_dcf_inst_merge_from_emp_chg_inst_lau(db: Database, syor_date: str):
raise BatchOperationException(e)
logger.info("emp_chg_inst_lau.v_inst_cd was set!")
return

View File

@ -0,0 +1,60 @@
import csv
from io import TextIOWrapper
class DatFileLine:
layout_class: str
records: list[str]
def __init__(self, dat_line: list[str]) -> None:
self.layout_class = dat_line[0]
self.records = dat_line
class DatFile:
"""アルトマークデータファイル"""
lines: list[DatFileLine]
success_count: int = 0
error_count: int = 0
total_count: int = 0
__i: int = 0
def __iter__(self):
return self
def __next__(self) -> DatFileLine:
if self.__i == len(self.lines):
raise StopIteration()
line = self.lines[self.__i]
self.__i += 1
return line
def __init__(self, file: TextIOWrapper) -> None:
reader = csv.reader(file)
csv_rows = [DatFileLine(row) for row in reader]
self.lines = csv_rows
self.total_count = len(csv_rows)
def count_up_success(self):
self.success_count += 1
def count_up_error(self):
self.error_count += 1
@classmethod
def from_path(cls, local_file_path: str):
"""アルトマークデータファイルを読み込み、新しいインスタンスを作成する
Args:
local_file_path (str): ローカルのファイルパス
Returns:
DatFile: このクラスのインスタンス
"""
# cp932(Shift-JIS Windows拡張)でファイルを読み込む
file = open(local_file_path, encoding='cp932')
instance = cls(file)
file.close()
return instance

View File

@ -0,0 +1,99 @@
"""アルトマークデータ保管"""
from src.aws.s3 import UltmarcBucket
from src.batch.common.batch_config import BatchConfig
from src.batch.ultmarc.datfile import DatFile
from src.batch.ultmarc.utmp_tables.ultmarc_table_mapper_factory import \
UltmarcTableMapperFactory
from src.db.database import Database
from src.logging.get_logger import get_logger
logger = get_logger('アルトマークデータ保管')
ultmarc_bucket = UltmarcBucket()
batch_config = BatchConfig.get_instance()
def exec_import():
"""アルトマーク取り込み処理"""
try:
logger.info('アルトマーク取込処理: 開始')
# datファイルをS3から取得する
dat_file_list = ultmarc_bucket.list_dat_file()
# ファイルがない場合は処理せず、正常終了とする
if len(dat_file_list) == 0:
logger.info('ファイルがないため、アルトマーク取込処理をスキップします')
return
# ファイルが複数ある場合はエラーとする
if len(dat_file_list) > 1:
logger.error(f'複数の取込ファイルがあるため、異常終了 ファイル一覧:{dat_file_list}')
return
# ファイルの件数は必ず1件になる
dat_file_info = dat_file_list[0]
# 0Byteの場合、
if dat_file_info['size'] == 0:
logger.info(f'0Byteファイルのため、処理をスキップします。ファイル名={dat_file_info["filename"]}')
return
dat_file_name = dat_file_info['filename']
logger.info(f"{dat_file_name}を取り込みます")
# ファイルをバックアップ
# 現行は、jobctrl_dailyの先頭でやっている
ultmarc_bucket.backup_dat_file(dat_file_name, batch_config.syor_date)
# datファイルをダウンロード
local_file_path = ultmarc_bucket.download_dat_file(dat_file_name)
dat_file = DatFile.from_path(local_file_path)
# アルトマーク取り込み実行
_import_to_ultmarc_table(dat_file)
# 処理後、ファイルをS3から削除する
logger.info(f'取り込み処理が完了したため、datファイルを削除。ファイル名={dat_file_name}')
ultmarc_bucket.delete_dat_file(dat_file_name)
except Exception as e:
logger.exception(e)
raise e
finally:
logger.info('アルトマーク取込処理: 終了')
def _import_to_ultmarc_table(dat_file: DatFile):
db = Database.get_instance()
# DB接続
db.connect()
# ファイル単位でトランザクションを行う
db.begin()
logger.info('Transaction BEGIN')
mapper_factory = UltmarcTableMapperFactory()
# datファイルを1行ずつ処理し、各テーブルへ登録
for line in dat_file:
try:
# 書き込み先のテーブルを特定
mapper_class = mapper_factory.create(
line.layout_class,
line.records,
db
)
mapper_class.make_query()
mapper_class.execute_queries()
dat_file.count_up_success()
except Exception as e:
logger.warning(e)
record = line.records
log_message = ','.join([f'"{r}"' for r in record])
logger.warning(f'ERROR_LINE: {log_message}')
dat_file.count_up_error()
# すべての行を登録終えたらコミットする
db.commit()
db.disconnect()
# 処理結果をログに出力する
logger.info('Transaction COMMIT')
logger.info(f'ultmarc import process RESULT')
logger.info(f'SUCCESS_COUNT={dat_file.success_count}')
logger.info(f'ERROR_COUNT={dat_file.error_count}')
logger.info(f'ALL_COUNT={dat_file.total_count}')
# 1件でもエラーがあれば、通知用にログに出力する
if dat_file.error_count > 0:
logger.warning('取り込みに失敗した行があります。詳細は`ERROR_LINE:`の行を確認してください。')
return

View File

@ -0,0 +1,8 @@
import glob
import os
# 同階層内のモジュールを一括でインポート
__all__ = [
os.path.split(os.path.splitext(file)[0])[1]
for file in glob.glob(os.path.join(os.path.dirname(__file__), '[a-zA-Z0-9]*.py'))
]

View File

@ -0,0 +1,92 @@
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
from src.batch.ultmarc.utmp_tables.tables.com_alma import ComAlma
class ComAlmaMapper(UltmarcTableMapper):
"""レイアウト区分004: COM_出身校 登録処理"""
# レコード存在確認SQL
RECORD_EXISTS_QUERY = """\
SELECT
COUNT(*) AS count_num
FROM
src05.com_alma
WHERE
alma_cd = :alma_cd
"""
# データ登録用SQL
INSERT_QUERY = """\
INSERT INTO src05.com_alma
(
alma_cd,
alma,
regist_ymd,
sys_regist_date,
regist_prgm_id,
sys_update_date,
update_prgm_id
)
VALUES (
:alma_cd,
:alma,
:execute_date_str_ymd,
:execute_datetime,
:program_name,
:execute_datetime,
:program_name
)
"""
UPDATE_QUERY = """\
UPDATE
src05.com_alma
SET
alma = :alma,
update_ymd = :execute_date_str_ymd,
sys_update_date = :execute_datetime,
update_prgm_id = :program_name
WHERE
alma_cd = :alma_cd
"""
# 修正区分が「C(削除)」の場合の更新SQL
LOGICAL_DELETE_QUERY = """\
UPDATE
src05.com_alma
SET
delete_ymd = :execute_date_str_ymd,
sys_update_date = :execute_date_str_ymd,
update_prgm_id = :program_name
WHERE
alma_cd = :alma_cd
"""
record: ComAlma
def __init__(self, record: list[str], db) -> None:
super().__init__(record, db, ComAlma)
program_name = __name__.split('.')[-1] # 当モジュール名(現行から変わっている)
# モジュール名をクエリパラメータに設定
self.query_parameter['program_name'] = program_name
# 読み込んだレコード値もクエリパラメータに追加
self.query_parameter = {**self.query_parameter, **self.record.to_sql_parameter()}
def make_query(self):
# 修正区分がC(削除)の場合、論理削除
if self.record.maint_flag == 'C':
self.queries.append(self.LOGICAL_DELETE_QUERY)
return
# 追加、更新の場合
self.queries.append(self.__make_upsert_query())
return
def __make_upsert_query(self):
# レコードの存在確認
record_count = self.db.execute_select(self.RECORD_EXISTS_QUERY, self.query_parameter)
# 存在しない場合はInsert
if record_count[0]['count_num'] == 0:
return self.INSERT_QUERY
# 存在する場合はUpdate
return self.UPDATE_QUERY

View File

@ -0,0 +1,257 @@
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
from src.batch.ultmarc.utmp_tables.tables.com_dr_wrkplace import ComDrWrkplace
class ComDrWrkplaceMapper(UltmarcTableMapper):
"""レイアウト区分501-01:COM_医師勤務先 登録処理"""
# レコード存在確認SQL
RECORD_EXISTS_QUERY = """\
SELECT
COUNT(*) AS count_num
FROM
src05.com_dr_wrkplace
WHERE
dcf_pcf_dr_cd = :full_dcfdr_code
AND dcf_dsf_inst_cd = :full_hp_code
"""
# COM_所属部課から所属部科カナと所属部科名を取得するSQL
GET_NAME_FROM_COM_BLNG_SEC_QUERY = """\
SELECT
blng_sec_kana,
blng_sec_name
FROM
src05.com_blng_sec
WHERE
blng_sec_cd = :sectcode
"""
# データ登録用SQL
INSERT_QUERY = """\
INSERT INTO src05.com_dr_wrkplace (
dcf_dsf_inst_cd,
dcf_pcf_dr_cd,
blng_sec_cd,
post_cd,
identity_cd,
aply_start_ymd,
blng_sec_name_kana,
blng_sec_name,
notdm_flg,
regist_ymd,
sys_regist_date,
regist_prgm_id,
sys_update_date,
update_prgm_id
)
VALUES (
:full_hp_code,
:full_dcfdr_code,
:sectcode,
:postcode,
:identitycode,
:syor_date,
:sectname_kana,
:sectname,
:notdm_flg,
:execute_date_str_ymd,
:execute_datetime,
:program_name,
:execute_datetime,
:program_name
)
"""
# 更新用SQL
UPDATE_QUERY = """\
UPDATE src05.com_dr_wrkplace
SET
{update_columns}
update_ymd = :execute_date_str_ymd,
sys_update_date = :execute_datetime,
update_prgm_id = :program_name
WHERE
DCF_PCF_DR_CD= :full_dcfdr_code
AND DCF_DSF_INST_CD = :full_hp_code
"""
# 更新・削除の場合に該当のデータを履歴テーブルに退避するSQL
TO_HISTORY_QUERY = """\
INSERT INTO src05.com_dr_wrkplace_his (
dcf_dsf_inst_cd,
dcf_pcf_dr_cd,
blng_sec_cd,
post_cd,
identity_cd,
aply_start_ymd,
blng_sec_name_kana,
blng_sec_name,
notdm_flg,
aply_end_ymd,
regist_ymd,
sys_regist_date,
regist_prgm_id,
sys_update_date,
update_prgm_id
)
SELECT
dcf_dsf_inst_cd,
dcf_pcf_dr_cd,
(
CASE
WHEN blng_sec_cd = '' THEN '9999'
ELSE blng_sec_cd
END
) AS blng_sec_cd,
(
CASE
WHEN post_cd = '' THEN '999'
ELSE post_cd
END
) AS post_cd,
(
CASE
WHEN identity_cd = '' THEN '999'
ELSE identity_cd
END
) AS identity_cd,
DATE_FORMAT(aply_start_ymd, '%Y%m%d'),
blng_sec_name_kana,
blng_sec_name,
notdm_flg,
(
CASE
WHEN DATE_FORMAT(aply_start_ymd, '%Y%m%d') > DATE_FORMAT(:syor_date, '%Y%m%d') -1 THEN DATE_FORMAT(aply_start_ymd, '%Y%m%d')
ELSE DATE_FORMAT(:syor_date, '%Y%m%d') -1
END
) AS aply_end_ymd,
:execute_date_str_ymd,
:execute_datetime,
:program_name,
:execute_datetime,
:program_name
FROM
src05.com_dr_wrkplace
WHERE
dcf_pcf_dr_cd = :full_dcfdr_code
AND dcf_dsf_inst_cd = :full_hp_code
AND aply_start_ymd < :syor_date
"""
# 退職レコードの場合、物理削除するSQL
PHYSICAL_DELETE_FOR_RETIREMENT_QUERY = """\
DELETE FROM src05.com_dr_wrkplace
WHERE
dcf_pcf_dr_cd = :full_dcfdr_code
AND dcf_dsf_inst_cd = :full_hp_code
"""
record: ComDrWrkplace
def __init__(self, record: list[str], db) -> None:
super().__init__(record, db, ComDrWrkplace)
program_name = __name__.split('.')[-1] # 当モジュール名(現行から変わっている)
# モジュール名をクエリパラメータに設定
self.query_parameter['program_name'] = program_name
# 読み込んだレコード値もクエリパラメータに追加
self.query_parameter = {**self.query_parameter, **self.record.to_sql_parameter()}
def make_query(self):
# 所属部科を取得し、所属部科カナと所属部科名を設定する
self.__set_sect_name_and_sect_name_kana()
# 追加/更新クエリを生成
# 履歴へのレコード登録もあるため、リストで返る
self.queries = self.__make_queries()
return
def __set_sect_name_and_sect_name_kana(self):
# 所属部科を取得し、所属部科カナと所属部科名を設定する
com_blng_sec_records = self.db.execute_select(self.GET_NAME_FROM_COM_BLNG_SEC_QUERY, self.query_parameter)
if len(com_blng_sec_records) == 0:
return
# 必ず1件
com_blng_sec_record = com_blng_sec_records[0]
if com_blng_sec_record['blng_sec_kana'] != '' and com_blng_sec_record['blng_sec_kana'] is not None:
self.record.sectname_kana = com_blng_sec_record['blng_sec_kana']
self.query_parameter['sectname_kana'] = com_blng_sec_record['blng_sec_kana']
if com_blng_sec_record['blng_sec_name'] != '' and com_blng_sec_record['blng_sec_name'] is not None:
self.record.sectname = com_blng_sec_record['blng_sec_name']
self.query_parameter['sectname'] = com_blng_sec_record['blng_sec_name']
def __make_queries(self):
# レコードの存在確認
record_count = self.db.execute_select(self.RECORD_EXISTS_QUERY, self.query_parameter)
# 存在しない場合はInsert
if record_count[0]['count_num'] == 0:
return [self.INSERT_QUERY]
# 存在する場合はUpdate
# 予備/退職異動区分が1(削除:退職)の場合、退職済みのレコードとして処理
if self.record.drretflag == '1':
# 履歴への移動と、退職レコードの物理削除
return [self.TO_HISTORY_QUERY, self.PHYSICAL_DELETE_FOR_RETIREMENT_QUERY]
# 履歴への移動+更新クエリ生成
return self.__make_update_query()
def __make_update_query(self):
make_history_query = None
# 履歴レコード作成判断となる、UPDATE SET句を作成
set_clauses_with_historical = self.__make_update_columns_with_historical()
# 履歴レコード作成判断とならない、UPDATE SET句
set_clause_without_historical = []
# DM不可フラグの値をセット
# 履歴レコード作成判断とならないため、後から設定
if self.record.notdm_flg != '':
notdm_flg = None if self.record.notdm_flg == '@' else self.record.notdm_flg
self.query_parameter['notdm_flg'] = notdm_flg
set_clause_without_historical.append(f'notdm_flg = :notdm_flg')
# 何かしら更新がある場合、履歴作成クエリを作成
if len(set_clauses_with_historical) != 0:
make_history_query = self.TO_HISTORY_QUERY
update_columns = ','.join(set_clauses_with_historical + set_clause_without_historical)
if len(update_columns) > 0:
# 何かしら更新がある場合、末尾にカンマを付けてSET句を完成させる
update_columns += ','
update_query = self.UPDATE_QUERY.format(
update_columns=update_columns
)
return [make_history_query, update_query]
def __make_update_columns_with_historical(self):
# 履歴レコードの作成有無を判断するカラムの更新設定
# DM不可フラグは、履歴レコードの作成判断に使わないため、この関数の外で判定する
set_clauses = []
# 役職コード
if self.record.postcode != '':
set_clauses.append('post_cd = :postcode')
self.query_parameter['postcode'] = '' if self.record.postcode == '@' else self.record.postcode
# 大学順位
if self.record.identitycode != '':
set_clauses.append('identity_cd = :identitycode')
self.query_parameter['identitycode'] = '' if self.record.identitycode == '@' else self.record.identitycode
# 所属部科(集合項目)
if self.record.sectcode != '':
# 所属部科コード
self.query_parameter['sectcode'] = '9999' if self.record.sectcode == '@' else self.record.sectcode
set_clauses.append('blng_sec_cd = :sectcode')
# 所属部科(カナ)
sectname_kana = None if self.record.sectname_kana == '@' else self.record.sectname_kana
self.query_parameter['sectname_kana'] = sectname_kana
set_clauses.append(f'blng_sec_name_kana = :sectname_kana')
# 所属部科(漢字)
# 全角文字なので、修正項目として全角@が連携されるパターンがある
sectname = None if self.record.sectname == '' else self.record.sectname
self.query_parameter['sectname'] = sectname
set_clauses.append(f'blng_sec_name = :sectname')
# 何かしら更新がある場合、適用開始日をセットする
if len(set_clauses) != 0:
# 処理日はパラメータに設定済み
set_clauses.append("aply_start_ymd = DATE_FORMAT(:syor_date, '%Y%m%d')")
return set_clauses

View File

@ -0,0 +1,99 @@
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
from src.batch.ultmarc.utmp_tables.tables.com_hamtec import ComHamtec
class ComHamtecMapper(UltmarcTableMapper):
"""レイアウト区分021: COM_高度先進医療 登録処理"""
# レコード存在確認SQL
RECORD_EXISTS_QUERY = """\
SELECT
COUNT(*) AS count_num
FROM
src05.com_hamtec
WHERE
hamtec_cd = :hamtec_cd
"""
# データ登録用SQL
INSERT_QUERY = """\
INSERT INTO src05.com_hamtec
(
hamtec_cd,
hamtec_div,
hamtec_name,
regist_ymd,
sys_regist_date,
regist_prgm_id,
sys_update_date,
update_prgm_id
)
VALUES (
:hamtec_cd,
:hamtec_div,
:hamtec_name,
:execute_date_str_ymd,
:execute_datetime,
:program_name,
:execute_datetime,
:program_name
)
"""
UPDATE_QUERY = """\
UPDATE
src05.com_hamtec
SET
hamtec_div = :hamtec_div,
hamtec_name = :hamtec_name,
update_ymd = :execute_date_str_ymd,
sys_update_date = :execute_datetime,
update_prgm_id = :program_name
WHERE
hamtec_cd = :hamtec_cd
"""
# 修正区分が「C(削除)」の場合の更新SQL
LOGICAL_DELETE_QUERY = """\
UPDATE
src05.com_hamtec
SET
delete_ymd = :execute_date_str_ymd,
sys_update_date = :execute_date_str_ymd,
update_prgm_id = :program_name
WHERE
hamtec_cd = :hamtec_cd
"""
record: ComHamtec
def __init__(self, record: list[str], db) -> None:
super().__init__(record, db, ComHamtec)
program_name = __name__.split('.')[-1] # 当モジュール名(現行から変わっている)
# モジュール名をクエリパラメータに設定
self.query_parameter['program_name'] = program_name
# 読み込んだレコード値もクエリパラメータに追加
self.query_parameter = {**self.query_parameter, **self.record.to_sql_parameter()}
def make_query(self):
# 修正区分がC(削除)の場合、論理削除
if self.record.maint_flag == 'C':
self.queries.append(self.LOGICAL_DELETE_QUERY)
return
# 追加、更新の場合
self.queries.append(self.__make_upsert_query())
return
def __make_upsert_query(self):
# レコードの存在確認
record_count = self.db.execute_select(self.RECORD_EXISTS_QUERY, self.query_parameter)
# 存在しない場合はInsert
if record_count[0]['count_num'] == 0:
return self.INSERT_QUERY
# 存在する場合はUpdate
# 更新データがある場合のみ更新
if self.record.hamtec_div != '' or self.record.hamtec_name != '':
return self.UPDATE_QUERY
else:
return None

View File

@ -0,0 +1,9 @@
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
class ComInstMapper(UltmarcTableMapper):
"""COM_施設 登録処理: TODO"""
def make_query(self):
self.queries.append(None)

View File

@ -0,0 +1,8 @@
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
class NullMapper(UltmarcTableMapper):
def make_query(self):
return super().make_query()

View File

@ -0,0 +1,50 @@
from abc import ABCMeta, abstractmethod
from datetime import datetime
from src.batch.common.batch_config import BatchConfig
from src.batch.ultmarc.utmp_tables.tables.ultmarc_table import UltmarcTable
from src.db.database import Database
# 処理日を使用するために、configを使用
batch_config = BatchConfig.get_instance()
class UltmarcTableMapper(metaclass=ABCMeta):
"""アルトマークテーブルへの登録処理の抽象クラス"""
record: UltmarcTable
db: Database
queries: list[str]
query_parameter: dict
def __init__(self, record: list[str], db: Database, table_class: type[UltmarcTable]) -> None:
self.record = table_class(record)
self.db = db
# 実行年月日(文字列)、実行年月日時分秒を設定
now = datetime.now()
execute_date_str_ymd = now.strftime('%Y%m%d')
execute_datetime = now.strftime('%Y/%m/%d %H:%M:%S')
# クエリリストを初期化
self.queries = []
# 共通クエリパラメータを設定
self.query_parameter = {
'execute_date_str_ymd': execute_date_str_ymd,
'execute_datetime': execute_datetime,
# バッチ共通設定から処理日を取得
'syor_date': batch_config.syor_date
}
@abstractmethod
def make_query(self):
pass
def execute_queries(self):
if len(self.queries) == 0:
raise Exception('make_queryを呼び出してから実行してください')
for query in self.queries:
if query is None:
continue
self.db.execute(query, self.query_parameter)

View File

@ -0,0 +1,14 @@
from src.batch.ultmarc.utmp_tables.tables.ultmarc_table import UltmarcTable
class ComAlma(UltmarcTable):
"""レイアウト区分004: COM_出身校"""
maint_flag: str # 修正区分
alma_cd: str # 出身校コード
alma: str # 出身校
def __init__(self, record: list[str]):
super().__init__(record)
self.maint_flag = record[2]
self.alma_cd = record[1]
self.alma = record[5]

View File

@ -0,0 +1,49 @@
from src.batch.ultmarc.utmp_tables.tables.ultmarc_table import UltmarcTable
class ComDrWrkplace(UltmarcTable):
"""レイアウト区分501-01:COM_医師勤務先"""
maint_flag: str # 修正区分
dcfdr_id: str # 個人コードID
dcfdr_code: str # 個人コード(個人コード)
dcfdr_yobi: str # 個人コード(予備)
hp_id: str # 施設コードID
hp_code: str # 施設コード(施設コード)
hp_yobi: str # 施設コード(予備)
drretflag: str # 予備/退職異動区分
maintdate: str # メンテナンス年月日
trndate: str # 予備/転送年月日
postcode: str # 役職コード
identitycode: str # 大学職位
sectcode: str # 所属部科コード
sectname: str # 所属部科(漢字)
sectname_kana: str # 所属部科(カナ)
notdm_flg: str # DM不可フラグ
full_dcfdr_code: str # 個人ID+個人コード+個人コード予備
full_hp_code: str # 施設ID+施設コード+施設コード予備
def __init__(self, record: list[str]):
super().__init__(record)
self.maintflag = record[4]
self.dcfdr_id = record[1]
self.dcfdr_code = record[2]
self.dcfdr_yobi = record[3].strip()
self.hp_id = record[5]
self.hp_code = record[6]
self.hp_yobi = record[7].strip()
self.drretflag = record[8]
self.maintdate = record[9]
self.trndate = record[10]
self.postcode = record[11].strip()
self.identitycode = record[12].strip()
# 所属部科の集合項目
self.sectcode = record[13].strip()
self.sectname = record[14].strip()
self.sectname_kana = record[15].strip()
self.notdm_flg = record[16].strip()
# ID、コード、予備を結合してフル桁コードに変換
self.full_dcfdr_code = ''.join([self.dcfdr_id, self.dcfdr_code, self.dcfdr_yobi])
self.full_hp_code = ''.join([self.hp_id, self.hp_code, self.hp_yobi])

View File

@ -0,0 +1,16 @@
from src.batch.ultmarc.utmp_tables.tables.ultmarc_table import UltmarcTable
class ComHamtec(UltmarcTable):
"""レイアウト区分021: COM_高度先進医療"""
maint_flag: str # 修正区分
hamtec_cd: str # 高度先進医療コード
hamtec_div: str # 高度先進医療区分
hamtec_name: str # 高度先進医療名
def __init__(self, record: list[str]):
super().__init__(record)
self.maint_flag = record[3]
self.hamtec_cd = record[1]
self.hamtec_div = record[2]
self.hamtec_name = record[6]

View File

@ -0,0 +1,9 @@
class UltmarcTable:
"""アルトマーク関連テーブルの抽象クラス"""
record: list
def __init__(self, record: list):
self.record = record
def to_sql_parameter(self):
return vars(self)

View File

@ -0,0 +1,107 @@
from src.batch.ultmarc.utmp_tables.table_mapper.concrete import (
com_alma_mapper, com_dr_wrkplace_mapper, com_hamtec_mapper,
com_inst_mapper, null_mapper)
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
from src.db.database import Database
# テーブルとのマッピング
COM_TABLE_LIST = {
# レコードID固定
# COM_医師学会
# TODO: 入れ子にしない
"521": null_mapper.NullMapper,
# COM_施設属性
"111": null_mapper.NullMapper,
# COM_臨床研修病院
"112": null_mapper.NullMapper,
# COM_医師
"501": null_mapper.NullMapper,
# COM_施設
"101": com_inst_mapper.ComInstMapper,
# COM_薬局
"102": null_mapper.NullMapper,
# COM_医師勤務先
"502": com_dr_wrkplace_mapper.ComDrWrkplaceMapper,
# COM_専門分野
"511": null_mapper.NullMapper,
# COM_都道府県医療機能情報(基本)
"132": null_mapper.NullMapper,
# COM_都道府県医療機能情報(施設設備)
"133": null_mapper.NullMapper,
# COM_都道府県医療機能情報(疾患治療)
"134": null_mapper.NullMapper,
# COM_都道府県医療機能情報(短期滞在手術)
"135": null_mapper.NullMapper,
# COM_都道府県医療機能情報(専門外来)
"136": null_mapper.NullMapper,
# COM_診療科目
"001": null_mapper.NullMapper,
# COM_病院種別
"002": null_mapper.NullMapper,
# COM_出身校学部識別
"003": null_mapper.NullMapper,
# COM_出身校
"004": com_alma_mapper.ComAlmaMapper,
# COM_役職
"005": null_mapper.NullMapper,
# 都道府県マスタ
"006": null_mapper.NullMapper,
# COM_経営体
"007": null_mapper.NullMapper,
# COM_所属部科
"008": null_mapper.NullMapper,
# COM_学会
"009": null_mapper.NullMapper,
# COM_専門医資格
"010": null_mapper.NullMapper,
# COM_施設区分
"011": null_mapper.NullMapper,
# COM_高度先進医療
"021": com_hamtec_mapper.ComHamtecMapper,
# COM_先端医療機器
"022": null_mapper.NullMapper,
# COM_看護種別
"023": null_mapper.NullMapper,
# COM_医療機能評価
"024": null_mapper.NullMapper,
# COM_地域クリティカルパス
"026": null_mapper.NullMapper,
# COM_疾患別リハビリテーション科
"027": null_mapper.NullMapper,
# COM_政策医療
"028": null_mapper.NullMapper,
# COM_医療圏都道府県
"121": null_mapper.NullMapper,
# COM_医療圏次マスタ
"122": null_mapper.NullMapper,
# COM_二次医療圏
"123": null_mapper.NullMapper,
# COM_医療圏都道府県市町村対照表
"124": null_mapper.NullMapper
}
class UltmarcTableMapperFactory:
def create(self, layout_class: str, records: list[str], db: Database) -> UltmarcTableMapper:
"""レイアウト区分とレコードIDから、マッピング先のテーブルマッパーを特定する
Args:
layout_class (str): レイアウト区分
records (list[str]): アルトマークデータの1行
db (Database): データベース操作クラス
Raises:
Exception: レイアウトを特定できない場合
Returns:
UltmarcTableMapper: マッパークラス
"""
# レイアウト区分から、マッピング先のテーブルを特定
mapper_class = COM_TABLE_LIST.get(layout_class)
# レイアウト区分が特定できない場合はエラーとする
if mapper_class is None:
raise Exception(f'マッピング先のテーブルを特定できませんでした。レイアウト区分={layout_class}')
return mapper_class(records, db)

View File

@ -1,6 +1,5 @@
from sqlalchemy import (Connection, CursorResult, Engine, QueuePool,
create_engine, text)
from sqlalchemy.engine.create import create_engine
from sqlalchemy.engine.url import URL
from tenacity import retry, stop_after_attempt, wait_exponential
@ -10,6 +9,7 @@ from src.system_var import environment
logger = get_logger(__name__)
class Database:
"""データベース操作クラス"""
__connection: Connection = None
@ -19,8 +19,7 @@ class Database:
__username: str = None
__password: str = None
__schema: str = None
__connection_string:str = None
__connection_string: str = None
def __init__(self, username: str, password: str, host: str, port: int, schema: str) -> None:
"""このクラスの新たなインスタンスを初期化します
@ -37,9 +36,9 @@ class Database:
self.__host = host
self.__port = int(port)
self.__schema = schema
self.__connection_string = URL.create(
drivername='mysql+pymysql',
drivername='mysql+pymysql',
username=self.__username,
password=self.__password,
host=self.__host,
@ -47,12 +46,11 @@ class Database:
database=self.__schema,
query={"charset": "utf8mb4"}
)
self.__engine = create_engine(
self.__connection_string,
pool_timeout=5,
poolclass=QueuePool,
isolation_level="AUTOCOMMIT"
poolclass=QueuePool
)
@classmethod
@ -83,7 +81,10 @@ class Database:
Raises:
DBException: 接続失敗
"""
self.__connection = self.__engine.connect()
try:
self.__connection = self.__engine.connect()
except Exception as e:
raise DBException(f'SQL Error: {e}')
def execute_select(self, select_query: str, parameters=None) -> list[dict]:
"""SELECTクエリを実行します。
@ -100,10 +101,18 @@ class Database:
"""
if self.__connection is None:
raise DBException('DBに接続していません')
result = None
try:
result = self.__connection.execute(text(select_query), parameters=parameters)
# トランザクションが開始している場合は、トランザクションを引き継ぐ
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(e)
raise DBException(f'SQL Error: {e}')
result_rows = result.mappings().all()
return result_rows
@ -122,10 +131,18 @@ class Database:
"""
if self.__connection is None:
raise DBException('DBに接続していません')
result = None
try:
result = self.__connection.execute(text(query), parameters=parameters)
# トランザクションが開始している場合は、トランザクションを引き継ぐ
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(e)
raise DBException(f'SQL Error: {e}')
return result
def begin(self):
@ -148,3 +165,14 @@ class Database:
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

View File

@ -4,11 +4,14 @@ from tenacity import RetryError
class MeDaCaException(Exception):
pass
class DBException(MeDaCaException):
pass
class BatchOperationException(MeDaCaException):
pass
class MaxRetryExceededException(MeDaCaException, RetryError):
pass
pass

View File

@ -1,10 +1,16 @@
from src.batch import jissekiaraigae
from src.batch.batch_functions import get_syor_date
from src.batch.batch_functions import get_syor_date_as_date_format
from src.batch.common.batch_config import BatchConfig
from src.batch.ultmarc import ultmarc_process
from src.error.exceptions import BatchOperationException
from src.logging.get_logger import get_logger
logger = get_logger('日次処理コントロール') # ここを処理IDとかにするといいかもしれない
# バッチ共通設定を取得
batch_config = BatchConfig.get_instance()
def batch_process():
try:
logger.info('日次ジョブ:開始')
@ -15,14 +21,16 @@ def batch_process():
# logger.error('データベース接続エラー(異常終了)') # 検査例外を捕まえて、共通的に出せばいいと思う
try:
logger.info('処理日取得')
syor_date = get_syor_date()
except BatchOperationException as e:
syor_date = get_syor_date_as_date_format()
except BatchOperationException as e:
logger.error(f'処理日取得エラー(異常終了){e}')
logger.info(f'処理日={syor_date}')
# バッチ共通設定に処理日を追加
batch_config.syor_date = syor_date
# 休日判定ファイルを読み込み
logger.info('休日判定処理')
if True: # 休日判定
logger.info('非営業日かつ月、火、水以外です。') # 分岐
logger.info('非営業日かつ月、火、水以外です。') # 分岐
try:
# 処理中フラグ判定。ここでdumpのフラグも見る
logger.info('処理フラグ更新中')
@ -32,7 +40,7 @@ def batch_process():
logger.info('日次ジョブ:終了(正常終了)')
try:
logger.info('日次ジョブ処理中判定')
if True: # 処理中判定
if True: # 処理中判定
logger.error('処理フラグ処理中(異常終了)')
logger.info('処理中フラグの更新:起動')
logger.info('処理中フラグの更新:終了')
@ -54,21 +62,22 @@ def batch_process():
logger.debug('卸在庫データファイル名作成: {read_filename}')
logger.debug('ファイル移動OK{_MOVE_OROSHI_ZAIKO}') # S3からダウンロード
logger.debug('ファイル解凍OK{sprintf(_ZIP_OROSHI_ZAIKO, $read_filename)}') # gunzip -fなので、gzipを使う
logger.debug('ファイル名変更OK {sprintf(_RENAME_OROSHI_ZAIKO, $read_filename)}') #S3にアップロード
logger.debug('ファイル名変更OK {sprintf(_RENAME_OROSHI_ZAIKO, $read_filename)}') # S3にアップロード
try:
logger.info('卸在庫データ取込:起動')
logger.info('卸在庫データ取込:終了')
except BatchOperationException as e:
logger.error(f'卸在庫データ取込処理エラー(異常終了){e}')
logger.info('日次処理(アルトマーク)')
if True: # アルトマークなければ
if True: # アルトマークなければ
logger.info('日次処理(アルトマーク)実行対象日でない為未実行')
try:
logger.info('アルトマーク取込:起動')
ultmarc_process.exec_import()
logger.info('アルトマーク取込:終了')
except BatchOperationException as e:
logger.error(f'アルトマーク取込処理エラー(異常終了){e}')
if True: # 休日判定
if True: # 休日判定
try:
logger.info('メルク施設マスタ作成')
logger.info('メルク施設マスタ作成終了')
@ -83,7 +92,7 @@ def batch_process():
logger.info('V実消化連携データ存在確認')
if True:
logger.error('V実消化連携データ存在確認異常終了')
logger.info('日次処理V実消化')
try:
logger.info('V実消化取込起動')
@ -111,7 +120,7 @@ def batch_process():
logger.exception(f'処理中フラグ更新エラー(異常終了){e}')
logger.info('ワークディレクトリクリーニング')
logger.info('日次ジョブ:終了(正常終了)')
return 0
except Exception as e:
raise e

View File

@ -6,8 +6,16 @@ from src.system_var.environment import LOG_LEVEL
for name in ["boto3", "botocore", "s3transfer", "urllib3"]:
logging.getLogger(name).setLevel(logging.WARNING)
# 共通ロガー
def get_logger(log_name):
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):

View File

@ -1,12 +1,20 @@
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']
LOG_LEVEL = os.environ['LOG_LEVEL']
# AWS
ULTMARC_DATA_BUCKET = os.environ['ULTMARC_DATA_BUCKET']
ULTMARC_DATA_FOLDER = os.environ['ULTMARC_DATA_FOLDER']
ULTMARC_BACKUP_BUCKET = os.environ['ULTMARC_BACKUP_BUCKET']
ULTMARC_BACKUP_FOLDER = os.environ['ULTMARC_BACKUP_FOLDER']
# 初期値がある環境変数
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))

View File

View File

@ -0,0 +1,7 @@
"004","001","A","20141113","20141114","北大"
"004","002","A","20141113","20141114","札幌医"
"004","003","A","20141113","20141114","弘大"
"004","004","A","20141113","20141114",
"004","005","A","20141113","20141114","東北大"
"004","006","C","20141113","20141114","福島医"
"004","007","A","20141113","20141114","群馬大"
1 004 001 A 20141113 20141114 北大
2 004 002 A 20141113 20141114 札幌医
3 004 003 A 20141113 20141114 弘大
4 004 004 A 20141113 20141114
5 004 005 A 20141113 20141114 東北大
6 004 006 C 20141113 20141114 福島医
7 004 007 A 20141113 20141114 群馬大

View File

@ -0,0 +1,6 @@
"004","001","A","20141113","20141114","北大"
"004","002","A","20141113","20141114","札幌医"
"004","003","A","20141113","20141114","弘大"
"004","004","A","20141113","20141114","岩手医"
"004","005","A","20141113","20141114","東北大"
"004","006","A","20141113","20141114","福島医"
1 004 001 A 20141113 20141114 北大
2 004 002 A 20141113 20141114 札幌医
3 004 003 A 20141113 20141114 弘大
4 004 004 A 20141113 20141114 岩手医
5 004 005 A 20141113 20141114 東北大
6 004 006 A 20141113 20141114 福島医

View File

@ -0,0 +1,7 @@
"004","001","B","20141113","20141114","北大"
"004","002","B","20141113","20141114","札幌医"
"004","003","B","20141113","20141114","弘大"
"004","004","B","20141113","20141114",
"004","005","B","20141113","20141114","福島医"
"004","006","B","20141113","20141114","東北大"
"004","007","A","20141113","20141114","神大"
1 004 001 B 20141113 20141114 北大
2 004 002 B 20141113 20141114 札幌医
3 004 003 B 20141113 20141114 弘大
4 004 004 B 20141113 20141114
5 004 005 B 20141113 20141114 福島医
6 004 006 B 20141113 20141114 東北大
7 004 007 A 20141113 20141114 神大

View File

@ -0,0 +1,7 @@
"alma_cd","alma","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","北大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","clsComAlma"
"002","札幌医","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","clsComAlma"
"003","弘大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","clsComAlma"
"004",,"20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","clsComAlma"
"005","東北大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","clsComAlma"
"006","福島医","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","clsComAlma"
1 alma_cd alma regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 北大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 clsComAlma
3 002 札幌医 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 clsComAlma
4 003 弘大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 clsComAlma
5 004 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 clsComAlma
6 005 東北大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 clsComAlma
7 006 福島医 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 clsComAlma

View File

@ -0,0 +1,7 @@
"alma_cd","alma","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","北大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:27:33","clsComAlma"
"002","札幌医","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:27:33","clsComAlma"
"003","弘大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:27:33","clsComAlma"
"004","岩手医","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:27:33","clsComAlma"
"005","東北大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:27:33","clsComAlma"
"006","福島医","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:27:33","clsComAlma"
1 alma_cd alma regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 北大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:27:33 clsComAlma
3 002 札幌医 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:27:33 clsComAlma
4 003 弘大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:27:33 clsComAlma
5 004 岩手医 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:27:33 clsComAlma
6 005 東北大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:27:33 clsComAlma
7 006 福島医 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:27:33 clsComAlma

View File

@ -0,0 +1,8 @@
"alma_cd","alma","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","北大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:43:15","com_alma_mapper"
"002","札幌医","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:43:15","com_alma_mapper"
"003","弘大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:43:15","com_alma_mapper"
"004","","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:43:15","com_alma_mapper"
"005","東北大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:43:15","com_alma_mapper"
"006","福島医","20171020","20171020","20171020","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:43:15","com_alma_mapper"
"007","群馬大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:43:15","com_alma_mapper","2017/10/20 10:43:15","com_alma_mapper"
1 alma_cd alma regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 北大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:43:15 com_alma_mapper
3 002 札幌医 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:43:15 com_alma_mapper
4 003 弘大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:43:15 com_alma_mapper
5 004 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:43:15 com_alma_mapper
6 005 東北大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:43:15 com_alma_mapper
7 006 福島医 20171020 20171020 20171020 NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:43:15 com_alma_mapper
8 007 群馬大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:43:15 com_alma_mapper 2017/10/20 10:43:15 com_alma_mapper

View File

@ -0,0 +1,7 @@
"alma_cd","alma","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","北大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:27:33","com_alma_mapper"
"002","札幌医","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:27:33","com_alma_mapper"
"003","弘大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:27:33","com_alma_mapper"
"004","岩手医","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:27:33","com_alma_mapper"
"005","東北大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:27:33","com_alma_mapper"
"006","福島医","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:27:33","com_alma_mapper"
1 alma_cd alma regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 北大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:27:33 com_alma_mapper
3 002 札幌医 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:27:33 com_alma_mapper
4 003 弘大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:27:33 com_alma_mapper
5 004 岩手医 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:27:33 com_alma_mapper
6 005 東北大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:27:33 com_alma_mapper
7 006 福島医 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:27:33 com_alma_mapper

View File

@ -0,0 +1,8 @@
"alma_cd","alma","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","北大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","com_alma_mapper"
"002","札幌医","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","com_alma_mapper"
"003","弘大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","com_alma_mapper"
"004",,"20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","com_alma_mapper"
"005","福島医","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","com_alma_mapper"
"006","東北大","20171020","20171020","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","clsComAlma","2017/10/20 10:35:27","com_alma_mapper"
"007","神大","20171020","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/20 10:27:33","com_alma_mapper","2017/10/20 10:35:27","com_alma_mapper"
1 alma_cd alma regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 北大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 com_alma_mapper
3 002 札幌医 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 com_alma_mapper
4 003 弘大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 com_alma_mapper
5 004 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 com_alma_mapper
6 005 福島医 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 com_alma_mapper
7 006 東北大 20171020 20171020 NULL NULL NULL NULL NULL 2017/10/20 10:27:33 clsComAlma 2017/10/20 10:35:27 com_alma_mapper
8 007 神大 20171020 NULL NULL NULL NULL NULL NULL 2017/10/20 10:27:33 com_alma_mapper 2017/10/20 10:35:27 com_alma_mapper

View File

@ -0,0 +1,197 @@
import os.path as path
from datetime import datetime
import pytest
from src.batch.common.batch_config import BatchConfig
from src.batch.ultmarc.utmp_tables.table_mapper.concrete import com_alma_mapper
from src.db.database import Database
from tests.testing_utility import (assert_table_results,
create_db_data_from_csv,
create_delete_sql_with_parameter,
create_insert_sql_with_parameter,
create_ultmarc_table_mapper_sut,
create_ultmarc_test_data_from_csv)
class TestComAlmaMapper:
"""レイアウト区分004: COM_出身校"""
db: Database
batch_config: BatchConfig
test_file_path: str = path.dirname(__file__)
@pytest.fixture(autouse=True, scope='function')
def pre_test(self, database: Database):
"""テスト実行前後処理"""
self.batch_config = BatchConfig.get_instance()
# setup
self.db = database
self.db.connect()
self.db.begin()
# testing
yield
# teardown
self.db.rollback()
self.db.disconnect()
def test_insert_record(self):
"""
Cases:
COM_出身校テーブルにレコードを登録する
Arranges:
- CSVデータを用意し読み込む
- 追加対象となるレコードを削除する
Expects:
- 登録内容が期待値と一致すること
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = datetime.strftime(datetime.now(), '%Y/%m/%d')
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_alma_insert.csv'))
# 一旦全データをDBから削除
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_alma', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_alma_mapper.ComAlmaMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_alma_mapper.ComAlmaMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_alma_insert.csv'))
primary_keys = [f"'{primary_key['alma_cd']}'" for primary_key in expect_data_list]
actual_select_sql = f"SELECT * FROM src05.com_alma WHERE alma_cd IN ({','.join(primary_keys)})"
actual_data_list = self.db.execute_select(actual_select_sql)
# 期待値検査
ignore_columns = ['regist_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_data_list, expect_data_list, ignore_col_name=ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_data_list, expect_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ['regist_ymd', 'sys_regist_date', 'sys_update_date']:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
def test_update_record(self):
"""
Cases:
COM_出身校テーブルのレコードを更新する
Arranges:
- CSVデータを用意し読み込む
- 更新対象となるレコードを登録する
Expects:
- 登録内容が期待値と一致すること
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = datetime.strftime(datetime.now(), '%Y/%m/%d')
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_alma_update.csv'))
# 一旦全データをDBから削除
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_alma', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# テストデータをDBに登録
# DBデータを読み込む
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_alma_before_update.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_alma',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_alma_mapper.ComAlmaMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_alma_mapper.ComAlmaMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_alma_update.csv'))
primary_keys = [f"'{primary_key['alma_cd']}'" for primary_key in expect_data_list]
actual_select_sql = f"SELECT * FROM src05.com_alma WHERE alma_cd IN ({','.join(primary_keys)})"
actual_data_list = self.db.execute_select(actual_select_sql)
# 期待値検査
ignore_columns = ['regist_ymd', 'update_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_data_list, expect_data_list, ignore_col_name=ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_data_list, expect_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
def test_logical_delete(self):
"""
Cases:
COM_出身校テーブルのレコードを1件論理削除する
Arranges:
- CSVデータを用意し読み込む
- 削除対象となるレコードを登録する
Expects:
- 登録内容が期待値と一致すること
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = datetime.strftime(datetime.now(), '%Y/%m/%d')
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_alma_delete.csv'))
# 一旦全データをDBから削除
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_alma', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# テストデータをDBに登録
# DBデータを読み込む
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_alma_before_delete.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_alma',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_alma_mapper.ComAlmaMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_alma_mapper.ComAlmaMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_alma_delete.csv'))
primary_keys = [f"'{primary_key['alma_cd']}'" for primary_key in expect_data_list]
actual_select_sql = f"SELECT * FROM src05.com_alma WHERE alma_cd IN ({','.join(primary_keys)})"
actual_data_list = self.db.execute_select(actual_select_sql)
# 期待値検査
ignore_columns = ['regist_ymd', 'update_ymd', 'delete_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_data_list, expect_data_list, ignore_col_name=ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_data_list, expect_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'

View File

@ -0,0 +1,5 @@
"502","01","997682","","B","00","5408060","","1","20141204","20141206","","","1512","","",""
"502","01","997906","","B","00","5409446","","1","20141128","20141206","","","6802","","",""
"502","01","997682","","B","00","5412977","","1","20141204","20141206","","","6720","","",""
"502","01","995783","","B","00","5414992","","1","20141204","20141206","","","1118","","",""
"502","01","997906","","B","00","5503358","","1","20141202","20141206","","","7212","","",""
1 502 01 997682 B 00 5408060 1 20141204 20141206 1512
2 502 01 997906 B 00 5409446 1 20141128 20141206 6802
3 502 01 997682 B 00 5412977 1 20141204 20141206 6720
4 502 01 995783 B 00 5414992 1 20141204 20141206 1118
5 502 01 997906 B 00 5503358 1 20141202 20141206 7212

View File

@ -0,0 +1,10 @@
"502","01","995783","","A","00","5414992","","2","20141113","20141114","501","","","","",""
"502","01","995783","","A","00","5507600","","2","20141113","20141114","133","144","9112","","",""
"502","01","997682","","A","00","5402984","","2","20141113","20141114","165","144","1512","","",""
"502","01","997682","","A","00","5408060","","2","20141113","20141114","","144","6802","","",""
"502","01","997682","","A","00","5412977","","2","20141113","20141114","","144","6720","","",""
"502","01","997906","","A","00","5409446","","2","20141113","20141114","501","","1118","","",""
"502","01","997906","","A","00","5503358","","2","20141113","20141114","172","144","1118","","",""
"502","01","997906","","A","00","5504428","","2","20141113","20141114","","144","7212","","",""
"502","01","997906","","A","00","5507600","","2","20141113","20141114","","144","9114","","",""
"502","01","999613","","A","00","5504428","","2","20141113","20141114","","144","5140","","",""
1 502 01 995783 A 00 5414992 2 20141113 20141114 501
2 502 01 995783 A 00 5507600 2 20141113 20141114 133 144 9112
3 502 01 997682 A 00 5402984 2 20141113 20141114 165 144 1512
4 502 01 997682 A 00 5408060 2 20141113 20141114 144 6802
5 502 01 997682 A 00 5412977 2 20141113 20141114 144 6720
6 502 01 997906 A 00 5409446 2 20141113 20141114 501 1118
7 502 01 997906 A 00 5503358 2 20141113 20141114 172 144 1118
8 502 01 997906 A 00 5504428 2 20141113 20141114 144 7212
9 502 01 997906 A 00 5507600 2 20141113 20141114 144 9114
10 502 01 999613 A 00 5504428 2 20141113 20141114 144 5140

View File

@ -0,0 +1,5 @@
"502","01","997906","","B","00","5409446","","","20170906","20170910","","","","","","@"
"502","01","995783","","B","00","5507600","","","20170907","20170910","@","802","@","","@",""
"502","01","997682","","A","00","5408060","","","20141113","20141114","","","","","",""
"502","01","997682","","B","00","5402984","","","20141113","20141114","165","@","","","",""
"502","01","999613","","B","00","5504428","","2","20170328","20170401","501","","9999","内分泌・骨代謝外来","ナイブンピ.ホネタイシヤガイライ",""
1 502 01 997906 B 00 5409446 20170906 20170910 @
2 502 01 995783 B 00 5507600 20170907 20170910 @ 802 @ @
3 502 01 997682 A 00 5408060 20141113 20141114
4 502 01 997682 B 00 5402984 20141113 20141114 165 @
5 502 01 999613 B 00 5504428 2 20170328 20170401 501 9999 内分泌・骨代謝外来 ナイブンピ.ホネタイシヤガイライ

View File

@ -0,0 +1,6 @@
"blng_sec_cd","blng_sec_kana","blng_sec_name","regist_ymd","update_ymd","delete_ymd","inst_category","trt_category","category_sort","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"1512",,NULL,"20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2022-05-16 22:18:28","clsComBlngSec"
"6802","NULL",,"20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2022-05-30 22:18:48","clsComBlngSec"
"6720",,"NULL","20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2019-12-23 22:13:44","clsComBlngSec"
"1118","NULL",,"20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2016-05-17 00:13:18","clsComBlngSec"
"7212",,"NULL","20150818","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-18 00:12:58","clsComBlngSec","2021-01-11 22:15:40","clsComBlngSec"
1 blng_sec_cd blng_sec_kana blng_sec_name regist_ymd update_ymd delete_ymd inst_category trt_category category_sort regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 1512 NULL 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2022-05-16 22:18:28 clsComBlngSec
3 6802 NULL 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2022-05-30 22:18:48 clsComBlngSec
4 6720 NULL 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2019-12-23 22:13:44 clsComBlngSec
5 1118 NULL 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2016-05-17 00:13:18 clsComBlngSec
6 7212 NULL 20150818 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-18 00:12:58 clsComBlngSec 2021-01-11 22:15:40 clsComBlngSec

View File

@ -0,0 +1,9 @@
"blng_sec_cd","blng_sec_kana","blng_sec_name","regist_ymd","update_ymd","delete_ymd","inst_category","trt_category","category_sort","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"1512","シヨウカキゲカ","消化器外科","20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2022-05-16 22:18:28","clsComBlngSec"
"6802","シヨウカキゲカガク1","消化器外科学Ⅰ","20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2022-05-30 22:18:48","clsComBlngSec"
"6720","シヨウカキゲカガク","消化器外科学","20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2019-12-23 22:13:44","clsComBlngSec"
"1118","ケツエキナイカ","血液内科","20150825","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-25 00:10:58","clsComBlngSec","2016-05-17 00:13:18","clsComBlngSec"
"7212","ユケツ.サイボウチリヨウガク","輸血・細胞治療学","20150818","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-18 00:12:58","clsComBlngSec","2021-01-11 22:15:40","clsComBlngSec"
"5140","ヤクリガク","薬理学","20150818","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-18 00:12:58","clsComBlngSec","2022-08-22 22:23:47","clsComBlngSec"
"9112","ハツセイ.セイシヨクブモン","発生・生殖部門","20150818","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-18 00:12:58","clsComBlngSec","2022-08-01 22:23:53","clsComBlngSec"
"9114","サイボウイシヨクブモン","細胞移植部門","20150818","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","2015-08-18 00:12:58","clsComBlngSec","2022-08-01 22:23:53","clsComBlngSec"
1 blng_sec_cd blng_sec_kana blng_sec_name regist_ymd update_ymd delete_ymd inst_category trt_category category_sort regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 1512 シヨウカキゲカ 消化器外科 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2022-05-16 22:18:28 clsComBlngSec
3 6802 シヨウカキゲカガク1 消化器外科学Ⅰ 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2022-05-30 22:18:48 clsComBlngSec
4 6720 シヨウカキゲカガク 消化器外科学 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2019-12-23 22:13:44 clsComBlngSec
5 1118 ケツエキナイカ 血液内科 20150825 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-25 00:10:58 clsComBlngSec 2016-05-17 00:13:18 clsComBlngSec
6 7212 ユケツ.サイボウチリヨウガク 輸血・細胞治療学 20150818 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-18 00:12:58 clsComBlngSec 2021-01-11 22:15:40 clsComBlngSec
7 5140 ヤクリガク 薬理学 20150818 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-18 00:12:58 clsComBlngSec 2022-08-22 22:23:47 clsComBlngSec
8 9112 ハツセイ.セイシヨクブモン 発生・生殖部門 20150818 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-18 00:12:58 clsComBlngSec 2022-08-01 22:23:53 clsComBlngSec
9 9114 サイボウイシヨクブモン 細胞移植部門 20150818 NULL NULL NULL NULL NULL NULL NULL NULL NULL 2015-08-18 00:12:58 clsComBlngSec 2022-08-01 22:23:53 clsComBlngSec

View File

@ -0,0 +1,11 @@
"dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"005414992","01995783",,"501",,"2020-02-22",,,,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01995783","9999",,"802","2020-02-23",,,,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
"005402984","01997682","1512","165",,"2020-02-23","シヨウカキゲカ","消化器外科",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
"005408060","01997682","6802",,"144","2020-02-22","シヨウカキゲカガク1","消化器外科学Ⅰ",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005412977","01997682","6720",,"144","2020-02-22","シヨウカキゲカガク","消化器外科学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005409446","01997906","1118","501",,"2020-02-22","ケツエキナイカ","血液内科",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
"005503358","01997906","1118","172","144","2020-02-22","ケツエキナイカ","血液内科",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01997906","7212",,"144","2020-02-22","ユケツ.サイボウチリヨウガク","輸血・細胞治療学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01997906","9114",,"144","2020-02-22","サイボウイシヨクブモン","細胞移植部門",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01999613","9999","501","144","2020-02-23","ナイブンピ.ホネタイシヤガイライ","内分泌・骨代謝外来",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
1 dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 005414992 01995783 501 2020-02-22 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
3 005507600 01995783 9999 802 2020-02-23 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk
4 005402984 01997682 1512 165 2020-02-23 シヨウカキゲカ 消化器外科 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk
5 005408060 01997682 6802 144 2020-02-22 シヨウカキゲカガク1 消化器外科学Ⅰ 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
6 005412977 01997682 6720 144 2020-02-22 シヨウカキゲカガク 消化器外科学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
7 005409446 01997906 1118 501 2020-02-22 ケツエキナイカ 血液内科 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk
8 005503358 01997906 1118 172 144 2020-02-22 ケツエキナイカ 血液内科 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
9 005504428 01997906 7212 144 2020-02-22 ユケツ.サイボウチリヨウガク 輸血・細胞治療学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
10 005507600 01997906 9114 144 2020-02-22 サイボウイシヨクブモン 細胞移植部門 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
11 005504428 01999613 9999 501 144 2020-02-23 ナイブンピ.ホネタイシヤガイライ 内分泌・骨代謝外来 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk

View File

@ -0,0 +1,11 @@
"dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"005414992","01995783",,"501",,"2020-02-22",,,,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01995783","9112","133","144","2020-02-22","ハツセイ.セイシヨクブモン","発生・生殖部門","1","2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005402984","01997682","1512","165","144","2020-02-22","シヨウカキゲカ","消化器外科",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005408060","01997682","6802",,"144","2020-02-22","シヨウカキゲカガク1","消化器外科学Ⅰ",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005412977","01997682","6720",,"144","2020-02-22","シヨウカキゲカガク","消化器外科学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005409446","01997906","1118","501",,"2020-02-22","ケツエキナイカ","血液内科","1","2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005503358","01997906","1118","172","144","2020-02-22","ケツエキナイカ","血液内科",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01997906","7212",,"144","2020-02-22","ユケツ.サイボウチリヨウガク","輸血・細胞治療学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01997906","9114",,"144","2020-02-22","サイボウイシヨクブモン","細胞移植部門",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01999613","5140",,"144","2020-02-22","ヤクリガク","薬理学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
1 dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 005414992 01995783 501 2020-02-22 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
3 005507600 01995783 9112 133 144 2020-02-22 ハツセイ.セイシヨクブモン 発生・生殖部門 1 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
4 005402984 01997682 1512 165 144 2020-02-22 シヨウカキゲカ 消化器外科 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
5 005408060 01997682 6802 144 2020-02-22 シヨウカキゲカガク1 消化器外科学Ⅰ 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
6 005412977 01997682 6720 144 2020-02-22 シヨウカキゲカガク 消化器外科学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
7 005409446 01997906 1118 501 2020-02-22 ケツエキナイカ 血液内科 1 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
8 005503358 01997906 1118 172 144 2020-02-22 ケツエキナイカ 血液内科 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
9 005504428 01997906 7212 144 2020-02-22 ユケツ.サイボウチリヨウガク 輸血・細胞治療学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
10 005507600 01997906 9114 144 2020-02-22 サイボウイシヨクブモン 細胞移植部門 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
11 005504428 01999613 5140 144 2020-02-22 ヤクリガク 薬理学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk

View File

@ -0,0 +1,4 @@
"dr_wrkplace_his_key","dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","aply_end_ymd","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"1482020","005507600","01995783","9112","133","144","20200222","ハツセイ.セイシヨクブモン","発生・生殖部門",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"1482021","005402984","01997682","1512","165","144","20200222","シヨウカキゲカ","消化器外科",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"1482022","005504428","01999613","5140","999","144","20200222","ヤクリガク","薬理学",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
1 dr_wrkplace_his_key dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg aply_end_ymd regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 1482020 005507600 01995783 9112 133 144 20200222 ハツセイ.セイシヨクブモン 発生・生殖部門 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
3 1482021 005402984 01997682 1512 165 144 20200222 シヨウカキゲカ 消化器外科 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
4 1482022 005504428 01999613 5140 999 144 20200222 ヤクリガク 薬理学 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper

View File

@ -0,0 +1,6 @@
"dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"005507600","01995783","9999",,"802","2020-02-23",,,,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
"005402984","01997682","1512","165",,"2020-02-23","シヨウカキゲカ","消化器外科",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
"005504428","01997906","7212",,"144","2020-02-22","ユケツ.サイボウチリヨウガク","輸血・細胞治療学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01997906","9114",,"144","2020-02-22","サイボウイシヨクブモン","細胞移植部門",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01999613","9999","501","144","2020-02-23","ナイブンピ.ホネタイシヤガイライ","内分泌・骨代謝外来",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","clsComDrWrk"
1 dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 005507600 01995783 9999 802 2020-02-23 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk
3 005402984 01997682 1512 165 2020-02-23 シヨウカキゲカ 消化器外科 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk
4 005504428 01997906 7212 144 2020-02-22 ユケツ.サイボウチリヨウガク 輸血・細胞治療学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
5 005507600 01997906 9114 144 2020-02-22 サイボウイシヨクブモン 細胞移植部門 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
6 005504428 01999613 9999 501 144 2020-02-23 ナイブンピ.ホネタイシヤガイライ 内分泌・骨代謝外来 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 clsComDrWrk

View File

@ -0,0 +1,9 @@
"dr_wrkplace_his_key","dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","aply_end_ymd","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"1482020","005507600","01995783","9112","133","144","20200222","ハツセイ.セイシヨクブモン","発生・生殖部門",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"1482021","005402984","01997682","1512","165","144","20200222","シヨウカキゲカ","消化器外科",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"1482022","005504428","01999613","5140","999","144","20200222","ヤクリガク","薬理学",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"1482023","005408060","01997682","6802","999","144","20200222","シヨウカキゲカガク1","消化器外科学Ⅰ",,"20200223","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 16:18:08","com_dr_wrkplace_mapper","2022-02-03 16:18:08","com_dr_wrkplace_mapper"
"1482024","005409446","01997906","1118","501","999","20200222","ケツエキナイカ","血液内科",,"20200223","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 16:18:08","com_dr_wrkplace_mapper","2022-02-03 16:18:08","com_dr_wrkplace_mapper"
"1482025","005412977","01997682","6720","999","144","20200222","シヨウカキゲカガク","消化器外科学",,"20200223","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 16:18:08","com_dr_wrkplace_mapper","2022-02-03 16:18:08","com_dr_wrkplace_mapper"
"1482026","005414992","01995783","9999","501","999","20200222",,,,"20200223","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 16:18:08","com_dr_wrkplace_mapper","2022-02-03 16:18:08","com_dr_wrkplace_mapper"
"1482027","005503358","01997906","1118","172","144","20200222","ケツエキナイカ","血液内科",,"20200223","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 16:18:08","com_dr_wrkplace_mapper","2022-02-03 16:18:08","com_dr_wrkplace_mapper"
1 dr_wrkplace_his_key dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg aply_end_ymd regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 1482020 005507600 01995783 9112 133 144 20200222 ハツセイ.セイシヨクブモン 発生・生殖部門 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
3 1482021 005402984 01997682 1512 165 144 20200222 シヨウカキゲカ 消化器外科 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
4 1482022 005504428 01999613 5140 999 144 20200222 ヤクリガク 薬理学 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
5 1482023 005408060 01997682 6802 999 144 20200222 シヨウカキゲカガク1 消化器外科学Ⅰ 20200223 20220203 NULL NULL NULL NULL NULL 2022-02-03 16:18:08 com_dr_wrkplace_mapper 2022-02-03 16:18:08 com_dr_wrkplace_mapper
6 1482024 005409446 01997906 1118 501 999 20200222 ケツエキナイカ 血液内科 20200223 20220203 NULL NULL NULL NULL NULL 2022-02-03 16:18:08 com_dr_wrkplace_mapper 2022-02-03 16:18:08 com_dr_wrkplace_mapper
7 1482025 005412977 01997682 6720 999 144 20200222 シヨウカキゲカガク 消化器外科学 20200223 20220203 NULL NULL NULL NULL NULL 2022-02-03 16:18:08 com_dr_wrkplace_mapper 2022-02-03 16:18:08 com_dr_wrkplace_mapper
8 1482026 005414992 01995783 9999 501 999 20200222 20200223 20220203 NULL NULL NULL NULL NULL 2022-02-03 16:18:08 com_dr_wrkplace_mapper 2022-02-03 16:18:08 com_dr_wrkplace_mapper
9 1482027 005503358 01997906 1118 172 144 20200222 ケツエキナイカ 血液内科 20200223 20220203 NULL NULL NULL NULL NULL 2022-02-03 16:18:08 com_dr_wrkplace_mapper 2022-02-03 16:18:08 com_dr_wrkplace_mapper

View File

@ -0,0 +1,4 @@
"dr_wrkplace_his_key","dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","aply_end_ymd","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"1","005507600","01995783","9112","133","144","20200222","ハツセイ.セイシヨクブモン","発生・生殖部門","1","20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"2","005402984","01997682","1512","165","144","20200222","シヨウカキゲカ","消化器外科",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"3","005504428","01999613","5140","999","144","20200222","ヤクリガク","薬理学",,"20200222","20220203","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:43:43","com_dr_wrkplace_mapper","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
1 dr_wrkplace_his_key dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg aply_end_ymd regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 1 005507600 01995783 9112 133 144 20200222 ハツセイ.セイシヨクブモン 発生・生殖部門 1 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
3 2 005402984 01997682 1512 165 144 20200222 シヨウカキゲカ 消化器外科 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper
4 3 005504428 01999613 5140 999 144 20200222 ヤクリガク 薬理学 20200222 20220203 NULL NULL NULL NULL NULL 2022-02-03 14:43:43 com_dr_wrkplace_mapper 2022-02-03 14:43:43 com_dr_wrkplace_mapper

View File

@ -0,0 +1,11 @@
"dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"005414992","01995783",,"501",,"2020-02-22",,,,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 14:54:00","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005507600","01995783","9112","133","144","2020-02-22","ハツセイ.セイシヨクブモン","発生・生殖部門",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:16","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005402984","01997682","1512","165","144","2020-02-22","シヨウカキゲカ","消化器外科",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:16","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005408060","01997682","6802",,"144","2020-02-22","シヨウカキゲカガク1","消化器外科学Ⅰ",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:16","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005412977","01997682","6720",,"144","2020-02-22","シヨウカキゲカガク","消化器外科学",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:16","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005409446","01997906","1118","501",,"2020-02-22","ケツエキナイカ","血液内科",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:16","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005503358","01997906","1118","172","144","2020-02-22","ケツエキナイカ","血液内科",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:17","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005504428","01997906","7212",,"144","2020-02-22","ユケツ.サイボウチリヨウガク","輸血・細胞治療学",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:17","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005507600","01997906","9114",,"144","2020-02-22","サイボウイシヨクブモン","細胞移植部門",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:17","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
"005504428","01999613","5140",,"144","2020-02-22","ヤクリガク","薬理学",,"2022-02-02","NULL","NULL","NULL","NULL","NULL","2022-02-02 10:45:17","com_dr_wrkplace_mapper","2022-02-02 14:54:00","com_dr_wrkplace_mapper"
1 dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 005414992 01995783 501 2020-02-22 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 14:54:00 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
3 005507600 01995783 9112 133 144 2020-02-22 ハツセイ.セイシヨクブモン 発生・生殖部門 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:16 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
4 005402984 01997682 1512 165 144 2020-02-22 シヨウカキゲカ 消化器外科 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:16 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
5 005408060 01997682 6802 144 2020-02-22 シヨウカキゲカガク1 消化器外科学Ⅰ 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:16 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
6 005412977 01997682 6720 144 2020-02-22 シヨウカキゲカガク 消化器外科学 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:16 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
7 005409446 01997906 1118 501 2020-02-22 ケツエキナイカ 血液内科 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:16 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
8 005503358 01997906 1118 172 144 2020-02-22 ケツエキナイカ 血液内科 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:17 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
9 005504428 01997906 7212 144 2020-02-22 ユケツ.サイボウチリヨウガク 輸血・細胞治療学 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:17 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
10 005507600 01997906 9114 144 2020-02-22 サイボウイシヨクブモン 細胞移植部門 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:17 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper
11 005504428 01999613 5140 144 2020-02-22 ヤクリガク 薬理学 2022-02-02 NULL NULL NULL NULL NULL 2022-02-02 10:45:17 com_dr_wrkplace_mapper 2022-02-02 14:54:00 com_dr_wrkplace_mapper

View File

@ -0,0 +1,11 @@
"dcf_dsf_inst_cd","dcf_pcf_dr_cd","blng_sec_cd","post_cd","identity_cd","aply_start_ymd","blng_sec_name_kana","blng_sec_name","notdm_flg","regist_ymd","update_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"005414992","01995783",,"501",,"2020-02-22",,,,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01995783","9999",,"802","2020-02-23","NULL","NULL","1","2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"005402984","01997682","1512","165",,"2020-02-23","シヨウカキゲカ","消化器外科",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"005408060","01997682","6802",,"144","2020-02-22","シヨウカキゲカガク1","消化器外科学Ⅰ",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"005412977","01997682","6720",,"144","2020-02-22","シヨウカキゲカガク","消化器外科学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005409446","01997906","1118","501",,"2020-02-22","ケツエキナイカ","血液内科","NULL","2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
"005503358","01997906","1118","172","144","2020-02-22","ケツエキナイカ","血液内科",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01997906","7212",,"144","2020-02-22","ユケツ.サイボウチリヨウガク","輸血・細胞治療学",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005507600","01997906","9114",,"144","2020-02-22","サイボウイシヨクブモン","細胞移植部門",,"2022-02-03","NULL","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:23:39","clsComDrWrk"
"005504428","01999613","9999","501","144","2020-02-23","ナイブンピ.ホネタイシヤガイライ","内分泌・骨代謝外来",,"2022-02-03","2022-02-03","NULL","NULL","NULL","NULL","2022-02-03 14:23:39","clsComDrWrk","2022-02-03 14:43:43","com_dr_wrkplace_mapper"
1 dcf_dsf_inst_cd dcf_pcf_dr_cd blng_sec_cd post_cd identity_cd aply_start_ymd blng_sec_name_kana blng_sec_name notdm_flg regist_ymd update_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 005414992 01995783 501 2020-02-22 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
3 005507600 01995783 9999 802 2020-02-23 NULL NULL 1 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 com_dr_wrkplace_mapper
4 005402984 01997682 1512 165 2020-02-23 シヨウカキゲカ 消化器外科 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 com_dr_wrkplace_mapper
5 005408060 01997682 6802 144 2020-02-22 シヨウカキゲカガク1 消化器外科学Ⅰ 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 com_dr_wrkplace_mapper
6 005412977 01997682 6720 144 2020-02-22 シヨウカキゲカガク 消化器外科学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
7 005409446 01997906 1118 501 2020-02-22 ケツエキナイカ 血液内科 NULL 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 com_dr_wrkplace_mapper
8 005503358 01997906 1118 172 144 2020-02-22 ケツエキナイカ 血液内科 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
9 005504428 01997906 7212 144 2020-02-22 ユケツ.サイボウチリヨウガク 輸血・細胞治療学 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
10 005507600 01997906 9114 144 2020-02-22 サイボウイシヨクブモン 細胞移植部門 2022-02-03 NULL NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:23:39 clsComDrWrk
11 005504428 01999613 9999 501 144 2020-02-23 ナイブンピ.ホネタイシヤガイライ 内分泌・骨代謝外来 2022-02-03 2022-02-03 NULL NULL NULL NULL 2022-02-03 14:23:39 clsComDrWrk 2022-02-03 14:43:43 com_dr_wrkplace_mapper

View File

@ -0,0 +1,390 @@
import os.path as path
import pytest
from src.batch.common.batch_config import BatchConfig
from src.batch.ultmarc.utmp_tables.table_mapper.concrete import \
com_dr_wrkplace_mapper
from src.db.database import Database
from tests.testing_utility import (assert_table_results,
create_db_data_from_csv,
create_delete_sql_with_parameter,
create_insert_sql_with_parameter,
create_ultmarc_table_mapper_sut,
create_ultmarc_test_data_from_csv)
class TestComDrWrkplaceMapper:
"""COM_DCF医師勤務先"""
db: Database
batch_config: BatchConfig
test_file_path: str = path.dirname(__file__)
@ pytest.fixture(autouse=True, scope='function')
def pre_test(self, database: Database):
"""テスト実行前後処理"""
self.batch_config = BatchConfig.get_instance()
# setup
self.db = database
self.db.connect()
self.db.begin()
# testing
yield
# teardown
self.db.rollback()
self.db.disconnect()
def test_insert_record(self):
"""
Cases:
COM_DCF医師勤務先テーブルにレコードを登録する
Arranges:
- CSVデータを用意する
- 追加対象となるレコードを削除する
Expects:
- COM_医師勤務先の登録内容が期待値と一致すること
- COM_医師勤務先履歴にデータが登録されないこと
"""
# Arrange
# 処理日設定
# 適用開始日と同値になる
self.batch_config.syor_date = '2020/02/22'
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_dr_wrkplace_insert.csv'))
# 一旦全データをDBから削除
# COM_医師勤務先
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_dr_wrkplace', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_医師勤務先履歴
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_dr_wrkplace_his', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_所属部科
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_blng_sec', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_所属部科を登録
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_blng_sec_before_insert.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_blng_sec',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_dr_wrkplace_mapper.ComDrWrkplaceMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_dr_wrkplace_mapper.ComDrWrkplaceMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_dr_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_dr_wrkplace_insert.csv'))
primary_keys_dcf_dsf_inst_cd = [{'dcf_dsf_inst_cd': columns['dcf_dsf_inst_cd']} for columns in expect_dr_data_list]
primary_keys_dcf_pcf_dr_cd = [{'dcf_pcf_dr_cd': columns['dcf_pcf_dr_cd']} for columns in expect_dr_data_list]
# 複合主キーのため、1件ずつ取得して期待値を作る
actual_dr_data_list = []
actual_dr_select_sql = """\
SELECT * FROM src05.com_dr_wrkplace
WHERE
dcf_dsf_inst_cd = :dcf_dsf_inst_cd
AND dcf_pcf_dr_cd = :dcf_pcf_dr_cd\
"""
actual_his_select_sql = """\
SELECT * FROM src05.com_dr_wrkplace_his
WHERE
dcf_dsf_inst_cd = :dcf_dsf_inst_cd
AND dcf_pcf_dr_cd = :dcf_pcf_dr_cd
"""
for param_dcf_dsf_inst_cd, param_dcf_pcf_dr_cd in zip(primary_keys_dcf_dsf_inst_cd, primary_keys_dcf_pcf_dr_cd):
# COM_医師勤務先の取得
actual_dr_data = self.db.execute_select(
actual_dr_select_sql,
{**param_dcf_dsf_inst_cd, **param_dcf_pcf_dr_cd})
assert len(actual_dr_data) == 1, '1件取得できていること'
actual_dr_data_list.append(actual_dr_data[0])
# COM_医師勤務先履歴の取得
# 取得できないこと
actual_his_data = self.db.execute_select(
actual_his_select_sql,
{**param_dcf_dsf_inst_cd, **param_dcf_pcf_dr_cd})
assert len(actual_his_data) == 0, '履歴が作成されていないこと'
assert len(actual_dr_data_list) == len(expect_dr_data_list), 'COM_医師勤務先が期待値通りの件数作成されていること'
# 期待値検査
ignore_columns = ['regist_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_dr_data_list, expect_dr_data_list, ignore_col_name=ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_dr_data_list, expect_dr_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ignore_columns:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
def test_update_record(self):
"""
Cases:
COM_DCF医師勤務先テーブルのレコードを更新する
Arranges:
- CSVデータを用意し読み込む
- 更新対象となるレコードを登録する
Expects:
- COM_医師勤務先の登録内容が期待値と一致すること
- COM_医師勤務先履歴にデータが登録され期待値と一致すること
"""
# Arrange
# 処理日設定
# 適用開始日と同値、適用終了日の+1日になる
self.batch_config.syor_date = '2020/02/23'
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_dr_wrkplace_update.csv'))
# 一旦全データをDBから削除
# COM_医師勤務先
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_dr_wrkplace', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_医師勤務先履歴
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_dr_wrkplace_his', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_所属部科
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_blng_sec', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_医師勤務先を登録
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_dr_wrkplace_before_update.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_dr_wrkplace',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_dr_wrkplace_mapper.ComDrWrkplaceMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_dr_wrkplace_mapper.ComDrWrkplaceMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_dr_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_dr_wrkplace_update.csv'))
expect_his_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_dr_wrkplace_his_update.csv'))
# 複合主キーのため、1件ずつ取得して期待値を作る
actual_dr_data_list = []
actual_his_data_list = []
actual_dr_select_sql = """\
SELECT * FROM src05.com_dr_wrkplace
WHERE
dcf_dsf_inst_cd = :dcf_dsf_inst_cd
AND dcf_pcf_dr_cd = :dcf_pcf_dr_cd\
"""
actual_his_select_sql = """\
SELECT * FROM src05.com_dr_wrkplace_his
WHERE
dcf_dsf_inst_cd = :dcf_dsf_inst_cd
AND dcf_pcf_dr_cd = :dcf_pcf_dr_cd
"""
# COM_医師勤務先の取得
primary_keys_dcf_dsf_inst_cd = [{'dcf_dsf_inst_cd': columns['dcf_dsf_inst_cd']} for columns in expect_dr_data_list]
primary_keys_dcf_pcf_dr_cd = [{'dcf_pcf_dr_cd': columns['dcf_pcf_dr_cd']} for columns in expect_dr_data_list]
for param_dcf_dsf_inst_cd, param_dcf_pcf_dr_cd in zip(primary_keys_dcf_dsf_inst_cd, primary_keys_dcf_pcf_dr_cd):
actual_dr_data = self.db.execute_select(
actual_dr_select_sql,
{**param_dcf_dsf_inst_cd, **param_dcf_pcf_dr_cd})
assert len(actual_dr_data) == 1, '1件取得できていること'
actual_dr_data_list.append(actual_dr_data[0])
# COM_医師勤務先履歴の取得
primary_keys_dcf_dsf_inst_cd = [{'dcf_dsf_inst_cd': columns['dcf_dsf_inst_cd']} for columns in expect_his_data_list]
primary_keys_dcf_pcf_dr_cd = [{'dcf_pcf_dr_cd': columns['dcf_pcf_dr_cd']} for columns in expect_his_data_list]
for param_dcf_dsf_inst_cd, param_dcf_pcf_dr_cd in zip(primary_keys_dcf_dsf_inst_cd, primary_keys_dcf_pcf_dr_cd):
actual_his_data = self.db.execute_select(
actual_his_select_sql,
{**param_dcf_dsf_inst_cd, **param_dcf_pcf_dr_cd})
assert len(actual_dr_data) == 1, '1件取得できていること'
actual_his_data_list.append(actual_his_data[0])
assert len(actual_his_data_list) == len(expect_his_data_list), 'COM_医師勤務先が期待値通りの件数作成されていること'
assert len(actual_his_data_list) == len(expect_his_data_list), 'COM_医師勤務先履歴が期待値通りの件数作成されていること'
# 期待値検査
# COM_医師勤務先
dr_ignore_columns = ['regist_ymd', 'update_ymd', 'sys_update_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_dr_data_list, expect_dr_data_list, ignore_col_name=dr_ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_dr_data_list, expect_dr_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in dr_ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
# COM_医師勤務先履歴
his_ignore_columns = ['dr_wrkplace_his_key', 'regist_ymd', 'update_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_his_data_list, expect_his_data_list, ignore_col_name=his_ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_dr_data_list, expect_dr_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in his_ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
def test_delete_record(self):
"""
Cases:
COM_DCF医師勤務先テーブルのレコードを削除する
Arranges:
- CSVデータを用意し読み込む
- 削除対象となるレコードを登録する
Expects:
- COM_医師勤務先の登録内容が期待値と一致すること
- COM_医師勤務先履歴にデータが登録されないこと
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = '2020/02/24'
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_dr_wrkplace_delete.csv'))
# 一旦全データをDBから削除
# COM_医師勤務先
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_dr_wrkplace', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_医師勤務先履歴
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_dr_wrkplace_his', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_所属部科
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_blng_sec', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# COM_医師勤務先を登録
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_dr_wrkplace_before_delete.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_dr_wrkplace',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# COM_医師勤務先履歴を登録
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_dr_wrkplace_his_before_delete.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_dr_wrkplace_his',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# COM_所属部科を登録
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_blng_sec_before_delete.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_blng_sec',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_dr_wrkplace_mapper.ComDrWrkplaceMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_dr_wrkplace_mapper.ComDrWrkplaceMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_dr_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_dr_wrkplace_delete.csv'))
expect_his_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_dr_wrkplace_his_delete.csv'))
# 複合主キーのため、1件ずつ取得して期待値を作る
actual_dr_data_list = []
actual_his_data_list = []
actual_dr_select_sql = """\
SELECT * FROM src05.com_dr_wrkplace
WHERE
dcf_dsf_inst_cd = :dcf_dsf_inst_cd
AND dcf_pcf_dr_cd = :dcf_pcf_dr_cd\
"""
actual_his_select_sql = """\
SELECT * FROM src05.com_dr_wrkplace_his
WHERE
dcf_dsf_inst_cd = :dcf_dsf_inst_cd
AND dcf_pcf_dr_cd = :dcf_pcf_dr_cd
"""
# COM_医師勤務先の取得
primary_keys_dcf_dsf_inst_cd = [{'dcf_dsf_inst_cd': columns['dcf_dsf_inst_cd']} for columns in expect_dr_data_list]
primary_keys_dcf_pcf_dr_cd = [{'dcf_pcf_dr_cd': columns['dcf_pcf_dr_cd']} for columns in expect_dr_data_list]
for param_dcf_dsf_inst_cd, param_dcf_pcf_dr_cd in zip(primary_keys_dcf_dsf_inst_cd, primary_keys_dcf_pcf_dr_cd):
actual_dr_data = self.db.execute_select(
actual_dr_select_sql,
{**param_dcf_dsf_inst_cd, **param_dcf_pcf_dr_cd})
assert len(actual_dr_data) == 1, '1件取得できていること'
actual_dr_data_list.append(actual_dr_data[0])
# COM_医師勤務先履歴の取得
primary_keys_dcf_dsf_inst_cd = [{'dcf_dsf_inst_cd': columns['dcf_dsf_inst_cd']} for columns in expect_his_data_list]
primary_keys_dcf_pcf_dr_cd = [{'dcf_pcf_dr_cd': columns['dcf_pcf_dr_cd']} for columns in expect_his_data_list]
for param_dcf_dsf_inst_cd, param_dcf_pcf_dr_cd in zip(primary_keys_dcf_dsf_inst_cd, primary_keys_dcf_pcf_dr_cd):
# COM_医師勤務先履歴の取得
actual_his_data = self.db.execute_select(
actual_his_select_sql,
{**param_dcf_dsf_inst_cd, **param_dcf_pcf_dr_cd})
assert len(actual_his_data) == 1, '1件取得できていること'
actual_his_data_list.append(actual_his_data[0])
assert len(actual_dr_data_list) == len(expect_dr_data_list), 'COM_医師勤務先が期待値通りの件数作成されていること'
assert len(actual_his_data_list) == len(expect_his_data_list), 'COM_医師勤務先履歴が期待値通りの件数作成されていること'
# 期待値検査
# COM_医師勤務先
dr_ignore_columns = ['regist_ymd', 'update_ymd', 'sys_update_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_dr_data_list, expect_dr_data_list, ignore_col_name=dr_ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_dr_data_list, expect_dr_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in dr_ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
# COM_医師勤務先履歴
his_ignore_columns = ['dr_wrkplace_his_key', 'regist_ymd', 'update_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_his_data_list, expect_his_data_list, ignore_col_name=his_ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_dr_data_list, expect_dr_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in his_ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'

View File

@ -0,0 +1,7 @@
"021","001",,"A","20141113","20141114",
"021","002","1","A","20141113","20141114","電磁波温熱療法(放射線療法と併用しないもの)"
"021","003","2","A","20141113","20141114","微小銅線による脳血管性病変に対しての電気的凝固治療"
"021","004","1","C","20141113","20141114","顔面骨、頭蓋骨の観血的移動術"
"021","005","1","A","20141113","20141114","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)"
"021","006","1","A","20141113","20141114","造血器腫瘍のDNA診断"
"021","007","2","A","20141113","20141114","重症肥満の外科治療法"
1 021 001 A 20141113 20141114
2 021 002 1 A 20141113 20141114 電磁波温熱療法(放射線療法と併用しないもの)
3 021 003 2 A 20141113 20141114 微小銅線による脳血管性病変に対しての電気的凝固治療
4 021 004 1 C 20141113 20141114 顔面骨、頭蓋骨の観血的移動術
5 021 005 1 A 20141113 20141114 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)
6 021 006 1 A 20141113 20141114 造血器腫瘍のDNA診断
7 021 007 2 A 20141113 20141114 重症肥満の外科治療法

View File

@ -0,0 +1,6 @@
"021","001","2","A","20141113","20141114","直流電流による骨電気治療法"
"021","002","1","A","20141113","20141114","電磁波温熱療法(放射線療法と併用しないもの)"
"021","003","2","A","20141113","20141114","微小銅線による脳血管性病変に対しての電気的凝固治療"
"021","004","1","A","20141113","20141114","顔面骨、頭蓋骨の観血的移動術"
"021","005","1","A","20141113","20141114","造血器腫瘍のDNA診断"
"021","006","1","A","20141113","20141114","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)"
1 021 001 2 A 20141113 20141114 直流電流による骨電気治療法
2 021 002 1 A 20141113 20141114 電磁波温熱療法(放射線療法と併用しないもの)
3 021 003 2 A 20141113 20141114 微小銅線による脳血管性病変に対しての電気的凝固治療
4 021 004 1 A 20141113 20141114 顔面骨、頭蓋骨の観血的移動術
5 021 005 1 A 20141113 20141114 造血器腫瘍のDNA診断
6 021 006 1 A 20141113 20141114 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)

View File

@ -0,0 +1,6 @@
"021","001",,"B","20141113","20141114",
"021","002","1","B","20141113","20141114","電磁波温熱療法(放射線療法と併用しないもの)"
"021","003","2","B","20141113","20141114","微小銅線による脳血管性病変に対しての電気的凝固治療"
"021","004","1","B","20141113","20141114","顔面骨、頭蓋骨の観血的移動術"
"021","005","1","B","20141113","20141114","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)"
"021","006","1","B","20141113","20141114","造血器腫瘍のDNA診断"
1 021 001 B 20141113 20141114
2 021 002 1 B 20141113 20141114 電磁波温熱療法(放射線療法と併用しないもの)
3 021 003 2 B 20141113 20141114 微小銅線による脳血管性病変に対しての電気的凝固治療
4 021 004 1 B 20141113 20141114 顔面骨、頭蓋骨の観血的移動術
5 021 005 1 B 20141113 20141114 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)
6 021 006 1 B 20141113 20141114 造血器腫瘍のDNA診断

View File

@ -0,0 +1,7 @@
"hamtec_cd","hamtec_div","hamtec_name","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","2","直流電流による骨電気治療法","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:03:10","clsComHamtec"
"002","1","電磁波温熱療法(放射線療法と併用しないもの)","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"003","2","微小銅線による脳血管性病変に対しての電気的凝固治療","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"004","1","顔面骨、頭蓋骨の観血的移動術","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"005","1","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"006","1","造血器腫瘍のDNA診断","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
1 hamtec_cd hamtec_div hamtec_name regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 2 直流電流による骨電気治療法 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:03:10 clsComHamtec
3 002 1 電磁波温熱療法(放射線療法と併用しないもの) 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
4 003 2 微小銅線による脳血管性病変に対しての電気的凝固治療 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
5 004 1 顔面骨、頭蓋骨の観血的移動術 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
6 005 1 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る) 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
7 006 1 造血器腫瘍のDNA診断 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec

View File

@ -0,0 +1,7 @@
"hamtec_cd","hamtec_div","hamtec_name","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","2","直流電流による骨電気治療法","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:03:10","clsComHamtec"
"002","1","電磁波温熱療法(放射線療法と併用しないもの)","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"003","2","微小銅線による脳血管性病変に対しての電気的凝固治療","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"004","1","顔面骨、頭蓋骨の観血的移動術","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"005","1","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
"006","1","造血器腫瘍のDNA診断","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","clsComHamtec"
1 hamtec_cd hamtec_div hamtec_name regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 2 直流電流による骨電気治療法 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:03:10 clsComHamtec
3 002 1 電磁波温熱療法(放射線療法と併用しないもの) 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
4 003 2 微小銅線による脳血管性病変に対しての電気的凝固治療 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
5 004 1 顔面骨、頭蓋骨の観血的移動術 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
6 005 1 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る) 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec
7 006 1 造血器腫瘍のDNA診断 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 clsComHamtec

View File

@ -0,0 +1,8 @@
"hamtec_cd","hamtec_div","hamtec_name","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","2","直流電流による骨電気治療法","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:03:10","clsComHamtec"
"002","1","電磁波温熱療法(放射線療法と併用しないもの)","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:21:01","com_hamtec_mapper"
"003","2","微小銅線による脳血管性病変に対しての電気的凝固治療","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:21:01","com_hamtec_mapper"
"004","1","顔面骨、頭蓋骨の観血的移動術","20171018","20171018","20171018","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:21:01","com_hamtec_mapper"
"005","1","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:21:01","com_hamtec_mapper"
"006","1","造血器腫瘍のDNA診断","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:21:01","com_hamtec_mapper"
"007","2","重症肥満の外科治療法","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:21:01","com_hamtec_mapper","2017/10/18 17:21:01","com_hamtec_mapper"
1 hamtec_cd hamtec_div hamtec_name regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 2 直流電流による骨電気治療法 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:03:10 clsComHamtec
3 002 1 電磁波温熱療法(放射線療法と併用しないもの) 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:21:01 com_hamtec_mapper
4 003 2 微小銅線による脳血管性病変に対しての電気的凝固治療 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:21:01 com_hamtec_mapper
5 004 1 顔面骨、頭蓋骨の観血的移動術 20171018 20171018 20171018 NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:21:01 com_hamtec_mapper
6 005 1 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る) 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:21:01 com_hamtec_mapper
7 006 1 造血器腫瘍のDNA診断 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:21:01 com_hamtec_mapper
8 007 2 重症肥満の外科治療法 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:21:01 com_hamtec_mapper 2017/10/18 17:21:01 com_hamtec_mapper

View File

@ -0,0 +1,7 @@
"hamtec_cd","hamtec_div","hamtec_name","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","2","直流電流による骨電気治療法","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 16:24:26","com_hamtec_mapper","2017/10/18 16:24:26","com_hamtec_mapper"
"002","1","電磁波温熱療法(放射線療法と併用しないもの)","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 16:24:26","com_hamtec_mapper","2017/10/18 16:24:26","com_hamtec_mapper"
"003","2","微小銅線による脳血管性病変に対しての電気的凝固治療","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 16:24:26","com_hamtec_mapper","2017/10/18 16:24:26","com_hamtec_mapper"
"004","1","顔面骨、頭蓋骨の観血的移動術","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 16:24:26","com_hamtec_mapper","2017/10/18 16:24:26","com_hamtec_mapper"
"005","1","造血器腫瘍のDNA診断","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 16:24:26","com_hamtec_mapper","2017/10/18 16:24:26","com_hamtec_mapper"
"006","1","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 16:24:26","com_hamtec_mapper","2017/10/18 16:24:26","com_hamtec_mapper"
1 hamtec_cd hamtec_div hamtec_name regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 2 直流電流による骨電気治療法 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 16:24:26 com_hamtec_mapper 2017/10/18 16:24:26 com_hamtec_mapper
3 002 1 電磁波温熱療法(放射線療法と併用しないもの) 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 16:24:26 com_hamtec_mapper 2017/10/18 16:24:26 com_hamtec_mapper
4 003 2 微小銅線による脳血管性病変に対しての電気的凝固治療 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 16:24:26 com_hamtec_mapper 2017/10/18 16:24:26 com_hamtec_mapper
5 004 1 顔面骨、頭蓋骨の観血的移動術 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 16:24:26 com_hamtec_mapper 2017/10/18 16:24:26 com_hamtec_mapper
6 005 1 造血器腫瘍のDNA診断 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 16:24:26 com_hamtec_mapper 2017/10/18 16:24:26 com_hamtec_mapper
7 006 1 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る) 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 16:24:26 com_hamtec_mapper 2017/10/18 16:24:26 com_hamtec_mapper

View File

@ -0,0 +1,7 @@
"hamtec_cd","hamtec_div","hamtec_name","regist_ymd","update_ymd","delete_ymd","regist_date","create_user","update_date","update_user","sys_regist_date","regist_prgm_id","sys_update_date","update_prgm_id"
"001","2","直流電流による骨電気治療法","20171018","NULL","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:03:10","clsComHamtec"
"002","1","電磁波温熱療法(放射線療法と併用しないもの)","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","com_hamtec_mapper"
"003","2","微小銅線による脳血管性病変に対しての電気的凝固治療","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","com_hamtec_mapper"
"004","1","顔面骨、頭蓋骨の観血的移動術","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","com_hamtec_mapper"
"005","1","培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る)","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","com_hamtec_mapper"
"006","1","造血器腫瘍のDNA診断","20171018","20171018","NULL","NULL","NULL","NULL","NULL","2017/10/18 17:03:10","clsComHamtec","2017/10/18 17:08:06","com_hamtec_mapper"
1 hamtec_cd hamtec_div hamtec_name regist_ymd update_ymd delete_ymd regist_date create_user update_date update_user sys_regist_date regist_prgm_id sys_update_date update_prgm_id
2 001 2 直流電流による骨電気治療法 20171018 NULL NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:03:10 clsComHamtec
3 002 1 電磁波温熱療法(放射線療法と併用しないもの) 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 com_hamtec_mapper
4 003 2 微小銅線による脳血管性病変に対しての電気的凝固治療 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 com_hamtec_mapper
5 004 1 顔面骨、頭蓋骨の観血的移動術 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 com_hamtec_mapper
6 005 1 培養細胞による先天性代謝異常診断(胎児又は新生児に係るものに限る) 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 com_hamtec_mapper
7 006 1 造血器腫瘍のDNA診断 20171018 20171018 NULL NULL NULL NULL NULL 2017/10/18 17:03:10 clsComHamtec 2017/10/18 17:08:06 com_hamtec_mapper

View File

@ -0,0 +1,198 @@
import os.path as path
from datetime import datetime
import pytest
from src.batch.common.batch_config import BatchConfig
from src.batch.ultmarc.utmp_tables.table_mapper.concrete import \
com_hamtec_mapper
from src.db.database import Database
from tests.testing_utility import (assert_table_results,
create_db_data_from_csv,
create_delete_sql_with_parameter,
create_insert_sql_with_parameter,
create_ultmarc_table_mapper_sut,
create_ultmarc_test_data_from_csv)
class TestComHamtecMapper:
"""レイアウト区分021: COM_高度先進医療"""
db: Database
batch_config: BatchConfig
test_file_path: str = path.dirname(__file__)
@pytest.fixture(autouse=True, scope='function')
def pre_test(self, database: Database):
"""テスト実行前後処理"""
self.batch_config = BatchConfig.get_instance()
# setup
self.db = database
self.db.connect()
self.db.begin()
# testing
yield
# teardown
self.db.rollback()
self.db.disconnect()
def test_insert_record(self):
"""
Cases:
COM_高度先進医療テーブルにレコードを登録する
Arranges:
- CSVデータを用意し読み込む
- 追加対象となるレコードを削除する
Expects:
- 登録内容が期待値と一致すること
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = datetime.strftime(datetime.now(), '%Y/%m/%d')
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_hamtec_insert.csv'))
# 一旦全データをDBから削除
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_hamtec', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_hamtec_mapper.ComHamtecMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_hamtec_mapper.ComHamtecMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_hamtec_insert.csv'))
primary_keys = [f"'{primary_key['hamtec_cd']}'" for primary_key in expect_data_list]
actual_select_sql = f"SELECT * FROM src05.com_hamtec WHERE hamtec_cd IN ({','.join(primary_keys)})"
actual_data_list = self.db.execute_select(actual_select_sql)
# 期待値検査
ignore_columns = ['regist_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_data_list, expect_data_list, ignore_col_name=ignore_columns)
line_number = 0
# 動的日付項目の個別確認
for actual_row, expect_row in zip(actual_data_list, expect_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ['regist_ymd', 'sys_regist_date', 'sys_update_date']:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
def test_update_record(self):
"""
Cases:
COM_高度先進医療テーブルのレコードを更新する
Arranges:
- CSVデータを用意し読み込む
- 更新対象となるレコードを登録する
Expects:
- 登録内容が期待値と一致すること
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = datetime.strftime(datetime.now(), '%Y/%m/%d')
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_hamtec_update.csv'))
# 一旦全データをDBから削除
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_hamtec', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# テストデータをDBに登録
# DBデータを読み込む
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_hamtec_before_update.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_hamtec',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_hamtec_mapper.ComHamtecMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_hamtec_mapper.ComHamtecMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_hamtec_update.csv'))
primary_keys = [f"'{primary_key['hamtec_cd']}'" for primary_key in expect_data_list]
actual_select_sql = f"SELECT * FROM src05.com_hamtec WHERE hamtec_cd IN ({','.join(primary_keys)})"
actual_data_list = self.db.execute_select(actual_select_sql)
# 期待値検査
ignore_columns = ['regist_ymd', 'update_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_data_list, expect_data_list, ignore_col_name=ignore_columns)
line_number = 0
# 動的日付項目の個別確認
for actual_row, expect_row in zip(actual_data_list, expect_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'
def test_logical_delete(self):
"""
Cases:
COM_高度先進医療テーブルのレコードを1件論理削除する
Arranges:
- CSVデータを用意し読み込む
- 削除対象となるレコードを登録する
Expects:
- 登録内容が期待値と一致すること
"""
# Arrange
# 処理日設定
self.batch_config.syor_date = datetime.strftime(datetime.now(), '%Y/%m/%d')
# テスト用のCSVを読み込む
test_dat_file = create_ultmarc_test_data_from_csv(path.join(self.test_file_path, 'com_hamtec_delete.csv'))
# 一旦全データをDBから削除
delete_sql, delete_parameter = create_delete_sql_with_parameter('src05.com_hamtec', {'1': '1'})
self.db.execute(delete_sql, delete_parameter)
# テストデータをDBに登録
# DBデータを読み込む
test_sql_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'db_com_hamtec_before_delete.csv'))
for test_data in test_sql_data_list:
insert_sql, insert_parameter = create_insert_sql_with_parameter(
'src05.com_hamtec',
test_data.keys(),
test_data.values()
)
self.db.execute(insert_sql, insert_parameter)
# Act
for line_number, line in enumerate(test_dat_file, start=1):
sut: com_hamtec_mapper.ComHamtecMapper = create_ultmarc_table_mapper_sut(line, self.db)
assert type(sut) is com_hamtec_mapper.ComHamtecMapper, f'{line_number}行目:マッパークラスが期通りか'
sut.make_query()
sut.execute_queries()
# Assert
# 期待値ファイルを読み込む
expect_data_list = create_db_data_from_csv(path.join(self.test_file_path, 'expect_com_hamtec_delete.csv'))
primary_keys = [f"'{primary_key['hamtec_cd']}'" for primary_key in expect_data_list]
actual_select_sql = f"SELECT * FROM src05.com_hamtec WHERE hamtec_cd IN ({','.join(primary_keys)})"
actual_data_list = self.db.execute_select(actual_select_sql)
# 期待値検査
ignore_columns = ['regist_ymd', 'update_ymd', 'delete_ymd', 'sys_update_date', 'sys_regist_date']
assert_table_results(actual_data_list, expect_data_list, ignore_col_name=ignore_columns)
# 動的日付項目の個別確認
line_number = 0
for actual_row, expect_row in zip(actual_data_list, expect_data_list):
line_number += 1
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
if actual_col_name in ignore_columns:
if expect_row[expect_col_name] is None:
assert actual_row[actual_col_name] is None, f'{line_number}行目:{actual_col_name}が、登録されていないこと'
else:
assert actual_row[actual_col_name] >= expect_row[expect_col_name], f'{line_number}行目:{actual_col_name}が、期待値以降であること'

View File

@ -0,0 +1,11 @@
"""共通テストフィクスチャ"""
import pytest
from src.db.database import Database
@pytest.fixture
def database() -> Database:
"""データベース接続モジュールを作成"""
return Database.get_instance()

View File

@ -0,0 +1,168 @@
"""テスト用共通処理関数"""
import csv
import tempfile
from datetime import datetime
from src.batch.ultmarc.datfile import DatFile, DatFileLine
from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import \
UltmarcTableMapper
from src.batch.ultmarc.utmp_tables.ultmarc_table_mapper_factory import \
UltmarcTableMapperFactory
from src.db.database import Database
def create_ultmarc_test_data_from_csv(file_path: str) -> DatFile:
"""ファイルから、アルトマーク取り込み用のテストデータを作成する
Args:
file_path (str): csvファイルのパス
Returns:
DatFile: データファイルオブジェクト
"""
# 一度、Shift-JISファイルで書き出す
with open(file_path, encoding='utf8') as csv_file, tempfile.NamedTemporaryFile('w', encoding='cp932') as tmp_file:
tmp_file.write(csv_file.read())
tmp_file.seek(0)
tmpfile_path = tmp_file.name
dat_file = DatFile.from_path(tmpfile_path)
return dat_file
def create_db_data_from_csv(file_path: str) -> list[dict]:
"""ファイルから、DBの期待値データを作成する
Args:
file_path (str): csvファイルのパス
Returns:
DatFile: データファイルオブジェクト
"""
with open(file_path, encoding='utf8') as csv_file:
# ヘッダ行を取得し、改行とクォートを取り除く。
header = csv_file.readline().strip('\n').replace('"', '').split(',')
reader = csv.DictReader(csv_file, fieldnames=header)
rows = [r for r in reader]
# データ型変換
for row in rows:
for k, v in row.items():
converted_value = v
if v == 'NULL':
converted_value = None
if is_valid_date_format(v, '%Y/%m/%d') is True: # YYYY/MM/DD
converted_value = datetime.strptime(v, '%Y/%m/%d').date()
if is_valid_date_format(v, '%Y-%m-%d') is True: # YYYY-MM-DD
converted_value = datetime.strptime(v, '%Y-%m-%d').date()
if is_valid_date_format(v, '%Y/%m/%d %H:%M:%S') is True: # YYYY/MM/DD HH:MM:SS
converted_value = datetime.strptime(v, '%Y/%m/%d %H:%M:%S')
if is_valid_date_format(v, '%Y-%m-%d %H:%M:%S') is True: # YYYY-MM-DD HH:MM:SS
converted_value = datetime.strptime(v, '%Y-%m-%d %H:%M:%S')
row[k] = converted_value
return rows
def create_insert_sql_with_parameter(table_name: str, column_names: list[str], test_data: list[str]) -> tuple[str, dict]:
"""INSERT文と登録値のパラメータを返す
Args:
table_name (str): スキーマ完全修飾のテーブル名(:src05.com_alma)
column_names (list[str]): カラム名のリスト
test_data (list[str]): 値のリスト
Returns:
tuple[str, dict]: [0]INSERT文,[1]値のパラメータ
"""
placeholders = ','.join([f':{column_name}' for column_name in column_names])
insert_sql = f"INSERT INTO {table_name} ({','.join(column_names)}) VALUES({placeholders})"
parameter = {k: v for k, v in zip(column_names, test_data)}
return insert_sql, parameter
def create_delete_sql_with_parameter(table_name: str, delete_parameter: dict[str, str]):
"""DELETE文と削除条件値のパラメータを返す
Args:
table_name (str): スキーマ完全修飾のテーブル名(:src05.com_alma)
delete_parameter (dict[str, str]): 削除条件に使用するカラム名と値の辞書
Returns:
tuple[str, dict]: [0]DELETE文,[1]値のパラメータ
"""
where_clause_list = []
for k in delete_parameter:
where_clause_list.append(f'{k} = :{k}')
where_clauses = ' AND '.join(where_clause_list)
delete_sql = f"DELETE FROM {table_name} WHERE {where_clauses}"
return delete_sql, delete_parameter
def create_ultmarc_table_mapper_sut(line: DatFileLine, db: Database) -> UltmarcTableMapper:
"""アルトマークテーブルマッパーのインスタンスを返す
Args:
line (DatFileLine): テストデータの1行
db (Database): 接続済みDBインスタンス
Returns:
UltmarcTableMapper: マッパークラス
"""
layout_class = line.layout_class
factory = UltmarcTableMapperFactory()
sut = factory.create(
layout_class=layout_class,
records=line.records,
db=db
)
return sut
def is_valid_date_format(date_str: str, date_format):
"""日付文字列が、与えられたフォーマットにマッチするかを検査する
Args:
date_str (str): 日付文字列
date_format (str, optional): 日付のフォーマット
Returns:
_type_: 正しい日付文字列の場合Trueそれ以外はFalse
"""
try:
datetime.strptime(date_str, date_format)
return True
except ValueError:
return False
def assert_table_results(actual_rows: list[dict], expect_rows: list[dict], ignore_col_name: list = None) -> None:
"""テーブル同士の取得結果突き合わせ
Args:
actual_rows (list[dict]): テスト結果の辞書リスト
expect_rows (list[dict]): 期待値の辞書リスト
ignore_col_name (list): 比較を無視するDBのカラム名. Default None.
"""
# 取得件数が一致すること
assert len(actual_rows) == len(expect_rows)
line_number = 0
# 1行ずつ調査
for actual_row, expect_row in zip(actual_rows, expect_rows):
line_number += 1
# 1カラムずつ調査
for actual_col_name, expect_col_name in zip(actual_row, expect_row):
# テストメソッド側で個別に確認するものはスキップさせる
if ignore_col_name is not None and actual_col_name in ignore_col_name:
continue
else:
actual_value = actual_row[actual_col_name]
expect_value = expect_row[expect_col_name]
assert actual_value == expect_value, f'{line_number}行目:{actual_col_name}が、期待値と一致すること'

View File

@ -1,6 +1,5 @@
from sqlalchemy import (Connection, CursorResult, Engine, QueuePool,
create_engine, text)
from sqlalchemy.engine.create import create_engine
from sqlalchemy.engine.url import URL
from src.error.exceptions import DBException
@ -16,8 +15,7 @@ class Database:
__username: str = None
__password: str = None
__schema: str = None
__connection_string:str = None
__connection_string: str = None
def __init__(self, username: str, password: str, host: str, port: int, schema: str) -> None:
"""このクラスの新たなインスタンスを初期化します
@ -34,9 +32,9 @@ class Database:
self.__host = host
self.__port = int(port)
self.__schema = schema
self.__connection_string = URL.create(
drivername='mysql+pymysql',
drivername='mysql+pymysql',
username=self.__username,
password=self.__password,
host=self.__host,
@ -44,12 +42,11 @@ class Database:
database=self.__schema,
query={"charset": "utf8mb4"}
)
self.__engine = create_engine(
self.__connection_string,
pool_timeout=5,
poolclass=QueuePool,
isolation_level="AUTOCOMMIT"
poolclass=QueuePool
)
@classmethod
@ -97,10 +94,18 @@ class Database:
"""
if self.__connection is None:
raise DBException('DBに接続していません')
result = None
try:
result = self.__connection.execute(text(select_query), parameters=parameters)
# トランザクションが開始している場合は、トランザクションを引き継ぐ
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(e)
result_rows = result.mappings().all()
return result_rows
@ -119,10 +124,18 @@ class Database:
"""
if self.__connection is None:
raise DBException('DBに接続していません')
result = None
try:
result = self.__connection.execute(text(query), parameters=parameters)
# トランザクションが開始している場合は、トランザクションを引き継ぐ
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(e)
return result
def begin(self):
@ -145,3 +158,14 @@ class Database:
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