Procházet zdrojové kódy

Erster Versuch mit db compare

gc-server3 před 9 měsíci
rodič
revize
ed8e045e66
7 změnil soubory, kde provedl 174 přidání a 91 odebrání
  1. 82 82
      database/SQL/bcp.csv.log
  2. 5 4
      database/__init__.py
  3. 2 2
      database/bcp_log.py
  4. 76 0
      database/db_compare.py
  5. 1 1
      database/db_create.py
  6. 8 2
      db.py
  7. binární
      dist/gctools.exe

+ 82 - 82
database/SQL/bcp.csv.log

@@ -1,83 +1,83 @@
 filename;timestamp;imported;exported;ignored;missing;import_duration;export_duration;file_size
-CAR_STATISTIC_1;18.01.2023 23:12:45;26179;26179;0.0;0.0;1.922;0.219;-1
-COMM_TRANS_UNIT_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.047;0.001;-1
-COMM_UNIT_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-COURTESY_CAR_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.031;0.001;-1
-CUSTOMER_1;18.01.2023 23:12:45;20937;20937;0.0;0.0;0.828;1.031;-1
-CUSTOMER_TRANSACT_1;18.01.2023 23:12:45;61306;61306;0.0;0.0;0.953;0.969;-1
-DEPARTMENT_TYPE_1;18.01.2023 23:12:45;11;11;0.0;0.0;0.001;0.001;-1
-EMPLOYEE_1;18.01.2023 23:12:45;84;84;0.0;0.0;0.001;0.001;-1
-GLOBAL_MAKE_1;18.01.2023 23:12:45;164;164;0.0;0.0;0.001;0.015;-1
-GM_DRIVE_ORDER_1;18.01.2023 23:12:45;619;619;0.0;0.0;0.031;0.047;-1
-ORDER_ACCUMULATION_1;18.01.2023 23:12:45;318824;318824;0.0;0.0;1.704;1.312;-1
-ORDER_HEADER_1;18.01.2023 23:12:45;21846;21846;0.0;0.0;1.016;1.156;-1
-ORDER_LINE_1;18.01.2023 23:12:45;210570;210570;0.0;0.0;14.016;1.813;-1
-ORDER_OPEN_ITEMS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-ORDER_SERVICE_SCHEMES_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.031;0.001;-1
-PERSON_1;18.01.2023 23:12:45;110;110;0.0;0.0;0.001;0.001;-1
-PERSON_INFO_1;18.01.2023 23:12:45;61;61;0.0;0.0;0.001;0.001;-1
-PRODUCT_FILE_1;18.01.2023 23:12:45;11652;11652;0.0;0.0;0.328;0.375;-1
-PRODUCT_STOCK_FILE_1;18.01.2023 23:12:45;11651;11651;0.0;0.0;0.187;0.14;-1
-PROFILE_1;18.01.2023 23:12:45;93;93;0.0;0.0;0.001;0.001;-1
-PROFILE_TYPE_1;18.01.2023 23:12:45;209;209;0.0;0.0;0.001;0.001;-1
-PUNCH_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.016;0.001;-1
-PURCH_DISCOUNTS_1;18.01.2023 23:12:45;30928;30928;0.0;0.0;0.266;0.156;-1
-PURCH_DISC_TYPES_1;18.01.2023 23:12:45;62;62;0.0;0.0;0.001;0.001;-1
-SERVICE_2000_FILE_1;18.01.2023 23:12:45;5;5;0.0;0.0;0.094;0.016;-1
-SITE_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-SUPPLIER_1;18.01.2023 23:12:45;2223;2223;0.0;0.0;0.046;0.063;-1
-SUPPLIER_TRANSACT_1;18.01.2023 23:12:45;40115;40115;0.0;0.0;2.031;0.641;-1
-TIME_CONTROL_END_1;18.01.2023 23:12:45;224557;224557;0.0;0.0;9.953;1.86;-1
-TIME_CONTROL_OPEN_1;18.01.2023 23:12:45;13;13;0.0;0.0;0.001;0.001;-1
-TIME_CONTROL_TRANS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.11;0.001;-1
-TRANSACTION_TYPE_1;18.01.2023 23:12:45;3;3;0.0;0.0;0.001;0.001;-1
-UNIT_CHANGE_HIST_1;18.01.2023 23:12:45;27817;27817;0.0;0.0;0.171;0.187;-1
-UNIT_FILE_1;18.01.2023 23:12:45;11587;11587;0.0;0.0;0.407;0.485;-1
-UNIT_LINK_EXT_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.047;0.001;-1
-UNIT_SALES_PRICE_LOG_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-UNIT_STATUS_HIST_1;18.01.2023 23:12:45;12603;12603;0.0;0.0;0.078;0.063;-1
-UNIT_TEMP_TAB_GRNI_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-UNIT_TRANSFER_TAB_1;18.01.2023 23:12:45;61365;61365;0.0;0.0;0.312;0.266;-1
-UNIT_TYPE_FILE_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.125;0.001;-1
-UPDATE_OPTION_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.016;0.001;-1
-VEHICLE_1;18.01.2023 23:12:45;29343;29343;0.0;0.0;1.688;2.094;-1
-VEHICLE_ACCRUALS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-VEHICLE_DOCKETCARD_1;18.01.2023 23:12:45;6503;6503;0.0;0.0;0.344;0.172;-1
-VEHICLE_EXTENSION_1;18.01.2023 23:12:45;29324;29324;0.0;0.0;0.313;0.328;-1
-VEH_CARGRP_PURCHORIGIN_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-VEH_CLASSIFICATION_CODE_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-VEH_IN_TRANSIT_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.031;0.001;-1
-VEH_LINK_EXT_1;18.01.2023 23:12:45;44;44;0.0;0.0;0.001;0.001;-1
-VEH_MAX_STOCK_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-VEH_ORDER_HEADER_1;18.01.2023 23:12:45;21472;21472;0.0;0.0;0.688;0.688;-1
-VEH_ORDER_LINE_1;18.01.2023 23:12:45;22379;22379;0.0;0.0;0.39;0.266;-1
-VEH_ORDER_OPTION_1;18.01.2023 23:12:45;119100;119100;0.0;0.0;6.734;1.75;-1
-VEH_TRANSACT_COLUMNS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.015;-1
-VEH_TRANSACT_GRID_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-VEH_TRANSACT_GROUPS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-VEH_TRANSMISSION_CODES_1;18.01.2023 23:12:45;9;9;0.0;0.0;0.001;0.015;-1
-VPP25_1;18.01.2023 23:12:45;36;36;0.0;0.0;0.001;0.001;-1
-VPP2C_1;18.01.2023 23:12:45;33;33;0.0;0.0;0.125;0.001;-1
-VPP43_1;18.01.2023 23:12:45;87;87;0.0;0.0;0.062;0.001;-1
-VPP48_1;18.01.2023 23:12:45;24;24;0.0;0.0;0.001;0.001;-1
-VPP4K_1;18.01.2023 23:12:45;31;31;0.0;0.0;0.001;0.001;-1
-VPP51_1;18.01.2023 23:12:45;205;205;0.0;0.0;0.001;0.001;-1
-VPP53_1;18.01.2023 23:12:45;1213;1213;0.0;0.0;0.016;0.001;-1
-VPP5A_1;18.01.2023 23:12:45;45;45;0.0;0.0;0.001;0.016;-1
-VPP5M_1;18.01.2023 23:12:45;1067;1067;0.0;0.0;0.001;0.001;-1
-VPP5Q_1;18.01.2023 23:12:45;538;538;0.0;0.0;0.001;0.001;-1
-VPP5R_1;18.01.2023 23:12:45;8;8;0.0;0.0;0.001;0.001;-1
-VPP61_1;18.01.2023 23:12:45;1;1;0.0;0.0;0.001;0.016;-1
-VPP65_1;18.01.2023 23:12:45;14;14;0.0;0.0;0.001;0.001;-1
-VPP72_1;18.01.2023 23:12:45;42;42;0.0;0.0;0.016;0.001;-1
-VPP73_1;18.01.2023 23:12:45;24;24;0.0;0.0;0.001;0.016;-1
-VPP74_1;18.01.2023 23:12:45;595;595;0.0;0.0;0.015;0.001;-1
-VPP91_1;18.01.2023 23:12:45;4;4;0.0;0.0;0.001;0.001;-1
-VPP93_1;18.01.2023 23:12:45;36;36;0.0;0.0;0.001;0.015;-1
-VPPT1_1;18.01.2023 23:12:45;10773;10773;0.0;0.0;0.047;0.031;-1
-WORKING_PERIOD_1;18.01.2023 23:12:45;128;128;0.0;0.0;0.047;0.001;-1
-WORKSHOP_ORDER_SPLIT_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-WORKSHOP_PLANNING_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-WORKSHOP_TEAMS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-WORK_LINE_STATUS_1;18.01.2023 23:12:45;0;0;0.0;0.0;0.001;0.001;-1
-WORK_UNITS_1;18.01.2023 23:12:45;6;6;0.0;0.0;0.001;0.001;-1
+CAR_STATISTIC_1;2023-01-18T23:12:45;26179;26179;0;0;1.922;0.219;-1
+COMM_TRANS_UNIT_1;2023-01-18T23:12:45;0;0;0;0;0.047;0.001;-1
+COMM_UNIT_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+COURTESY_CAR_1;2023-01-18T23:12:45;0;0;0;0;0.031;0.001;-1
+CUSTOMER_1;2023-01-18T23:12:45;20937;20937;0;0;0.828;1.031;-1
+CUSTOMER_TRANSACT_1;2023-01-18T23:12:45;61306;61306;0;0;0.953;0.969;-1
+DEPARTMENT_TYPE_1;2023-01-18T23:12:45;11;11;0;0;0.001;0.001;-1
+EMPLOYEE_1;2023-01-18T23:12:45;84;84;0;0;0.001;0.001;-1
+GLOBAL_MAKE_1;2023-01-18T23:12:45;164;164;0;0;0.001;0.015;-1
+GM_DRIVE_ORDER_1;2023-01-18T23:12:45;619;619;0;0;0.031;0.047;-1
+ORDER_ACCUMULATION_1;2023-01-18T23:12:45;318824;318824;0;0;1.704;1.312;-1
+ORDER_HEADER_1;2023-01-18T23:12:45;21846;21846;0;0;1.016;1.156;-1
+ORDER_LINE_1;2023-01-18T23:12:45;210570;210570;0;0;14.016;1.813;-1
+ORDER_OPEN_ITEMS_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+ORDER_SERVICE_SCHEMES_1;2023-01-18T23:12:45;0;0;0;0;0.031;0.001;-1
+PERSON_1;2023-01-18T23:12:45;110;110;0;0;0.001;0.001;-1
+PERSON_INFO_1;2023-01-18T23:12:45;61;61;0;0;0.001;0.001;-1
+PRODUCT_FILE_1;2023-01-18T23:12:45;11652;11652;0;0;0.328;0.375;-1
+PRODUCT_STOCK_FILE_1;2023-01-18T23:12:45;11651;11651;0;0;0.187;0.14;-1
+PROFILE_1;2023-01-18T23:12:45;93;93;0;0;0.001;0.001;-1
+PROFILE_TYPE_1;2023-01-18T23:12:45;209;209;0;0;0.001;0.001;-1
+PUNCH_1;2023-01-18T23:12:45;0;0;0;0;0.016;0.001;-1
+PURCH_DISCOUNTS_1;2023-01-18T23:12:45;30928;30928;0;0;0.266;0.156;-1
+PURCH_DISC_TYPES_1;2023-01-18T23:12:45;62;62;0;0;0.001;0.001;-1
+SERVICE_2000_FILE_1;2023-01-18T23:12:45;5;5;0;0;0.094;0.016;-1
+SITE_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+SUPPLIER_1;2023-01-18T23:12:45;2223;2223;0;0;0.046;0.063;-1
+SUPPLIER_TRANSACT_1;2023-01-18T23:12:45;40115;40115;0;0;2.031;0.641;-1
+TIME_CONTROL_END_1;2023-01-18T23:12:45;224557;224557;0;0;9.953;1.86;-1
+TIME_CONTROL_OPEN_1;2023-01-18T23:12:45;13;13;0;0;0.001;0.001;-1
+TIME_CONTROL_TRANS_1;2023-01-18T23:12:45;0;0;0;0;0.11;0.001;-1
+TRANSACTION_TYPE_1;2023-01-18T23:12:45;3;3;0;0;0.001;0.001;-1
+UNIT_CHANGE_HIST_1;2023-01-18T23:12:45;27817;27817;0;0;0.171;0.187;-1
+UNIT_FILE_1;2023-01-18T23:12:45;11587;11587;0;0;0.407;0.485;-1
+UNIT_LINK_EXT_1;2023-01-18T23:12:45;0;0;0;0;0.047;0.001;-1
+UNIT_SALES_PRICE_LOG_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+UNIT_STATUS_HIST_1;2023-01-18T23:12:45;12603;12603;0;0;0.078;0.063;-1
+UNIT_TEMP_TAB_GRNI_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+UNIT_TRANSFER_TAB_1;2023-01-18T23:12:45;61365;61365;0;0;0.312;0.266;-1
+UNIT_TYPE_FILE_1;2023-01-18T23:12:45;0;0;0;0;0.125;0.001;-1
+UPDATE_OPTION_1;2023-01-18T23:12:45;0;0;0;0;0.016;0.001;-1
+VEHICLE_1;2023-01-18T23:12:45;29343;29343;0;0;1.688;2.094;-1
+VEHICLE_ACCRUALS_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+VEHICLE_DOCKETCARD_1;2023-01-18T23:12:45;6503;6503;0;0;0.344;0.172;-1
+VEHICLE_EXTENSION_1;2023-01-18T23:12:45;29324;29324;0;0;0.313;0.328;-1
+VEH_CARGRP_PURCHORIGIN_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+VEH_CLASSIFICATION_CODE_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+VEH_IN_TRANSIT_1;2023-01-18T23:12:45;0;0;0;0;0.031;0.001;-1
+VEH_LINK_EXT_1;2023-01-18T23:12:45;44;44;0;0;0.001;0.001;-1
+VEH_MAX_STOCK_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+VEH_ORDER_HEADER_1;2023-01-18T23:12:45;21472;21472;0;0;0.688;0.688;-1
+VEH_ORDER_LINE_1;2023-01-18T23:12:45;22379;22379;0;0;0.39;0.266;-1
+VEH_ORDER_OPTION_1;2023-01-18T23:12:45;119100;119100;0;0;6.734;1.75;-1
+VEH_TRANSACT_COLUMNS_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.015;-1
+VEH_TRANSACT_GRID_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+VEH_TRANSACT_GROUPS_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+VEH_TRANSMISSION_CODES_1;2023-01-18T23:12:45;9;9;0;0;0.001;0.015;-1
+VPP25_1;2023-01-18T23:12:45;36;36;0;0;0.001;0.001;-1
+VPP2C_1;2023-01-18T23:12:45;33;33;0;0;0.125;0.001;-1
+VPP43_1;2023-01-18T23:12:45;87;87;0;0;0.062;0.001;-1
+VPP48_1;2023-01-18T23:12:45;24;24;0;0;0.001;0.001;-1
+VPP4K_1;2023-01-18T23:12:45;31;31;0;0;0.001;0.001;-1
+VPP51_1;2023-01-18T23:12:45;205;205;0;0;0.001;0.001;-1
+VPP53_1;2023-01-18T23:12:45;1213;1213;0;0;0.016;0.001;-1
+VPP5A_1;2023-01-18T23:12:45;45;45;0;0;0.001;0.016;-1
+VPP5M_1;2023-01-18T23:12:45;1067;1067;0;0;0.001;0.001;-1
+VPP5Q_1;2023-01-18T23:12:45;538;538;0;0;0.001;0.001;-1
+VPP5R_1;2023-01-18T23:12:45;8;8;0;0;0.001;0.001;-1
+VPP61_1;2023-01-18T23:12:45;1;1;0;0;0.001;0.016;-1
+VPP65_1;2023-01-18T23:12:45;14;14;0;0;0.001;0.001;-1
+VPP72_1;2023-01-18T23:12:45;42;42;0;0;0.016;0.001;-1
+VPP73_1;2023-01-18T23:12:45;24;24;0;0;0.001;0.016;-1
+VPP74_1;2023-01-18T23:12:45;595;595;0;0;0.015;0.001;-1
+VPP91_1;2023-01-18T23:12:45;4;4;0;0;0.001;0.001;-1
+VPP93_1;2023-01-18T23:12:45;36;36;0;0;0.001;0.015;-1
+VPPT1_1;2023-01-18T23:12:45;10773;10773;0;0;0.047;0.031;-1
+WORKING_PERIOD_1;2023-01-18T23:12:45;128;128;0;0;0.047;0.001;-1
+WORKSHOP_ORDER_SPLIT_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+WORKSHOP_PLANNING_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+WORKSHOP_TEAMS_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+WORK_LINE_STATUS_1;2023-01-18T23:12:45;0;0;0;0;0.001;0.001;-1
+WORK_UNITS_1;2023-01-18T23:12:45;6;6;0;0;0.001;0.001;-1

+ 5 - 4
database/__init__.py

@@ -1,4 +1,5 @@
-from database.bcp_log import bcp_log
-from database.db_create import create
-from database.db_run import run
-from database.db_schema import schema
+from database.bcp_log import bcp_log  # noqa: F401
+from database.db_compare import compare  # noqa: F401
+from database.db_create import create  # noqa: F401
+from database.db_run import run  # noqa: F401
+from database.db_schema import schema  # noqa: F401

+ 2 - 2
database/bcp_log.py

@@ -1,7 +1,7 @@
 import re
 from dataclasses import dataclass
-from pathlib import Path
 from datetime import datetime
+from pathlib import Path
 
 
 @dataclass
@@ -21,7 +21,7 @@ class BulkcopyResult:
 
     def to_csv(self) -> str:
         return (
-            f"{self.file_name};{self.timestamp.strftime('%d.%m.%Y %H:%M:%S')};"
+            f"{self.file_name};{self.timestamp.strftime('%Y-%m-%dT%H:%M:%S')};"
             + f"{self.exported};{self.imported};{self.ignored};{self.missing};"
             + f"{self.export_duration};{self.import_duration};"
             + f"{self.file_size}"

+ 76 - 0
database/db_compare.py

@@ -0,0 +1,76 @@
+import json
+from pathlib import Path
+
+import pandas as pd
+
+from database.db_create import get_import_config
+from database.model import DatabaseInspect, create_db_ini, load_config
+
+
+def compare(config_file: str = "database/CARLO.json"):
+    cfg = load_config(config_file)
+    create_db_ini(cfg)
+    base_dir = str(Path(config_file).parent.parent.resolve())
+    config = get_import_config(f"{base_dir}/config/{cfg.csv_file}", cfg.dest_dsn.database)
+
+    source_db = DatabaseInspect(cfg.source_dsn, source=True)
+    source_tables = source_db.get_tables()
+    print(json.dumps(source_db.get_prefix(), indent=2))
+
+    dest_db = DatabaseInspect(cfg.dest_dsn)
+    dest_tables = dest_db.get_tables()
+
+    for _, current_table in config.iterrows():
+        dest_row_count = {}
+        dest_timestamp = {}
+        if current_table["dest"] in dest_tables:
+            full_table_name = f'[{current_table["dest_db"]}].[{cfg.dest_dsn.schema}].[{current_table["dest"]}]'
+            # pkey = dest_db.get_pkey(current_table["dest"], current_table["dest_db"])
+            # cols = pkey + ["timestamp"]
+            query_count_dest = f"SELECT [Client_DB], COUNT(*) as [Rows] FROM {full_table_name} GROUP BY [Client_DB]"
+            q = dest_db.cursor.execute(query_count_dest)
+            dest_row_count = dict([(col[0], col[1]) for col in q.fetchall()])
+
+            query_timestamp_dest = (
+                f"SELECT [Client_DB], max(timestamp) as [TS] FROM {full_table_name} GROUP BY [Client_DB]"
+            )
+            q = dest_db.cursor.execute(query_timestamp_dest)
+            dest_timestamp = dict([(col[0], col[1]) for col in q.fetchall()])
+
+        source_row_count = {}
+        source_row_count_ts = {}
+
+        for client_db, prefix in cfg.clients.items():
+            # table_client = f'{current_table["dest"]}_{client_db}'
+            source_table = current_table["source"].format(prefix)
+            if source_table in source_tables:
+                if not pd.isnull(current_table["query"]):
+                    select_query = current_table["query"].format(prefix, cfg.filter[0], cfg.filter[1])
+                elif "." in source_table or cfg.source_dsn.schema == "":
+                    if source_table[0] != "[":
+                        source_table = f"[{source_table}]"
+                    select_query = f"SELECT T1.* FROM {source_table} T1 "
+                else:
+                    select_query = f"SELECT T1.* FROM [{cfg.source_dsn.schema}].[{source_table}] T1 "
+
+                if not pd.isnull(current_table["filter"]):
+                    select_query += " WHERE " + current_table["filter"].format("", cfg.filter[0], cfg.filter[1])
+                query_count_source = select_query.replace("T1.*", "COUNT(*) as [Rows]")
+
+                q = source_db.cursor.execute(query_count_source)
+                source_row_count[client_db] = q.fetchone()[0]
+
+                query_ts = query_count_source
+                ts = dest_timestamp.get(client_db, "0x0000000000000000")
+                if "WHERE" in query_ts:
+                    query_ts = query_ts.replace("WHERE", "WHERE [timestamp] <= convert(binary(8), '{ts}', 1) AND")
+                else:
+                    query_ts += f" WHERE [timestamp] <= convert(binary(8), '{ts}', 1)"
+                q = source_db.cursor.execute(query_count_source)
+                source_row_count_ts[client_db] = q.fetchone()[0]
+
+            if dest_row_count.get(client_db, 0) != source_row_count.get(client_db, 0):
+                print(f"Tabelle {current_table['dest']} mit Client {client_db} stimmt nicht ueberein.")
+                print(f"  Quelle:          {source_row_count.get(client_db, 0):>8}")
+                print(f"  Quelle (bis ts): {source_row_count_ts.get(client_db, 0):>8}")
+                print(f"  dest:            {dest_row_count.get(client_db, 0):>8}")

+ 1 - 1
database/db_create.py

@@ -21,7 +21,7 @@ def get_import_config(filename: str, db_name: str):
 def create(config_file: str = "database/CARLO.json"):
     cfg = load_config(config_file)
     create_db_ini(cfg)
-    base_dir = str(Path(cfg.batch_dir).parent)
+    base_dir = str(Path(config_file).parent.parent.resolve())
     config = get_import_config(f"{base_dir}/config/{cfg.csv_file}", cfg.dest_dsn.database)
 
     source_db = DatabaseInspect(cfg.source_dsn, source=True)

+ 8 - 2
db.py

@@ -1,7 +1,7 @@
-import config
-import database
 import typer
 
+import config
+import database
 
 app = typer.Typer()
 cfg = config.Config()
@@ -13,6 +13,12 @@ def create(config_file: str):
     database.create(config_file)
 
 
+@app.command()
+def compare(config_file: str):
+    config_file = cfg.system_dir + f"\\SQL\\config\\{config_file}.json"
+    database.compare(config_file)
+
+
 @app.command()
 def run(max: int = 5):
     batch_dir = cfg.system_dir + "\\SQL\\batch"

binární
dist/gctools.exe