{"id":110627,"date":"2025-05-26T09:34:18","date_gmt":"2025-05-26T05:04:18","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/%d8%af%d8%a7%d8%af%d9%87-%d9%87%d8%a7%db%8c-%d9%82%d8%af%db%8c%d9%85%db%8c-%d8%ac%d8%a7%d9%85%d8%b9%d9%87-dev\/"},"modified":"2025-05-26T09:34:18","modified_gmt":"2025-05-26T05:04:18","slug":"%d8%af%d8%a7%d8%af%d9%87-%d9%87%d8%a7%db%8c-%d9%82%d8%af%db%8c%d9%85%db%8c-%d8%ac%d8%a7%d9%85%d8%b9%d9%87-dev","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/%d8%af%d8%a7%d8%af%d9%87-%d9%87%d8%a7%db%8c-%d9%82%d8%af%db%8c%d9%85%db%8c-%d8%ac%d8%a7%d9%85%d8%b9%d9%87-dev\/","title":{"rendered":"\u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0642\u062f\u06cc\u0645\u06cc &#8211; \u062c\u0627\u0645\u0639\u0647 dev"},"content":{"rendered":"<div data-article-id=\"2527146\" id=\"article-body\">\n<p>\u062f\u0631 \u0632\u06cc\u0631 \u06cc\u06a9 \u0631\u0627\u0647 \u062d\u0644 \u062f\u0648 \u0642\u0633\u0645\u062a \u0648 \u06a9\u0627\u0645\u0644 \u0628\u0647 \u067e\u0627\u06cc\u0627\u0646 \u0631\u0633\u06cc\u062f\u0647 \u0627\u0633\u062a \u06a9\u0647 \u0646\u06cc\u0627\u0632\u0647\u0627\u06cc \u0634\u0645\u0627 \u0631\u0627 \u0628\u0631\u0622\u0648\u0631\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f. \u0627\u06cc\u0646 \u0637\u0631\u062d \u0645\u0648\u0627\u0631\u062f \u0632\u06cc\u0631 \u0631\u0627 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u062f\u0647\u062f:<\/p>\n<ol>\n<li>\n<p><strong>\u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc \u0627\u0632 \u0642\u0627\u0644\u0628 CSV \u0648 \u062a\u0634\u062e\u06cc\u0635 \u0646\u0648\u0639 \u0648\u0631\u0648\u062f\u06cc<\/strong><\/p>\n<p>&#8211; \u0641\u0631\u0636 \u0628\u0631 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 CSV \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc \u0627\u0632 \u0627\u06cc\u0646 \u0633\u062a\u0648\u0646 \u0647\u0627 \u0627\u0633\u062a:<\/p>\n<p>mapping_id \u060c source_name \u060c source_object_type \u060c target_name \u060c target_object_type \u060c \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc_\u0645\u0648\u062f \u060c where_clause \u060c udude_columns<\/p>\n<p>&#8211; \u0633\u06cc\u0633\u062a\u0645 \u0645\u0642\u062f\u0627\u0631 Source_name \u0648 Target_Name \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc \u06a9\u0646\u062f. \u0627\u06af\u0631 \u0645\u0642\u062f\u0627\u0631 \u0628\u0627 &#8220;\u0627\u0646\u062a\u062e\u0627\u0628&#8221; \u0634\u0631\u0648\u0639 \u0634\u0648\u062f \u06cc\u0627 \u0628\u0627 &#8220;.sql&#8221; \u0628\u0647 \u067e\u0627\u06cc\u0627\u0646 \u0628\u0631\u0633\u062f \u060c \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u067e\u0631\u0633 \u0648 \u062c\u0648 SQL \u0633\u0641\u0627\u0631\u0634\u06cc (\u06cc\u0627 \u0645\u0633\u06cc\u0631 \u067e\u0631\u0648\u0646\u062f\u0647) \u0631\u0641\u062a\u0627\u0631 \u0645\u06cc \u0634\u0648\u062f. \u062f\u0631 \u063a\u06cc\u0631 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0641\u0631\u0636 \u0628\u0631 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u0646\u0627\u0645 \u0634\u06cc\u0621 \u06a9\u0627\u0645\u0644\u0627\u064b \u0648\u0627\u062c\u062f \u0634\u0631\u0627\u06cc\u0637 \u062f\u0631 \u0641\u0631\u0645 &#8220;DB.Schema.Object_Name&#8221; \u0627\u0633\u062a.<\/p>\n<\/li>\n<li>\n<p><strong>\u062f\u0633\u062a \u0632\u062f\u0646 \u0628\u0647 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u067e\u0648\u06cc\u0627<\/strong><\/p>\n<p>&#8211; \u0627\u06af\u0631 \u06cc\u06a9 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0633\u0641\u0627\u0631\u0634\u06cc \u0628\u0631\u0627\u06cc \u0647\u0631 \u062f\u0648 \u0637\u0631\u0641 \u0645\u0646\u062a\u0642\u0644 \u0634\u0648\u062f \u060c \u0633\u06cc\u0633\u062a\u0645 \u0627\u0628\u062a\u062f\u0627 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u06cc\u06a9 \u06cc\u0627\u0648\u0631 (_prepare_temp_object) \u06cc\u06a9 \u062c\u062f\u0648\u0644 \u0645\u0648\u0642\u062a (\u06cc\u0627 \u0646\u0645\u0627\u06cc) \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f \u06a9\u0647 \u06cc\u06a9 \u062f\u0633\u062a\u0648\u0631 &#8220;\u0627\u06cc\u062c\u0627\u062f \u062c\u062f\u0648\u0644 \u0645\u0648\u0642\u062a &#8230; \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 (\u067e\u0631\u0633 \u0648 \u062c\u0648 \u0633\u0641\u0627\u0631\u0634\u06cc)&#8221; \u0631\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc \u06a9\u0646\u062f. (\u062f\u0631 \u062a\u0648\u0644\u06cc\u062f \u062a\u0623\u06cc\u06cc\u062f \u0645\u06cc \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0634\u06cc \u0627\u06cc\u062c\u0627\u062f \u0634\u062f\u0647 \u0627\u0633\u062a \u060c \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u0645\u0627 \u0622\u0646 \u0631\u0627 \u0634\u0628\u06cc\u0647 \u0633\u0627\u0632\u06cc \u0645\u06cc \u06a9\u0646\u06cc\u0645.)<\/p>\n<p>&#8211; \u0633\u067e\u0633 \u060c \u062a\u0645\u0627\u0645 \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u0647\u0627\u06cc \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0648 \u06a9\u0644 \u0627\u0628\u0631\u062f\u0627\u062f\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0646\u0627\u0645 \u0622\u0646 \u0634\u06cc\u0621 \u0645\u0648\u0642\u062a \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 &#8220;from_name&#8221; \u062f\u0631 \u0627\u0644\u06af\u0648\u0647\u0627\u06cc \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<\/li>\n<li>\n<p><strong>\u062a\u0634\u06a9\u06cc\u0644 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u06a9\u0644 \u0648 \u0639\u0627\u062f\u06cc \u0633\u0627\u0632\u06cc<\/strong><\/p>\n<p>&#8211; \u0627\u0644\u06af\u0648\u0647\u0627\u06cc \u067e\u06cc\u0634 \u0641\u0631\u0636 SQL (\u062f\u0631 \u067e\u0631\u0648\u0646\u062f\u0647 \u0647\u0627\u06cc \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc YAML) \u0627\u0632 \u06cc\u06a9 \u0645\u06a9\u0627\u0646 \u0646\u06af\u0647\u062f\u0627\u0631\u0646\u062f\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f <code>{from_name}<\/code> \u0627\u06cc\u0646 \u06cc\u0627 \u0646\u0627\u0645 \u0634\u06cc\u0621 \u06a9\u0627\u0645\u0644\u0627\u064b \u0648\u0627\u062c\u062f \u0634\u0631\u0627\u06cc\u0637 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0645\u06cc \u0634\u0648\u062f (\u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0631\u0627\u0626\u0647 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0633\u0641\u0627\u0631\u0634\u06cc) \u06cc\u0627 \u0646\u0627\u0645 \u0634\u06cc\u0621 \u0645\u0648\u0642\u062a (\u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0631\u0627\u0626\u0647 SQL \u0633\u0641\u0627\u0631\u0634\u06cc).<\/p>\n<p>-\u062a\u0648\u0627\u0628\u0639 \u06cc\u0627\u0648\u0631 _to_dict \u0648 _normalize_aggregate \u0628\u0631\u0627\u06cc \u062a\u0628\u062f\u06cc\u0644 \u0646\u062a\u0627\u06cc\u062c \u067e\u0631\u0633 \u0648 \u062c\u0648 \u06a9\u0644 \u0628\u0647 \u0641\u0631\u0647\u0646\u06af \u0644\u063a\u062a \u0647\u0627\u06cc \u0645\u062a\u0639\u0627\u0631\u0641 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f \u0628\u0647 \u0637\u0648\u0631\u06cc \u06a9\u0647 \u0645\u0642\u0627\u062f\u06cc\u0631 \u0639\u062f\u062f\u06cc (\u06af\u0631\u062f) \u060c datetime (\u0628\u0631\u0634 \u062e\u0648\u0631\u062f\u0647) \u0648 \u0631\u0634\u062a\u0647 (\u067e\u0627\u06cc\u06cc\u0646 \u060c \u0633\u0644\u0628 \u0634\u062f\u0647) \u0628\u0647 \u062f\u0631\u0633\u062a\u06cc \u0645\u0642\u0627\u06cc\u0633\u0647 \u0645\u06cc \u0634\u0648\u0646\u062f \u060c \u062d\u062a\u06cc \u0627\u06af\u0631 \u06cc\u06a9 \u0637\u0631\u0641 \u06cc\u06a9 \u062a\u0648\u067e \u0631\u0627 \u0628\u0627\u0632\u06af\u0631\u062f\u0627\u0646\u062f \u0648 \u062f\u06cc\u06af\u0631\u06cc \u06cc\u06a9 \u062f\u06cc\u06a9\u062a.<\/p>\n<\/li>\n<li>\n<p><strong>\u062c\u0631\u06cc\u0627\u0646 \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc<\/strong><\/p>\n<p>&#8211; \u0631\u0648\u0646\u062f \u06a9\u0644\u06cc:<\/p>\n<p>\u0627\u0644\u0641 \u0646\u0627\u0645 \u0645\u0646\u0628\u0639 \u0648 \u0647\u062f\u0641 \u0631\u0627 \u062a\u0639\u06cc\u06cc\u0646 \u06a9\u0646\u06cc\u062f (\u0648 \u062f\u0631 \u0635\u0648\u0631\u062a \u0644\u0632\u0648\u0645 &#8220;\u0622\u0645\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f&#8221;).<\/p>\n<p>\u0628. \u062a\u0639\u062f\u0627\u062f \u0631\u062f\u06cc\u0641 \u0647\u0627\u06cc \u06a9\u0644 \u061b \u0627\u06af\u0631 \u0645\u062a\u0641\u0627\u0648\u062a \u0647\u0633\u062a\u0646\u062f \u060c \u0627\u0639\u062a\u0628\u0627\u0631 \u0628\u06cc\u0634\u062a\u0631\u06cc \u0631\u0627 \u0645\u062a\u0648\u0642\u0641 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u062c. \u0628\u0647 \u0635\u0648\u0631\u062a \u0627\u062e\u062a\u06cc\u0627\u0631\u06cc \u0686\u06a9 \u0647\u0627\u06cc \u062a\u06a9\u0631\u0627\u0631\u06cc \u0648 \u0686\u06a9 \u0647\u0627\u06cc \u062a\u0647\u06cc \u0631\u0627 \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u06cc\u062f.<\/p>\n<p>\u062f. \u0627\u0632 \u0647\u0631 \u0637\u0631\u0641 \u0627\u0628\u0631\u062f\u0627\u062f\u0647 \u0631\u0627 \u0628\u0627\u0632\u06cc\u0627\u0628\u06cc \u06a9\u0646\u06cc\u062f \u0648 \u0645\u0642\u0627\u06cc\u0633\u0647 \u06a9\u0646\u06cc\u062f (\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644 \u062a\u0639\u062f\u0627\u062f \u0633\u062a\u0648\u0646 \u0647\u0627 \u060c \u0646\u0627\u0645 \u0647\u0627\u06cc \u0645\u0637\u0627\u0628\u0642\u062a \u0648 \u0627\u0646\u0648\u0627\u0639 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0642\u0627\u0628\u0644 \u0642\u0628\u0648\u0644).<\/p>\n<p>\u0647. \u0628\u0631\u0627\u06cc \u0647\u0631 \u0633\u062a\u0648\u0646 \u060c \u06cc\u06a9 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u06a9\u0644 \u0631\u0627 \u0627\u062c\u0631\u0627 \u06a9\u0646\u06cc\u062f (\u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 &#8220;from_name&#8221; \u0645\u0646\u0627\u0633\u0628 \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0648 \u0633\u067e\u0633 \u062c\u0645\u0639 \u0622\u0648\u0631\u06cc \u0647\u0627\u06cc \u0646\u0631\u0645\u0627\u0644 \u0634\u062f\u0647 Field -by -Field \u0631\u0627 \u0645\u0642\u0627\u06cc\u0633\u0647 \u06a9\u0646\u06cc\u062f.<br \/>&#8211; \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u062f\u0642\u06cc\u0642 \u062f\u0631 \u0647\u0631 \u0645\u0631\u062d\u0644\u0647 \u0627\u0635\u0644\u06cc \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u0634\u0648\u062f \u060c \u0628\u0627 \u0627\u0645\u062a\u062d\u0627\u0646\/\u0628\u0647 \u062c\u0632 \u0628\u0644\u0648\u06a9 \u0647\u0627 \u0628\u0631\u0627\u06cc \u06af\u0631\u0641\u062a\u0646 \u062e\u0637\u0627 \u0648 \u0627\u062f\u0627\u0645\u0647 \u0628\u0627 \u0644\u0637\u0641.<\/p>\n<\/li>\n<li>\n<p><strong>\u0637\u0631\u0627\u062d\u06cc \u0645\u062f\u0648\u0644\u0627\u0631 \u0648 \u0627\u0633\u062a\u062d\u06a9\u0627\u0645<\/strong><\/p>\n<p>-\u06a9\u062f \u0628\u0647 \u062f\u0646\u0628\u0627\u0644 \u0627\u0635\u0648\u0644 \u062c\u0627\u0645\u062f \u060c \u062e\u0634\u06a9 \u060c \u0628\u0648\u0633\u0647 \u0648 yagni \u0628\u0647 \u0631\u0648\u0634\u0647\u0627\u06cc \u06a9\u0648\u0686\u06a9 \u0648 \u062f\u0627\u0631\u0627\u06cc \u062e\u0648\u062f \u0634\u06a9\u0633\u062a\u0647 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<p>&#8211; \u0647\u0645\u0647 \u0635\u0627\u062d\u0628\u062e\u0627\u0646\u0647 \u0647\u0627 (\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644 <code>{from_name}<\/code>) \u0648 \u067e\u0627\u0631\u0627\u0645\u062a\u0631\u0647\u0627\u06cc \u0627\u0636\u0627\u0641\u06cc \u0627\u0632 \u0637\u0631\u06cc\u0642 QueryFormatter \u0645\u0627 \u062a\u0632\u0631\u06cc\u0642 \u0645\u06cc \u0634\u0648\u0646\u062f.<br \/>&#8211; \u062f\u0631 \u0635\u0648\u0631\u062a \u0628\u0631\u0648\u0632 \u0647\u0631\u06af\u0648\u0646\u0647 \u062e\u0637\u0627\u06cc\u06cc (\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644 \u0642\u0627\u0644\u0628 \u0628\u0646\u062f\u06cc \u060c \u0627\u062c\u0631\u0627\u06cc \u067e\u0631\u0633 \u0648 \u062c\u0648 \u060c \u0627\u06cc\u062c\u0627\u062f \u062c\u062f\u0648\u0644 \u0645\u0648\u0642\u062a) \u060c \u0627\u0632 \u0622\u0646 \u06af\u0631\u0641\u062a\u0647 \u0645\u06cc \u0634\u0648\u062f \u060c \u0648\u0627\u0631\u062f \u0645\u06cc \u0634\u0648\u062f \u0648 \u0627\u0632 \u0645\u0642\u062f\u0627\u0631 \u0628\u0631\u06af\u0634\u062a\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<\/li>\n<\/ol>\n<p>\u062f\u0631 \u0632\u06cc\u0631 \u06a9\u062f \u06a9\u0627\u0645\u0644 \u0627\u0633\u062a. (\u0645\u0646 \u0622\u0646 \u0631\u0627 \u062f\u0631 \u062f\u0648 \u0628\u062e\u0634 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u062f\u0647\u0645.) <\/p>\n<p>\u00b0<\/p>\n<p><strong>\u0642\u0633\u0645\u062a 1: \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u060c \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u062f\u06cc (\u0627\u0632 \u062c\u0645\u0644\u0647 query_formatter \u0648 metadata_fetcher)<\/strong><\/p>\n<hr\/>\n<p><strong>\u067e\u0631\u0648\u0646\u062f\u0647: \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc\/bigQuery_config.yaml<\/strong><\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight yaml\"><code><span class=\"na\">use_database<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"nv\"> <\/span><span class=\"s\">'{database}'<\/span><span class=\"nv\"> <\/span><span class=\"s\">AS<\/span><span class=\"nv\"> <\/span><span class=\"s\">active_database;\"<\/span>\n<span class=\"na\">total_rows<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT COUNT(*) AS total_rows <\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">numeric<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MIN({column}) AS min_value,<\/span>\n         <span class=\"s\">MAX({column}) AS max_value,<\/span>\n         <span class=\"s\">AVG({column}) AS avg_value,<\/span>\n         <span class=\"s\">SUM({column}) AS sum_value,<\/span>\n         <span class=\"s\">COUNT(DISTINCT {column}) AS distinct_count<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">string<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT TO_HEX(MD5(CAST({column} AS STRING))) AS hash_value<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause};<\/span>\n<span class=\"na\">string_all<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT TO_HEX(MD5(STRING_AGG(CAST({column} AS STRING), '' ORDER BY {column}))) AS hash_value<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause};<\/span>\n<span class=\"na\">datetime<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MIN({column}) AS min_datetime,<\/span>\n         <span class=\"s\">MAX({column}) AS max_datetime,<\/span>\n         <span class=\"s\">COUNT(DISTINCT DATE({column})) AS distinct_dates <\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">null_check<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT COUNT(*) AS missing_values <\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NULL;<\/span>\n<span class=\"na\">duplicate_check<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT {column}, COUNT(*) AS duplicate_count<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">GROUP BY {column}<\/span>\n  <span class=\"s\">HAVING COUNT(*) &gt; 1;<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<p><strong>\u067e\u0631\u0648\u0646\u062f\u0647: \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc\/snowflake_config.yaml<\/strong><\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight yaml\"><code><span class=\"na\">use_database<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">USE<\/span><span class=\"nv\"> <\/span><span class=\"s\">DATABASE<\/span><span class=\"nv\"> <\/span><span class=\"s\">{database};\"<\/span>\n<span class=\"na\">total_rows<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"nv\"> <\/span><span class=\"s\">COUNT(*)<\/span><span class=\"nv\"> <\/span><span class=\"s\">AS<\/span><span class=\"nv\"> <\/span><span class=\"s\">total_rows<\/span><span class=\"nv\"> <\/span><span class=\"s\">FROM<\/span><span class=\"nv\"> <\/span><span class=\"s\">{from_name}<\/span><span class=\"nv\"> <\/span><span class=\"s\">{where_clause};\"<\/span>\n<span class=\"na\">numeric<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MIN({column}) AS min_value,<\/span>\n         <span class=\"s\">MAX({column}) AS max_value,<\/span>\n         <span class=\"s\">AVG({column}) AS avg_value,<\/span>\n         <span class=\"s\">SUM({column}) AS sum_value,<\/span>\n         <span class=\"s\">COUNT(DISTINCT {column}) AS distinct_count<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">string<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MD5(CAST({column} AS STRING)) AS hash_value<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause};<\/span>\n<span class=\"na\">string_all<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MD5(LISTAGG(CAST({column} AS STRING), '' ORDER BY {column})) AS hash_value<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause};<\/span>\n<span class=\"na\">datetime<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MIN({column}) AS min_datetime,<\/span>\n         <span class=\"s\">MAX({column}) AS max_datetime,<\/span>\n         <span class=\"s\">COUNT(DISTINCT TO_DATE({column})) AS distinct_dates<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">null_check<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"nv\"> <\/span><span class=\"s\">COUNT(*)<\/span><span class=\"nv\"> <\/span><span class=\"s\">AS<\/span><span class=\"nv\"> <\/span><span class=\"s\">missing_values<\/span><span class=\"nv\"> <\/span><span class=\"s\">FROM<\/span><span class=\"nv\"> <\/span><span class=\"s\">{from_name}<\/span><span class=\"nv\"> <\/span><span class=\"s\">WHERE<\/span><span class=\"nv\"> <\/span><span class=\"s\">{column}<\/span><span class=\"nv\"> <\/span><span class=\"s\">IS<\/span><span class=\"nv\"> <\/span><span class=\"s\">NULL<\/span><span class=\"nv\"> <\/span><span class=\"s\">{where_clause};\"<\/span>\n<span class=\"na\">duplicate_check<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT {column}, COUNT(*) AS duplicate_count<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">GROUP BY {column}<\/span>\n  <span class=\"s\">HAVING COUNT(*) &gt; 1;<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<p><strong>\u067e\u0631\u0648\u0646\u062f\u0647: \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc\/sqlserver_config.yaml<\/strong><\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight yaml\"><code><span class=\"na\">use_database<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">USE<\/span><span class=\"nv\"> <\/span><span class=\"s\">{database};\"<\/span>\n<span class=\"na\">total_rows<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"nv\"> <\/span><span class=\"s\">COUNT(*)<\/span><span class=\"nv\"> <\/span><span class=\"s\">AS<\/span><span class=\"nv\"> <\/span><span class=\"s\">total_rows<\/span><span class=\"nv\"> <\/span><span class=\"s\">FROM<\/span><span class=\"nv\"> <\/span><span class=\"s\">{from_name}<\/span><span class=\"nv\"> <\/span><span class=\"s\">{where_clause};\"<\/span>\n<span class=\"na\">numeric<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MIN({column}) AS min_value,<\/span>\n         <span class=\"s\">MAX({column}) AS max_value,<\/span>\n         <span class=\"s\">AVG({column}) AS avg_value,<\/span>\n         <span class=\"s\">SUM({column}) AS sum_value,<\/span>\n         <span class=\"s\">COUNT(DISTINCT {column}) AS distinct_count<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">string<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT CONVERT(VARCHAR(64), HASHBYTES('MD5', CAST({column} AS VARCHAR)), 2) AS hash_value<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause};<\/span>\n<span class=\"na\">string_all<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT CONVERT(VARCHAR(64), HASHBYTES('MD5', (<\/span>\n      <span class=\"s\">SELECT STRING_AGG(CAST({column} AS VARCHAR), '' ORDER BY {column})<\/span>\n      <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">)), 2) AS hash_value;<\/span>\n<span class=\"na\">datetime<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT MIN({column}) AS min_datetime,<\/span>\n         <span class=\"s\">MAX({column}) AS max_datetime,<\/span>\n         <span class=\"s\">COUNT(DISTINCT CONVERT(date, {column})) AS distinct_dates <\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">WHERE {column} IS NOT NULL;<\/span>\n<span class=\"na\">null_check<\/span><span class=\"pi\">:<\/span> <span class=\"s2\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"nv\"> <\/span><span class=\"s\">COUNT(*)<\/span><span class=\"nv\"> <\/span><span class=\"s\">AS<\/span><span class=\"nv\"> <\/span><span class=\"s\">missing_values<\/span><span class=\"nv\"> <\/span><span class=\"s\">FROM<\/span><span class=\"nv\"> <\/span><span class=\"s\">{from_name}<\/span><span class=\"nv\"> <\/span><span class=\"s\">WHERE<\/span><span class=\"nv\"> <\/span><span class=\"s\">{column}<\/span><span class=\"nv\"> <\/span><span class=\"s\">IS<\/span><span class=\"nv\"> <\/span><span class=\"s\">NULL<\/span><span class=\"nv\"> <\/span><span class=\"s\">{where_clause};\"<\/span>\n<span class=\"na\">duplicate_check<\/span><span class=\"pi\">:<\/span> <span class=\"pi\">&gt;<\/span>\n  <span class=\"s\">SELECT {column}, COUNT(*) AS duplicate_count<\/span>\n  <span class=\"s\">FROM {from_name} {where_clause}<\/span>\n  <span class=\"s\">GROUP BY {column}<\/span>\n  <span class=\"s\">HAVING COUNT(*) &gt; 1;<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<p><strong>\u067e\u0631\u0648\u0646\u062f\u0647: \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc\/\u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc_\u062f\u0627\u062a\u0627. csv<\/strong><\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>mapping_id,source_name,source_object_type,target_name,target_object_type,validation_mode,where_clause,exclude_columns\n1,db.schema.object_name,table,db.schema.target_object_name,table,column,,,\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><em>(\u062a\u0648\u062c\u0647: \u0628\u0631\u0627\u06cc \u067e\u0631\u0633 \u0648 \u062c\u0648\u0647\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u06cc\u06a9 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0628\u0627 \u0634\u0631\u0648\u0639 &#8220;\u0627\u0646\u062a\u062e\u0627\u0628&#8221; \u06cc\u0627 \u0645\u0633\u06cc\u0631 \u067e\u0631\u0648\u0646\u062f\u0647 .sql \u062f\u0631 Source_Name\/Target_Name \u0642\u0631\u0627\u0631 \u062f\u0647\u06cc\u062f.)<\/em><\/p>\n<hr\/>\n<p><strong>\u067e\u0631\u0648\u0646\u062f\u0647: UTILS\/Config_Loader.py<\/strong><\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">import<\/span> <span class=\"n\">os<\/span>\n<span class=\"kn\">import<\/span> <span class=\"n\">yaml<\/span>\n<span class=\"kn\">import<\/span> <span class=\"n\">logging<\/span>\n\n<span class=\"k\">class<\/span> <span class=\"nc\">ConfigLoader<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">def<\/span> <span class=\"nf\">get_db_config<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">db_type<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">db_type<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Database type must be provided.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">normalized<\/span> <span class=\"o\">=<\/span> <span class=\"n\">db_type<\/span><span class=\"p\">.<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\"> <\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">_<\/span><span class=\"sh\">\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n        <span class=\"n\">config_path<\/span> <span class=\"o\">=<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">path<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">config<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">normalized<\/span><span class=\"si\">}<\/span><span class=\"s\">_config.yaml<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">path<\/span><span class=\"p\">.<\/span><span class=\"nf\">exists<\/span><span class=\"p\">(<\/span><span class=\"n\">config_path<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">with<\/span> <span class=\"nf\">open<\/span><span class=\"p\">(<\/span><span class=\"n\">config_path<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">r<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"k\">as<\/span> <span class=\"n\">f<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Loading configuration from: <\/span><span class=\"si\">{<\/span><span class=\"n\">config_path<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n                    <span class=\"k\">return<\/span> <span class=\"n\">yaml<\/span><span class=\"p\">.<\/span><span class=\"nf\">safe_load<\/span><span class=\"p\">(<\/span><span class=\"n\">f<\/span><span class=\"p\">)<\/span> <span class=\"ow\">or<\/span> <span class=\"p\">{}<\/span>\n            <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">exc<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Error loading config file <\/span><span class=\"si\">{<\/span><span class=\"n\">config_path<\/span><span class=\"si\">}<\/span><span class=\"s\">: <\/span><span class=\"si\">{<\/span><span class=\"n\">exc<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n                <span class=\"k\">raise<\/span>\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">warning<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">No config file found for database type: <\/span><span class=\"si\">{<\/span><span class=\"n\">normalized<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"p\">{}<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<p><strong>\u067e\u0631\u0648\u0646\u062f\u0647: \u0627\u0633\u062a\u0641\u0627\u062f\u0647\/\u06cc\u0627\u0631\u0627\u0646 .py<\/strong><\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">import<\/span> <span class=\"n\">datetime<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">get_field_value<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"n\">field_name<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">keys<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">row<\/span><span class=\"p\">[<\/span><span class=\"n\">field_name<\/span><span class=\"p\">]<\/span>\n        <span class=\"k\">elif<\/span> <span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">row<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">field_name<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">row<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">[ERROR] Failed to get field <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">field_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\">: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"bp\">None<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">normalize_value<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">if<\/span> <span class=\"n\">data_category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"nf\">round<\/span><span class=\"p\">(<\/span><span class=\"nf\">float<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">),<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">value<\/span>\n    <span class=\"k\">elif<\/span> <span class=\"n\">data_category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"n\">datetime<\/span><span class=\"p\">.<\/span><span class=\"n\">date<\/span><span class=\"p\">,<\/span> <span class=\"n\">datetime<\/span><span class=\"p\">.<\/span><span class=\"n\">datetime<\/span><span class=\"p\">)):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">value<\/span><span class=\"p\">.<\/span><span class=\"nf\">strftime<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">%Y-%m-%d<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span>\n    <span class=\"k\">elif<\/span> <span class=\"n\">data_category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n    <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">value<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">normalize_rows<\/span><span class=\"p\">(<\/span><span class=\"n\">rows<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">rows<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">rows<\/span>\n    <span class=\"n\">normalized<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">rows<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">keys<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n                <span class=\"n\">norm<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><span class=\"n\">key<\/span><span class=\"p\">:<\/span> <span class=\"nf\">normalize_value<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">[<\/span><span class=\"n\">key<\/span><span class=\"p\">],<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">key<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">row<\/span><span class=\"p\">.<\/span><span class=\"nf\">keys<\/span><span class=\"p\">()}<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">norm<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">tuple<\/span><span class=\"p\">(<\/span><span class=\"nf\">normalize_value<\/span><span class=\"p\">(<\/span><span class=\"n\">val<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">val<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">row<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">norm<\/span> <span class=\"o\">=<\/span> <span class=\"n\">row<\/span>\n        <span class=\"n\">normalized<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">(<\/span><span class=\"n\">norm<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">return<\/span> <span class=\"n\">normalized<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">classify_dtype<\/span><span class=\"p\">(<\/span><span class=\"n\">dtype_str<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">dtype_str<\/span> <span class=\"o\">=<\/span> <span class=\"n\">dtype_str<\/span><span class=\"p\">.<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nf\">any<\/span><span class=\"p\">(<\/span><span class=\"n\">token<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">dtype_str<\/span> <span class=\"k\">for<\/span> <span class=\"n\">token<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">int<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">bigint<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">smallint<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">tinyint<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">decimal<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">float<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">real<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">number<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">double<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]):<\/span>\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nf\">any<\/span><span class=\"p\">(<\/span><span class=\"n\">token<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">dtype_str<\/span> <span class=\"k\">for<\/span> <span class=\"n\">token<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">varchar<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">nvarchar<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">char<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">text<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]):<\/span>\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nf\">any<\/span><span class=\"p\">(<\/span><span class=\"n\">token<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">dtype_str<\/span> <span class=\"k\">for<\/span> <span class=\"n\">token<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">date<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime2<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">timestamp<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">time<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]):<\/span>\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime<\/span><span class=\"sh\">\"<\/span>\n    <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">load_query_from_file<\/span><span class=\"p\">(<\/span><span class=\"n\">file_path<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">params<\/span><span class=\"p\">:<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">with<\/span> <span class=\"nf\">open<\/span><span class=\"p\">(<\/span><span class=\"n\">file_path<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">r<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"k\">as<\/span> <span class=\"n\">f<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">template<\/span> <span class=\"o\">=<\/span> <span class=\"n\">f<\/span><span class=\"p\">.<\/span><span class=\"nf\">read<\/span><span class=\"p\">()<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">template<\/span><span class=\"p\">.<\/span><span class=\"nf\">format<\/span><span class=\"p\">(<\/span><span class=\"o\">**<\/span><span class=\"n\">params<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">[ERROR] Failed to load query from <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">file_path<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\">: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"\"<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u00b0<\/p>\n<p><strong>\u06a9\u0647 \u0642\u0633\u0645\u062a 1 \u0628\u0647 \u067e\u0627\u06cc\u0627\u0646 \u0645\u06cc \u0631\u0633\u062f.<\/strong> <\/p>\n<p>\u062f\u0631 \u0642\u0633\u0645\u062a 2 \u060c \u0645\u0627 Datavalidator Core (\u06a9\u0647 \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0633\u0641\u0627\u0631\u0634\u06cc \u060c \u0627\u06cc\u062c\u0627\u062f \u0634\u06cc\u0621 \u062f\u0645\u0627 \u060c \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0627\u0628\u0631\u062f\u0627\u062f\u0647 \u060c \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc \u06a9\u0644 \u0648 \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645) \u0648 \u067e\u0631\u0648\u0646\u062f\u0647 \u0627\u0635\u0644\u06cc \u0631\u0627 \u0634\u0627\u0645\u0644 \u0645\u06cc \u0634\u0648\u062f. <\/p>\n<p>\u0644\u0637\u0641\u0627\u064b \u0642\u0633\u0645\u062a 2 \u0631\u0627 \u062f\u0631 \u067e\u0627\u0633\u062e \u0628\u0639\u062f\u06cc \u0628\u0628\u06cc\u0646\u06cc\u062f.<\/p>\n<p>\u062f\u0631 \u0632\u06cc\u0631 \u06a9\u062f \u0642\u0633\u0645\u062a \u062f\u0648\u0645 &#8211; \u06cc\u0639\u0646\u06cc \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c \u0627\u0635\u0644\u06cc (\u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0647\u062f\u0641 \u0645\u0648\u0642\u062a \u060c \u062a\u0639\u0648\u06cc\u0636 \u0645\u0646\u0627\u0633\u0628 \u062f\u0631 \u0645\u062d\u0644 \u060c \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0627\u0628\u0631\u062f\u0627\u062f\u0647 \u060c \u0639\u0627\u062f\u06cc \u0633\u0627\u0632\u06cc \u06a9\u0644 \u0648 \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c\u06cc) \u0628\u0647 \u0639\u0644\u0627\u0648\u0647 \u067e\u0631\u0648\u0646\u062f\u0647 \u0627\u0635\u0644\u06cc \u0627\u0631\u06a9\u0633\u062a\u0631\u0627\u0633\u06cc\u0648\u0646 \u0627\u0633\u062a. \u0634\u0645\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 \u0627\u06cc\u0646 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 &#8220;\u0642\u0633\u0645\u062a 2&#8221; \u062f\u0631 \u0631\u0627\u0647 \u062d\u0644 \u062e\u0648\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f. \u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u062d\u0627\u0635\u0644 \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0642\u0628\u0644\u0627\u064b \u067e\u0631\u0648\u0646\u062f\u0647 \u0647\u0627 \u0631\u0627 \u0627\u0632 \u0642\u0633\u0645\u062a 1 (\u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u060c \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc CSV \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u062f\u06cc) \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0631\u062f\u0647 \u0627\u06cc\u062f. <\/p>\n<hr\/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter-rtl ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">\u0641\u0647\u0631\u0633\u062a \u0645\u0637\u0627\u0644\u0628<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/nabfollower.com\/blog\/%d8%af%d8%a7%d8%af%d9%87-%d9%87%d8%a7%db%8c-%d9%82%d8%af%db%8c%d9%85%db%8c-%d8%ac%d8%a7%d9%85%d8%b9%d9%87-dev\/#%D9%BE%D8%B1%D9%88%D9%86%D8%AF%D9%87_%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1_%D8%B3%D9%86%D8%AC_%D9%87%D8%A7data_validatorpy\" >\u067e\u0631\u0648\u0646\u062f\u0647: \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c \u0647\u0627\/data_validator.py<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/nabfollower.com\/blog\/%d8%af%d8%a7%d8%af%d9%87-%d9%87%d8%a7%db%8c-%d9%82%d8%af%db%8c%d9%85%db%8c-%d8%ac%d8%a7%d9%85%d8%b9%d9%87-dev\/#File_mainpy\" >File: main.py<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/nabfollower.com\/blog\/%d8%af%d8%a7%d8%af%d9%87-%d9%87%d8%a7%db%8c-%d9%82%d8%af%db%8c%d9%85%db%8c-%d8%ac%d8%a7%d9%85%d8%b9%d9%87-dev\/#%D8%AA%D9%88%D8%B6%DB%8C%D8%AD_%D9%86%D9%87%D8%A7%DB%8C%DB%8C\" >\u062a\u0648\u0636\u06cc\u062d \u0646\u0647\u0627\u06cc\u06cc<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"%D9%BE%D8%B1%D9%88%D9%86%D8%AF%D9%87_%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1_%D8%B3%D9%86%D8%AC_%D9%87%D8%A7data_validatorpy\"><\/span>\n<p>  \u067e\u0631\u0648\u0646\u062f\u0647: \u0627\u0639\u062a\u0628\u0627\u0631 \u0633\u0646\u062c \u0647\u0627\/data_validator.py<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">import<\/span> <span class=\"n\">logging<\/span>\n<span class=\"kn\">import<\/span> <span class=\"n\">pandas<\/span> <span class=\"k\">as<\/span> <span class=\"n\">pd<\/span>\n<span class=\"kn\">from<\/span> <span class=\"n\">utils.helpers<\/span> <span class=\"kn\">import<\/span> <span class=\"p\">(<\/span>\n    <span class=\"n\">classify_dtype<\/span><span class=\"p\">,<\/span>\n    <span class=\"n\">get_field_value<\/span><span class=\"p\">,<\/span>\n    <span class=\"n\">normalize_rows<\/span><span class=\"p\">,<\/span>\n<span class=\"p\">)<\/span>\n<span class=\"kn\">from<\/span> <span class=\"n\">validators.metadata_fetcher<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">MetadataFetcher<\/span>\n<span class=\"kn\">from<\/span> <span class=\"n\">validators.query_formatter<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">QueryFormatter<\/span>\n\n<span class=\"k\">class<\/span> <span class=\"nc\">DataValidator<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">mapping_filepath<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">src_db_type<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">tgt_db_type<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">src_db_name<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">tgt_db_name<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">num_tolerance<\/span><span class=\"p\">:<\/span> <span class=\"nb\">float<\/span> <span class=\"o\">=<\/span> <span class=\"mf\">0.0<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">enable_transformation<\/span><span class=\"p\">:<\/span> <span class=\"nb\">bool<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">False<\/span><span class=\"p\">,<\/span>\n                 <span class=\"n\">string_hash_mode<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">column<\/span><span class=\"sh\">\"<\/span>  <span class=\"c1\"># \"column\" for aggregate, \"row\" for per-row\n<\/span>                 <span class=\"p\">):<\/span>\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">\n        Initialize with mapping filepath, source\/target cursors, database types\/names,\n        numeric tolerance, transformation flag, and string hash mode.\n        <\/span><span class=\"sh\">\"\"\"<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">mapping_file<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping_filepath<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span> <span class=\"o\">=<\/span> <span class=\"n\">src_cursor<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tgt_cursor<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db_type<\/span> <span class=\"o\">=<\/span> <span class=\"n\">src_db_type<\/span><span class=\"p\">.<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db_type<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tgt_db_type<\/span><span class=\"p\">.<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db<\/span> <span class=\"o\">=<\/span> <span class=\"n\">src_db_name<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tgt_db_name<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">num_tolerance<\/span> <span class=\"o\">=<\/span> <span class=\"n\">num_tolerance<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">enable_transformation<\/span> <span class=\"o\">=<\/span> <span class=\"n\">enable_transformation<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">string_hash_mode<\/span> <span class=\"o\">=<\/span> <span class=\"n\">string_hash_mode<\/span><span class=\"p\">.<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n\n        <span class=\"kn\">from<\/span> <span class=\"n\">utils.config_loader<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ConfigLoader<\/span>\n        <span class=\"n\">config_loader<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ConfigLoader<\/span><span class=\"p\">()<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_config<\/span> <span class=\"o\">=<\/span> <span class=\"n\">config_loader<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_db_config<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db_type<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_config<\/span> <span class=\"o\">=<\/span> <span class=\"n\">config_loader<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_db_config<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db_type<\/span><span class=\"p\">)<\/span>\n\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_formatter<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">QueryFormatter<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_config<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_formatter<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">QueryFormatter<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_config<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db<\/span><span class=\"p\">)<\/span>\n\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_metadata_fetcher<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">MetadataFetcher<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db_type<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_metadata_fetcher<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">MetadataFetcher<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db_type<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">_execute_query<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">):<\/span>\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">\n        Executes the given query using the provided cursor.\n        For BigQuery, call .result(); for others, call fetchall().\n        Returns a list.\n        <\/span><span class=\"sh\">\"\"\"<\/span>\n        <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">query<\/span><span class=\"p\">.<\/span><span class=\"nf\">strip<\/span><span class=\"p\">():<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Empty query provided; skipping execution.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">return<\/span> <span class=\"p\">[]<\/span>\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Executing query: <\/span><span class=\"si\">{<\/span><span class=\"n\">query<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_db_type<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">bigquery<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">or<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_db_type<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">bigquery<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">exec_result<\/span> <span class=\"o\">=<\/span> <span class=\"n\">cursor<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute<\/span><span class=\"p\">(<\/span><span class=\"n\">query<\/span><span class=\"p\">)<\/span>\n                <span class=\"k\">if<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">exec_result<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">result<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n                    <span class=\"k\">return<\/span> <span class=\"nf\">list<\/span><span class=\"p\">(<\/span><span class=\"n\">exec_result<\/span><span class=\"p\">.<\/span><span class=\"nf\">result<\/span><span class=\"p\">())<\/span>\n                <span class=\"k\">return<\/span> <span class=\"n\">exec_result<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">cursor<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute<\/span><span class=\"p\">(<\/span><span class=\"n\">query<\/span><span class=\"p\">)<\/span>\n                <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n                    <span class=\"k\">return<\/span> <span class=\"n\">cursor<\/span><span class=\"p\">.<\/span><span class=\"nf\">fetchall<\/span><span class=\"p\">()<\/span>\n                <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">fe<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Failed to fetchall() on cursor: <\/span><span class=\"si\">{<\/span><span class=\"n\">fe<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n                    <span class=\"k\">return<\/span> <span class=\"p\">[]<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Query execution failed for [<\/span><span class=\"si\">{<\/span><span class=\"n\">query<\/span><span class=\"si\">}<\/span><span class=\"s\">]: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">return<\/span> <span class=\"p\">[]<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">execute_and_normalize<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">results<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_execute_query<\/span><span class=\"p\">(<\/span><span class=\"n\">cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">query<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">results<\/span> <span class=\"ow\">is<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"bp\">None<\/span>\n        <span class=\"k\">return<\/span> <span class=\"nf\">normalize_rows<\/span><span class=\"p\">(<\/span><span class=\"n\">results<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">_to_dict<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">record<\/span><span class=\"p\">,<\/span> <span class=\"n\">category<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">:<\/span>\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">\n        Converts a record (tuple or dict) into a canonical dictionary.\n        For numeric: keys = [<\/span><span class=\"sh\">\"<\/span><span class=\"s\">min_value<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"s\">max_value<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"s\">avg_value<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"s\">sum_value<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"s\">distinct_count<\/span><span class=\"sh\">\"<\/span><span class=\"s\">].\n        For datetime: keys = [<\/span><span class=\"sh\">\"<\/span><span class=\"s\">min_datetime<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"s\">max_datetime<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"s\">distinct_dates<\/span><span class=\"sh\">\"<\/span><span class=\"s\">].\n        For string: key = [<\/span><span class=\"sh\">\"<\/span><span class=\"s\">hash_value<\/span><span class=\"sh\">\"<\/span><span class=\"s\">].\n        <\/span><span class=\"sh\">\"\"\"<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">record<\/span><span class=\"p\">,<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">record<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">keys<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">min_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">max_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">avg_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">sum_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">distinct_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">elif<\/span> <span class=\"n\">category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">keys<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">min_datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">max_datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">distinct_dates<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">elif<\/span> <span class=\"n\">category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">keys<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">hash_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">keys<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n            <span class=\"k\">return<\/span> <span class=\"nf\">dict<\/span><span class=\"p\">(<\/span><span class=\"nf\">zip<\/span><span class=\"p\">(<\/span><span class=\"n\">keys<\/span><span class=\"p\">,<\/span> <span class=\"n\">record<\/span><span class=\"p\">))<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">_normalize_aggregate<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">record<\/span><span class=\"p\">,<\/span> <span class=\"n\">category<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">:<\/span>\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">\n        Normalize an aggregate record:\n          * For numeric: convert values to float and round to two decimals.\n          * For datetime: trim the string.\n          * For string: lower-case and strip.\n        Returns a canonical dictionary.\n        <\/span><span class=\"sh\">\"\"\"<\/span>\n        <span class=\"n\">rec_dict<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_to_dict<\/span><span class=\"p\">(<\/span><span class=\"n\">record<\/span><span class=\"p\">,<\/span> <span class=\"n\">category<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">normalized<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">for<\/span> <span class=\"n\">k<\/span><span class=\"p\">,<\/span> <span class=\"n\">v<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">rec_dict<\/span><span class=\"p\">.<\/span><span class=\"nf\">items<\/span><span class=\"p\">():<\/span>\n                <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">normalized<\/span><span class=\"p\">[<\/span><span class=\"n\">k<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">round<\/span><span class=\"p\">(<\/span><span class=\"nf\">float<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">),<\/span> <span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\n                <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">normalized<\/span><span class=\"p\">[<\/span><span class=\"n\">k<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">v<\/span>\n        <span class=\"k\">elif<\/span> <span class=\"n\">category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">for<\/span> <span class=\"n\">k<\/span><span class=\"p\">,<\/span> <span class=\"n\">v<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">rec_dict<\/span><span class=\"p\">.<\/span><span class=\"nf\">items<\/span><span class=\"p\">():<\/span>\n                <span class=\"n\">normalized<\/span><span class=\"p\">[<\/span><span class=\"n\">k<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">v<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span>\n        <span class=\"k\">elif<\/span> <span class=\"n\">category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">normalized<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">hash_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">rec_dict<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">hash_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">normalized<\/span> <span class=\"o\">=<\/span> <span class=\"n\">rec_dict<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">normalized<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">_prepare_temp_object<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">custom_input<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">formatter<\/span><span class=\"p\">:<\/span> <span class=\"n\">QueryFormatter<\/span><span class=\"p\">,<\/span> <span class=\"n\">schema<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">cursor<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">\n        Create a temporary table\/view from a custom query.\n        If custom_input ends with <\/span><span class=\"sh\">\"<\/span><span class=\"s\">.sql<\/span><span class=\"sh\">\"<\/span><span class=\"s\">, load its content; if it starts with <\/span><span class=\"sh\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"sh\">\"<\/span><span class=\"s\">, assume it\u2019s a query.\n        Then, execute: CREATE TEMPORARY TABLE <table>_temp AS (<custom query=\"\">);\n        Return the temporary table\/view name.\n        <span class=\"sh\">\"\"\"<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"kn\">from<\/span> <span class=\"n\">utils.helpers<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">load_query_from_file<\/span>\n            <span class=\"n\">query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">custom_input<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">custom_input<\/span><span class=\"p\">.<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">endswith<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">.sql<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n                <span class=\"n\">query<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">load_query_from_file<\/span><span class=\"p\">(<\/span><span class=\"n\">custom_input<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"sh\">\"<\/span><span class=\"s\">database<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">formatter<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">schema<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">schema<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">table<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">table<\/span><span class=\"p\">})<\/span>\n            <span class=\"n\">temp_name<\/span> <span class=\"o\">=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">table<\/span><span class=\"si\">}<\/span><span class=\"s\">_temp<\/span><span class=\"sh\">\"<\/span>\n            <span class=\"n\">create_temp<\/span> <span class=\"o\">=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">CREATE TEMPORARY TABLE <\/span><span class=\"si\">{<\/span><span class=\"n\">temp_name<\/span><span class=\"si\">}<\/span><span class=\"s\"> AS (<\/span><span class=\"si\">{<\/span><span class=\"n\">query<\/span><span class=\"si\">}<\/span><span class=\"s\">);<\/span><span class=\"sh\">\"<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Creating temporary object: <\/span><span class=\"si\">{<\/span><span class=\"n\">create_temp<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">cursor<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute<\/span><span class=\"p\">(<\/span><span class=\"n\">create_temp<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">temp_name<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Failed to create temporary object from custom query: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">formatter<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"si\">}<\/span><span class=\"s\">.<\/span><span class=\"si\">{<\/span><span class=\"n\">schema<\/span><span class=\"si\">}<\/span><span class=\"s\">.<\/span><span class=\"si\">{<\/span><span class=\"n\">table<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>  <span class=\"c1\"># fallback to fully qualified name\n<\/span>\n    <span class=\"k\">def<\/span> <span class=\"nf\">get_src_metadata<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">schema<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">metadata<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_metadata_fetcher<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_metadata<\/span><span class=\"p\">(<\/span><span class=\"n\">schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">metadata<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">warning<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">No source metadata available for table: <\/span><span class=\"si\">{<\/span><span class=\"n\">table<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">metadata<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">get_tgt_metadata<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">schema<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">metadata<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_metadata_fetcher<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_metadata<\/span><span class=\"p\">(<\/span><span class=\"n\">schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">metadata<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">warning<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">No target metadata available for table: <\/span><span class=\"si\">{<\/span><span class=\"n\">table<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">metadata<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">get_query_for_column<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">formatter<\/span><span class=\"p\">:<\/span> <span class=\"n\">QueryFormatter<\/span><span class=\"p\">,<\/span> <span class=\"n\">default_key<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">schema<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra_params<\/span><span class=\"p\">:<\/span> <span class=\"nb\">dict<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">None<\/span><span class=\"p\">,<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">:<\/span> <span class=\"nb\">dict<\/span> <span class=\"o\">=<\/span> <span class=\"bp\">None<\/span><span class=\"p\">,<\/span> <span class=\"n\">side<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">source<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">\n        Build the aggregate query for the given column.\n        If a custom query (or SQL file path) is provided in mapping_row (using the field <\/span><span class=\"sh\">\"<\/span><span class=\"s\">source_name<\/span><span class=\"sh\">\"<\/span><span class=\"s\"> if side==<\/span><span class=\"sh\">\"<\/span><span class=\"s\">source<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\n        or <\/span><span class=\"sh\">\"<\/span><span class=\"s\">target_name<\/span><span class=\"sh\">\"<\/span><span class=\"s\"> if side==<\/span><span class=\"sh\">\"<\/span><span class=\"s\">target<\/span><span class=\"sh\">\"<\/span><span class=\"s\">), then create a temporary object using that query and use it for the FROM clause.\n        Otherwise, use the fully qualified object name.\n        <\/span><span class=\"sh\">\"\"\"<\/span>\n        <span class=\"n\">custom_input<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"\"<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">side<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">source<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">custom_input<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">source_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">custom_input<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">target_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span>\n\n        <span class=\"k\">if<\/span> <span class=\"n\">custom_input<\/span><span class=\"p\">.<\/span><span class=\"nf\">upper<\/span><span class=\"p\">().<\/span><span class=\"nf\">startswith<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SELECT<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"ow\">or<\/span> <span class=\"n\">custom_input<\/span><span class=\"p\">.<\/span><span class=\"nf\">endswith<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">.sql<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n            <span class=\"c1\"># Create temporary object.\n<\/span>            <span class=\"n\">temp_obj<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_prepare_temp_object<\/span><span class=\"p\">(<\/span><span class=\"n\">custom_input<\/span><span class=\"p\">,<\/span> <span class=\"n\">formatter<\/span><span class=\"p\">,<\/span> <span class=\"n\">schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">,<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span> <span class=\"k\">if<\/span> <span class=\"n\">side<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">source<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">extra_params<\/span> <span class=\"ow\">is<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">extra_params<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n            <span class=\"n\">extra_params<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">from_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"n\">temp_obj<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">extra_params<\/span> <span class=\"ow\">is<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">extra_params<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n            <span class=\"n\">extra_params<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">from_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">formatter<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"si\">}<\/span><span class=\"s\">.<\/span><span class=\"si\">{<\/span><span class=\"n\">schema<\/span><span class=\"si\">}<\/span><span class=\"s\">.<\/span><span class=\"si\">{<\/span><span class=\"n\">table<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\n        <span class=\"n\">key<\/span> <span class=\"o\">=<\/span> <span class=\"n\">default_key<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">default_key<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">string_hash_mode<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">column<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">key<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string_all<\/span><span class=\"sh\">\"<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"n\">key<\/span><span class=\"p\">,<\/span> <span class=\"n\">schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra_params<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">validate_column<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">:<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_col<\/span><span class=\"p\">:<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_schema<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\n                        <span class=\"n\">tgt_schema<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_total<\/span><span class=\"p\">:<\/span> <span class=\"nb\">any<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_total<\/span><span class=\"p\">:<\/span> <span class=\"nb\">any<\/span><span class=\"p\">,<\/span>\n                        <span class=\"n\">report_list<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_meta<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">col_name<\/span> <span class=\"o\">=<\/span> <span class=\"n\">src_col<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">column_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span>\n        <span class=\"n\">data_category<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">classify_dtype<\/span><span class=\"p\">(<\/span><span class=\"n\">src_col<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">data_type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">])<\/span>\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">debug<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Validating column <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">col_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\"> (Type: <\/span><span class=\"si\">{<\/span><span class=\"n\">src_col<\/span><span class=\"p\">[<\/span><span class=\"sh\">'<\/span><span class=\"s\">data_type<\/span><span class=\"sh\">'<\/span><span class=\"p\">]<\/span><span class=\"si\">}<\/span><span class=\"s\">, Category: <\/span><span class=\"si\">{<\/span><span class=\"n\">data_category<\/span><span class=\"si\">}<\/span><span class=\"s\">)<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n        <span class=\"c1\"># Sanitize WHERE clause.\n<\/span>        <span class=\"n\">where_clause<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">where_clause<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">where_clause<\/span> <span class=\"ow\">or<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">where_clause<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">nan<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">where_clause<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"\"<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">where_clause<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">where_clause<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span>\n        <span class=\"n\">extra<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{}<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">where_clause<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">extra<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">where_clause<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">WHERE <\/span><span class=\"si\">{<\/span><span class=\"n\">where_clause<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\n\n        <span class=\"c1\"># Sanitize exclude_columns.\n<\/span>        <span class=\"n\">exclude<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">exclude_columns<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">exclude<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"nb\">list<\/span><span class=\"p\">,<\/span> <span class=\"nb\">tuple<\/span><span class=\"p\">)):<\/span>\n            <span class=\"n\">exclude<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span> <span class=\"k\">for<\/span> <span class=\"n\">x<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">exclude<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">elif<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">exclude<\/span> <span class=\"ow\">or<\/span> <span class=\"p\">(<\/span><span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">exclude<\/span><span class=\"p\">,<\/span> <span class=\"nb\">float<\/span><span class=\"p\">)<\/span> <span class=\"ow\">and<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">exclude<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">().<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">nan<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n            <span class=\"n\">exclude<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"\"<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">exclude<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">.<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">[<\/span><span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span> <span class=\"k\">for<\/span> <span class=\"n\">x<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">exclude<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">,<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)]:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Skipping column <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">col_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\"> as it is excluded.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">return<\/span>\n\n        <span class=\"n\">default_key<\/span> <span class=\"o\">=<\/span> <span class=\"n\">data_category<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">default_key<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">string_hash_mode<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">column<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">default_key<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string_all<\/span><span class=\"sh\">\"<\/span>\n\n        <span class=\"n\">src_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_query_for_column<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_formatter<\/span><span class=\"p\">,<\/span> <span class=\"n\">default_key<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra<\/span><span class=\"p\">,<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">,<\/span> <span class=\"n\">side<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">source<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">tgt_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_query_for_column<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_formatter<\/span><span class=\"p\">,<\/span> <span class=\"n\">default_key<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra<\/span><span class=\"p\">,<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">,<\/span> <span class=\"n\">side<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">target<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">src_result<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute_and_normalize<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_query<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">tgt_result<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute_and_normalize<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_query<\/span><span class=\"p\">,<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Column <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">col_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\"> raw aggregation:<\/span><span class=\"se\">\\n<\/span><span class=\"s\">  source: <\/span><span class=\"si\">{<\/span><span class=\"n\">src_result<\/span><span class=\"si\">}<\/span><span class=\"se\">\\n<\/span><span class=\"s\">  target: <\/span><span class=\"si\">{<\/span><span class=\"n\">tgt_result<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">src_aggregate<\/span> <span class=\"o\">=<\/span> <span class=\"n\">src_result<\/span>\n        <span class=\"n\">tgt_aggregate<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tgt_result<\/span>\n\n        <span class=\"k\">if<\/span> <span class=\"n\">src_result<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">tgt_result<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">normalized_src<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_normalize_aggregate<\/span><span class=\"p\">(<\/span><span class=\"n\">src_result<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">normalized_tgt<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_normalize_aggregate<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_result<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"n\">data_category<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">normalized_src<\/span><span class=\"p\">,<\/span> <span class=\"n\">normalized_tgt<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{},<\/span> <span class=\"p\">{}<\/span>\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Normalized aggregate for <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">col_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\">:<\/span><span class=\"se\">\\n<\/span><span class=\"s\">  source: <\/span><span class=\"si\">{<\/span><span class=\"n\">normalized_src<\/span><span class=\"si\">}<\/span><span class=\"se\">\\n<\/span><span class=\"s\">  target: <\/span><span class=\"si\">{<\/span><span class=\"n\">normalized_tgt<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n        <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Pass<\/span><span class=\"sh\">\"<\/span>\n        <span class=\"n\">remarks<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"\"<\/span>\n\n        <span class=\"k\">if<\/span> <span class=\"n\">data_category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">for<\/span> <span class=\"n\">key<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">min_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">max_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">avg_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">sum_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">distinct_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]:<\/span>\n                <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">src_val<\/span> <span class=\"o\">=<\/span> <span class=\"n\">normalized_src<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">key<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n                    <span class=\"n\">tgt_val<\/span> <span class=\"o\">=<\/span> <span class=\"n\">normalized_tgt<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">key<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n                    <span class=\"k\">if<\/span> <span class=\"nf\">abs<\/span><span class=\"p\">(<\/span><span class=\"nf\">float<\/span><span class=\"p\">(<\/span><span class=\"n\">src_val<\/span><span class=\"p\">)<\/span> <span class=\"o\">-<\/span> <span class=\"nf\">float<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_val<\/span><span class=\"p\">))<\/span> <span class=\"o\">&gt;<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">num_tolerance<\/span><span class=\"p\">:<\/span>\n                        <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Fail<\/span><span class=\"sh\">\"<\/span>\n                        <span class=\"n\">remarks<\/span> <span class=\"o\">+=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">key<\/span><span class=\"si\">}<\/span><span class=\"s\"> mismatch; <\/span><span class=\"sh\">\"<\/span>\n                <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">ex<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Error comparing numeric key <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">key<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\"> for column <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">col_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\">: <\/span><span class=\"si\">{<\/span><span class=\"n\">ex<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">elif<\/span> <span class=\"n\">data_category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">for<\/span> <span class=\"n\">key<\/span> <span class=\"ow\">in<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">min_datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">max_datetime<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">distinct_dates<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]:<\/span>\n                <span class=\"k\">if<\/span> <span class=\"n\">normalized_src<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">key<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">normalized_tgt<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">key<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">):<\/span>\n                    <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Fail<\/span><span class=\"sh\">\"<\/span>\n                    <span class=\"n\">remarks<\/span> <span class=\"o\">+=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">key<\/span><span class=\"si\">}<\/span><span class=\"s\"> mismatch; <\/span><span class=\"sh\">\"<\/span>\n        <span class=\"k\">elif<\/span> <span class=\"n\">data_category<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">string<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">src_hash<\/span> <span class=\"o\">=<\/span> <span class=\"n\">normalized_src<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">hash_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">tgt_hash<\/span> <span class=\"o\">=<\/span> <span class=\"n\">normalized_tgt<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">hash_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Comparing hash for <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">col_name<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\">: source=<\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">src_hash<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\"> vs target=<\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">tgt_hash<\/span><span class=\"si\">}<\/span><span class=\"sh\">'\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">src_hash<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">tgt_hash<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Fail<\/span><span class=\"sh\">\"<\/span>\n                <span class=\"n\">remarks<\/span> <span class=\"o\">+=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">String hash mismatch; <\/span><span class=\"sh\">\"<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">normalized_src<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">normalized_tgt<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Fail<\/span><span class=\"sh\">\"<\/span>\n                <span class=\"n\">remarks<\/span> <span class=\"o\">+=<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">data_category<\/span><span class=\"p\">.<\/span><span class=\"nf\">capitalize<\/span><span class=\"p\">()<\/span><span class=\"si\">}<\/span><span class=\"s\"> data mismatch; <\/span><span class=\"sh\">\"<\/span>\n\n        <span class=\"n\">src_null_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">null_check<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">tgt_null_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">null_check<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">src_null_vals<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_execute_query<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_null_query<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">tgt_null_vals<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_execute_query<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_null_query<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">src_null_count<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">get_field_value<\/span><span class=\"p\">(<\/span><span class=\"n\">src_null_vals<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">missing_values<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"nf\">if <\/span><span class=\"p\">(<\/span><span class=\"n\">src_null_vals<\/span> <span class=\"ow\">and<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">src_null_vals<\/span><span class=\"p\">)<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"bp\">None<\/span>\n        <span class=\"n\">tgt_null_count<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">get_field_value<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_null_vals<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">missing_values<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"nf\">if <\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_null_vals<\/span> <span class=\"ow\">and<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_null_vals<\/span><span class=\"p\">)<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"bp\">None<\/span>\n\n        <span class=\"n\">src_dup_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">duplicate_check<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">tgt_dup_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">duplicate_check<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">src_dups<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_execute_query<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_dup_query<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">tgt_dups<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">_execute_query<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_dup_query<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">src_dup_count<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sum<\/span><span class=\"p\">(<\/span><span class=\"nf\">get_field_value<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">duplicate_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">src_dups<\/span><span class=\"p\">)<\/span> <span class=\"k\">if<\/span> <span class=\"n\">src_dups<\/span> <span class=\"k\">else<\/span> <span class=\"bp\">None<\/span>\n        <span class=\"n\">tgt_dup_count<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sum<\/span><span class=\"p\">(<\/span><span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"nf\">get_field_value<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">duplicate_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">))<\/span> <span class=\"k\">for<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">tgt_dups<\/span> <span class=\"k\">if<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"nf\">get_field_value<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">duplicate_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)).<\/span><span class=\"nf\">isdigit<\/span><span class=\"p\">())<\/span> <span class=\"k\">if<\/span> <span class=\"n\">tgt_dups<\/span> <span class=\"k\">else<\/span> <span class=\"bp\">None<\/span>\n\n        <span class=\"k\">if<\/span> <span class=\"n\">src_null_count<\/span> <span class=\"ow\">is<\/span> <span class=\"ow\">not<\/span> <span class=\"bp\">None<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">tgt_null_count<\/span> <span class=\"ow\">is<\/span> <span class=\"ow\">not<\/span> <span class=\"bp\">None<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">src_null_count<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">tgt_null_count<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Fail<\/span><span class=\"sh\">\"<\/span>\n            <span class=\"n\">remarks<\/span> <span class=\"o\">+=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Null count mismatch; <\/span><span class=\"sh\">\"<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">src_dup_count<\/span> <span class=\"ow\">is<\/span> <span class=\"ow\">not<\/span> <span class=\"bp\">None<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">tgt_dup_count<\/span> <span class=\"ow\">is<\/span> <span class=\"ow\">not<\/span> <span class=\"bp\">None<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">src_dup_count<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">tgt_dup_count<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">col_status<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Fail<\/span><span class=\"sh\">\"<\/span>\n            <span class=\"n\">remarks<\/span> <span class=\"o\">+=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Duplicate count mismatch; <\/span><span class=\"sh\">\"<\/span>\n\n        <span class=\"n\">report_list<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">({<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">mapping_id<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">mapping_row<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">mapping_id<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">table<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">column<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">col_name<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">data_type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">src_col<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">data_type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">],<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">status<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">col_status<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">remarks<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">remarks<\/span><span class=\"p\">.<\/span><span class=\"nf\">strip<\/span><span class=\"p\">(),<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">src_total_rows<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">src_total<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">tgt_total_rows<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">tgt_total<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">src_aggregate<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">src_aggregate<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">tgt_aggregate<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">tgt_aggregate<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">src_null_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">src_null_count<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">tgt_null_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">tgt_null_count<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">src_duplicate_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">src_dup_count<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">tgt_duplicate_count<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">tgt_dup_count<\/span>\n        <span class=\"p\">})<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">run_validation<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">pd<\/span><span class=\"p\">.<\/span><span class=\"n\">DataFrame<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">mapping_df<\/span> <span class=\"o\">=<\/span> <span class=\"n\">pd<\/span><span class=\"p\">.<\/span><span class=\"nf\">read_csv<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">mapping_file<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Loaded mapping file: <\/span><span class=\"si\">{<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">mapping_file<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Failed to load mapping file [<\/span><span class=\"si\">{<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">mapping_file<\/span><span class=\"si\">}<\/span><span class=\"s\">]: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">pd<\/span><span class=\"p\">.<\/span><span class=\"nc\">DataFrame<\/span><span class=\"p\">()<\/span>\n\n        <span class=\"n\">report_list<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n        <span class=\"k\">for<\/span> <span class=\"n\">_<\/span><span class=\"p\">,<\/span> <span class=\"n\">mapping<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">mapping_df<\/span><span class=\"p\">.<\/span><span class=\"nf\">iterrows<\/span><span class=\"p\">():<\/span>\n            <span class=\"c1\"># For the fully qualified object name, extract schema and object names from source_name and target_name.\n<\/span>            <span class=\"n\">source_full<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">source_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">target_full<\/span> <span class=\"o\">=<\/span> <span class=\"n\">mapping<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">target_name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">if<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">.<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">source_full<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">parts<\/span> <span class=\"o\">=<\/span> <span class=\"n\">source_full<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n                <span class=\"n\">src_schema<\/span> <span class=\"o\">=<\/span> <span class=\"n\">parts<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n                <span class=\"n\">src_table<\/span> <span class=\"o\">=<\/span> <span class=\"n\">parts<\/span><span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">src_schema<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"\"<\/span>\n                <span class=\"n\">src_table<\/span> <span class=\"o\">=<\/span> <span class=\"n\">source_full<\/span>\n            <span class=\"k\">if<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">.<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">target_full<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">parts<\/span> <span class=\"o\">=<\/span> <span class=\"n\">target_full<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n                <span class=\"n\">tgt_schema<\/span> <span class=\"o\">=<\/span> <span class=\"n\">parts<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n                <span class=\"n\">tgt_table<\/span> <span class=\"o\">=<\/span> <span class=\"n\">parts<\/span><span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">tgt_schema<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"\"<\/span>\n                <span class=\"n\">tgt_table<\/span> <span class=\"o\">=<\/span> <span class=\"n\">target_full<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Processing mapping ID <\/span><span class=\"si\">{<\/span><span class=\"n\">mapping<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">'<\/span><span class=\"s\">mapping_id<\/span><span class=\"sh\">'<\/span><span class=\"p\">)<\/span><span class=\"si\">}<\/span><span class=\"s\">: <\/span><span class=\"si\">{<\/span><span class=\"n\">src_table<\/span><span class=\"si\">}<\/span><span class=\"s\"> -&gt; <\/span><span class=\"si\">{<\/span><span class=\"n\">tgt_table<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n            <span class=\"n\">total_rows_key<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">total_rows<\/span><span class=\"sh\">\"<\/span>\n            <span class=\"n\">src_total_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"n\">total_rows_key<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra_params<\/span><span class=\"o\">=<\/span><span class=\"p\">{})<\/span>\n            <span class=\"n\">tgt_total_query<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_formatter<\/span><span class=\"p\">.<\/span><span class=\"nf\">format_query<\/span><span class=\"p\">(<\/span><span class=\"n\">total_rows_key<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">extra_params<\/span><span class=\"o\">=<\/span><span class=\"p\">{})<\/span>\n            <span class=\"n\">src_total_res<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute_and_normalize<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_total_query<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">tgt_total_res<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">execute_and_normalize<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_total_query<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">numeric<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">src_total<\/span> <span class=\"o\">=<\/span> <span class=\"n\">src_total_res<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">][<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"k\">if<\/span> <span class=\"n\">src_total_res<\/span> <span class=\"ow\">and<\/span> <span class=\"ow\">not<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">src_total_res<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">keys<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"bp\">None<\/span>\n            <span class=\"n\">tgt_total<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tgt_total_res<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">][<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"k\">if<\/span> <span class=\"n\">tgt_total_res<\/span> <span class=\"ow\">and<\/span> <span class=\"ow\">not<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_total_res<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">],<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">keys<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span> <span class=\"k\">else<\/span> <span class=\"bp\">None<\/span>\n\n            <span class=\"n\">src_meta<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_src_metadata<\/span><span class=\"p\">(<\/span><span class=\"n\">src_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">tgt_meta<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">get_tgt_metadata<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">)<\/span>\n            <span class=\"k\">for<\/span> <span class=\"n\">src_col<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">src_meta<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"nf\">validate_column<\/span><span class=\"p\">(<\/span><span class=\"n\">mapping<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_col<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_schema<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_table<\/span><span class=\"p\">,<\/span> <span class=\"n\">src_total<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_total<\/span><span class=\"p\">,<\/span> <span class=\"n\">report_list<\/span><span class=\"p\">,<\/span> <span class=\"n\">tgt_meta<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">report_df<\/span> <span class=\"o\">=<\/span> <span class=\"n\">pd<\/span><span class=\"p\">.<\/span><span class=\"nc\">DataFrame<\/span><span class=\"p\">(<\/span><span class=\"n\">report_list<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">report_df<\/span><span class=\"p\">.<\/span><span class=\"nf\">to_csv<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">validation_report.csv<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">index<\/span><span class=\"o\">=<\/span><span class=\"bp\">False<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Validation report saved to <\/span><span class=\"sh\">'<\/span><span class=\"s\">validation_report.csv<\/span><span class=\"sh\">'<\/span><span class=\"s\">.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">Exception<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Failed to save validation report: <\/span><span class=\"si\">{<\/span><span class=\"n\">e<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">report_df<\/span>\n\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>Enter fullscreen mode<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg>\n\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>Exit fullscreen mode<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg>\n\n<\/div>\n<\/div>\n\n\n\n\n\n<hr\/>\n\n<h3><span class=\"ez-toc-section\" id=\"File_mainpy\"><\/span>\n  \n  \n  File: main.py\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">import<\/span> <span class=\"n\">logging<\/span>\n<span class=\"kn\">from<\/span> <span class=\"n\">validators.data_validator<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">DataValidator<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">main<\/span><span class=\"p\">():<\/span>\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">basicConfig<\/span><span class=\"p\">(<\/span><span class=\"n\">level<\/span><span class=\"o\">=<\/span><span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">INFO<\/span><span class=\"p\">,<\/span>\n                        <span class=\"nb\">format<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">%(asctime)s - %(levelname)s - %(message)s<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">=== Dynamic Data Validation ===<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">mapping_file<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">mapping\/mapping_data.csv<\/span><span class=\"sh\">\"<\/span>\n    <span class=\"n\">source_db_type<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">bigquery<\/span><span class=\"sh\">\"<\/span>     <span class=\"c1\"># Adjust as needed.\n<\/span>    <span class=\"n\">target_db_type<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">snowflake<\/span><span class=\"sh\">\"<\/span>     <span class=\"c1\"># Adjust as needed.\n<\/span>    <span class=\"n\">source_db_name<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">db<\/span><span class=\"sh\">\"<\/span>           <span class=\"c1\"># This value is the database (or project) prefix.\n<\/span>    <span class=\"n\">target_db_name<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">db<\/span><span class=\"sh\">\"<\/span>           <span class=\"c1\"># Similarly for the target.\n<\/span>\n    <span class=\"c1\"># Replace these dummy cursor objects with your actual connectors.\n<\/span>    <span class=\"k\">class<\/span> <span class=\"nc\">DummyCursor<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">def<\/span> <span class=\"nf\">execute<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">query<\/span><span class=\"p\">):<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Dummy executing: <\/span><span class=\"si\">{<\/span><span class=\"n\">query<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n            <span class=\"c1\"># For BigQuery queries with backticks, simulate .result()\n<\/span>            <span class=\"k\">if<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">FROM `<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">class<\/span> <span class=\"nc\">DummyResult<\/span><span class=\"p\">:<\/span>\n                    <span class=\"k\">def<\/span> <span class=\"nf\">result<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\n                        <span class=\"k\">if<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">COUNT(*)<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                            <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"mi\">20<\/span><span class=\"p\">,)]<\/span>\n                        <span class=\"k\">elif<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MIN(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">and<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MAX(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">and<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">AVG(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                            <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"mf\">100.5<\/span><span class=\"p\">,<\/span> <span class=\"mf\">500.0<\/span><span class=\"p\">,<\/span> <span class=\"mf\">271.3<\/span><span class=\"p\">,<\/span> <span class=\"mf\">5426.0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">20<\/span><span class=\"p\">)]<\/span>\n                        <span class=\"k\">elif<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">TO_HEX(MD5<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">or<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MD5(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                            <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">07a3007e20f82d569079dedc5f5fb153<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,)]<\/span>\n                        <span class=\"k\">elif<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MIN(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">and<\/span> <span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">DATE(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">or<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">TO_DATE(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">):<\/span>\n                            <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">2024-01-01<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">2024-01-20<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">20<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)]<\/span>\n                        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                            <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">dummy_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,)]<\/span>\n                <span class=\"k\">return<\/span> <span class=\"nc\">DummyResult<\/span><span class=\"p\">()<\/span>\n            <span class=\"c1\"># For non-backtick queries, return tuples.\n<\/span>            <span class=\"k\">if<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">COUNT(*)<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"mi\">20<\/span><span class=\"p\">,)]<\/span>\n            <span class=\"k\">elif<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MIN(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">and<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MAX(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">and<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">AVG(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"mf\">101.0<\/span><span class=\"p\">,<\/span> <span class=\"mf\">500.0<\/span><span class=\"p\">,<\/span> <span class=\"mf\">271.35<\/span><span class=\"p\">,<\/span> <span class=\"mf\">5427.0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">20<\/span><span class=\"p\">)]<\/span>\n            <span class=\"k\">elif<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">HASHBYTES<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">or<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">LISTAGG<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">or<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MD5(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">07a3007e20f82d569079dedc5f5fb153<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,)]<\/span>\n            <span class=\"k\">elif<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MIN(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">and<\/span> <span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">TO_DATE(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span> <span class=\"ow\">or<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">DATE(<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">query<\/span><span class=\"p\">):<\/span>\n                <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">2024-01-01<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">2024-01-20<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">20<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)]<\/span>\n            <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">dummy_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,)]<\/span>\n        <span class=\"k\">def<\/span> <span class=\"nf\">fetchall<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">return<\/span> <span class=\"p\">[(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">dummy_value<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,)]<\/span>\n        <span class=\"k\">def<\/span> <span class=\"nf\">close<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\n            <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">DummyCursor closed.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">src_cursor<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">DummyCursor<\/span><span class=\"p\">()<\/span>\n    <span class=\"n\">tgt_cursor<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">DummyCursor<\/span><span class=\"p\">()<\/span>\n\n    <span class=\"n\">validator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">DataValidator<\/span><span class=\"p\">(<\/span><span class=\"n\">mapping_file<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">source_db_type<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">target_db_type<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">source_db_name<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">target_db_name<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">num_tolerance<\/span><span class=\"o\">=<\/span><span class=\"mf\">0.001<\/span><span class=\"p\">,<\/span>\n                              <span class=\"n\">enable_transformation<\/span><span class=\"o\">=<\/span><span class=\"bp\">True<\/span><span class=\"p\">,<\/span>  <span class=\"c1\"># Set True to enable custom query handling and temp table creation.\n<\/span>                              <span class=\"n\">string_hash_mode<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">column<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">report_df<\/span> <span class=\"o\">=<\/span> <span class=\"n\">validator<\/span><span class=\"p\">.<\/span><span class=\"nf\">run_validation<\/span><span class=\"p\">()<\/span>\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">=== Validation Report ===<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"sh\">\"<\/span> <span class=\"o\">+<\/span> <span class=\"n\">report_df<\/span><span class=\"p\">.<\/span><span class=\"nf\">to_string<\/span><span class=\"p\">())<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">src_cursor<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">close<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">src_cursor<\/span><span class=\"p\">.<\/span><span class=\"nf\">close<\/span><span class=\"p\">()<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nf\">hasattr<\/span><span class=\"p\">(<\/span><span class=\"n\">tgt_cursor<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">close<\/span><span class=\"sh\">\"<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">tgt_cursor<\/span><span class=\"p\">.<\/span><span class=\"nf\">close<\/span><span class=\"p\">()<\/span>\n\n<span class=\"k\">if<\/span> <span class=\"n\">__name__<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">__main__<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n    <span class=\"nf\">main<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<hr\/>\n<h3><span class=\"ez-toc-section\" id=\"%D8%AA%D9%88%D8%B6%DB%8C%D8%AD_%D9%86%D9%87%D8%A7%DB%8C%DB%8C\"><\/span>\n<p>  \u062a\u0648\u0636\u06cc\u062d \u0646\u0647\u0627\u06cc\u06cc<br \/>\n<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li>\n<strong>\u0648\u0631\u0648\u062f\u06cc \u0648 \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc:<\/strong><br \/>\n\u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc CSV \u0627\u06a9\u0646\u0648\u0646 \u0627\u0646\u062a\u0638\u0627\u0631 \u06cc\u06a9 \u0646\u0627\u0645 \u0634\u06cc\u0621 \u06a9\u0627\u0645\u0644\u0627\u064b \u0648\u0627\u062c\u062f \u0634\u0631\u0627\u06cc\u0637 (\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644 \"DB.Schema.Object_Name\") \u062f\u0631 Source_name\/Target_name \u0627\u0633\u062a \u060c \u0645\u06af\u0631 \u0627\u06cc\u0646\u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0628\u062e\u0648\u0627\u0647\u062f \u06cc\u06a9 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0633\u0641\u0627\u0631\u0634\u06cc \u06cc\u0627 \u0645\u0633\u06cc\u0631 \u067e\u0631\u0648\u0646\u062f\u0647 SQL \u0631\u0627 \u062a\u0647\u06cc\u0647 \u06a9\u0646\u062f.\n<\/li>\n<li>\n<strong>\u062f\u0633\u062a \u0632\u062f\u0646 \u0628\u0647 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0633\u0641\u0627\u0631\u0634\u06cc:<\/strong><br \/>\n\u0627\u06af\u0631 \u06cc\u06a9 \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0633\u0641\u0627\u0631\u0634\u06cc (\u06cc\u0639\u0646\u06cc \u06cc\u06a9\u06cc \u0627\u0632 \"\u0627\u0646\u062a\u062e\u0627\u0628\" \u06cc\u0627 \u067e\u0627\u06cc\u0627\u0646 \u062f\u0627\u062f\u0646 \u0628\u0647 \".sql\") \u062f\u0631 \u0647\u0631 \u062f\u0648 source_name \u06cc\u0627 target_name \u062a\u0634\u062e\u06cc\u0635 \u062f\u0627\u062f\u0647 \u0634\u0648\u062f \u060c \u06a9\u062f \u06cc\u06a9 \u062c\u062f\u0648\u0644\/\u0646\u0645\u0627\u06cc \u0645\u0648\u0642\u062a (\u0627\u0632 \u0637\u0631\u06cc\u0642 _prepare_temp_object) \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0627\u0632 \u0622\u0646 \u0646\u0627\u0645 \u0634\u06cc\u0621 \u0645\u0648\u0642\u062a \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \"from_name\" \u062f\u0631 \u067e\u0631\u0633 \u0648 \u062c\u0648\u0647\u0627\u06cc \u067e\u06cc\u0634 \u0641\u0631\u0636 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f.\n<\/li>\n<li>\n<strong>\u0646\u0633\u0644 \u0648 \u0645\u0642\u0627\u06cc\u0633\u0647 \u06a9\u0644:<\/strong><br \/>\n\u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u06a9\u0644 \u0628\u0627 \u062c\u0627\u06cc\u06af\u0632\u06cc\u0646\u06cc \u0645\u062a\u063a\u06cc\u0631\u0647\u0627\u06cc \u0645\u062a\u062f\u0627\u0648\u0644 - \u0628\u0647 \u0648\u06cc\u0698\u0647 {\u0627\u0632_ \u0646\u0627\u0645} - \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0646\u0627\u0645 \u06a9\u0627\u0645\u0644\u0627\u064b \u0648\u0627\u062c\u062f \u0634\u0631\u0627\u06cc\u0637 \u06cc\u0627 \u0646\u0627\u0645 \u0634\u06cc\u0621 \u0645\u0648\u0642\u062a \u0633\u0627\u062e\u062a\u0647 \u0645\u06cc \u0634\u0648\u062f. \u0646\u062a\u0627\u06cc\u062c \u0639\u0627\u062f\u06cc \u0645\u06cc \u0634\u0648\u0646\u062f (\u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 _to_dict \u0648 _normalize_aggregate) \u0628\u0647 \u0637\u0648\u0631\u06cc \u06a9\u0647 \u0645\u0642\u0627\u062f\u06cc\u0631 \u0639\u062f\u062f\u06cc \u060c datetime \u0648 \u0631\u0634\u062a\u0647 \u062d\u062a\u06cc \u0627\u06af\u0631 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 Tuples \u06cc\u0627 DICT \u0628\u0631\u06af\u0631\u062f\u0627\u0646\u062f\u0647 \u0634\u0648\u0646\u062f \u060c \u0628\u0647 \u0637\u0648\u0631 \u0645\u0633\u0627\u0648\u06cc \u0645\u0642\u0627\u06cc\u0633\u0647 \u0645\u06cc \u0634\u0648\u0646\u062f.\n<\/li>\n<li>\n<strong>\u062c\u0631\u06cc\u0627\u0646 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc:<\/strong><br \/>\n\u0633\u06cc\u0633\u062a\u0645 \u0627\u0628\u062a\u062f\u0627 \u0631\u062f\u06cc\u0641 \u0647\u0627\u06cc \u06a9\u0644 \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc \u06a9\u0646\u062f \u060c \u0633\u067e\u0633 \u06a9\u067e\u06cc \u0647\u0627 \u0648 \u062a\u0647\u06cc \u0647\u0627 \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc \u06a9\u0646\u062f \u060c \u0633\u067e\u0633 \u0627\u0628\u0631\u062f\u0627\u062f\u0647 \u0631\u0627 \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0645\u06cc \u06a9\u0646\u062f \u060c \u0648 \u062f\u0631 \u0622\u062e\u0631 \u062a\u06a9\u0631\u0627\u0631 \u0633\u062a\u0648\u0646 - \u062a\u0648\u0633\u0637 \u06a9\u0644\u0648\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u0647\u0627\u06cc \u06a9\u0644 \u0631\u0627 \u0627\u062c\u0631\u0627 \u0645\u06cc \u06a9\u0646\u062f.\n<\/li>\n<li>\n<strong>\u0627\u0633\u062a\u062d\u06a9\u0627\u0645:<\/strong><br \/>\n\u062a\u0645\u0627\u0645 \u0645\u0631\u0627\u062d\u0644 \u062f\u0631 \u0622\u0632\u0645\u0627\u06cc\u0634\/\u0628\u0647 \u062c\u0632 \u0628\u0644\u0648\u06a9 \u0647\u0627\u06cc\u06cc \u0628\u0627 \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u062f\u0642\u06cc\u0642 \u067e\u06cc\u0686\u06cc\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a.<\/li>\n<\/ul>\n<p>\u0627\u06cc\u0646 \u06a9\u062f (\u0647\u0645\u0631\u0627\u0647 \u0628\u0627 \u0642\u0633\u0645\u062a 1) \u06cc\u06a9 \u0631\u0627\u0647 \u062d\u0644 \u06a9\u0627\u0645\u0644 \u0648 \u0622\u0645\u0627\u062f\u0647 \u062a\u0648\u0644\u06cc\u062f \u0627\u0633\u062a \u06a9\u0647 \u0646\u06cc\u0627\u0632\u0647\u0627\u06cc \u0634\u0645\u0627 \u0631\u0627 \u0628\u0631\u0622\u0648\u0631\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f. \u0642\u0628\u0644 \u0627\u0632 \u0627\u0633\u062a\u0642\u0631\u0627\u0631 \u062f\u0631 \u0645\u062d\u06cc\u0637 \u062e\u0648\u062f \u060c \u0645\u0646\u0637\u0642 \u0622\u062f\u0645\u06a9 \u0648 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0631\u0627 \u062a\u0646\u0638\u06cc\u0645 \u06a9\u0646\u06cc\u062f.<\/p>\n<div id=\"global-signup-modal\" class=\"authentication-modal hidden\">\n<div class=\"authentication-modal__container\">\n<figure class=\"authentication-modal__image-container\">\n      <img decoding=\"async\" class=\"authentication-modal__image\" src=\"https:\/\/media2.dev.to\/dynamic\/image\/width=190,height=,fit=scale-down,gravity=auto,format=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png\" alt=\"\u062c\u0627\u0645\u0639\u0647 \u0645\u062c\u0644\u0644\" loading=\"lazy\" title=\"\"><br \/>\n    <\/figure>\n<div class=\"authentication-modal__content\">\n<p class=\"authentication-modal__description\">\n<p>          \u0645\u0627 \u0645\u06a9\u0627\u0646\u06cc \u0647\u0633\u062a\u06cc\u0645 \u06a9\u0647 \u0631\u0645\u0632\u06af\u0630\u0627\u0631\u0647\u0627 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0645\u06cc \u06af\u0630\u0627\u0631\u0646\u062f \u060c \u0628\u0647 \u0631\u0648\u0632 \u0645\u06cc \u0634\u0648\u0646\u062f \u0648 \u0634\u063a\u0644 \u062e\u0648\u062f \u0631\u0627 \u0631\u0634\u062f \u0645\u06cc \u062f\u0647\u0646\u062f.\n      <\/p>\n<\/p><\/div>\n<\/p><\/div>\n<\/div>\n<p>  <\/custom><\/table>\n<p><\/span><\/code><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u062f\u0631 \u0632\u06cc\u0631 \u06cc\u06a9 \u0631\u0627\u0647 \u062d\u0644 \u062f\u0648 \u0642\u0633\u0645\u062a \u0648 \u06a9\u0627\u0645\u0644 \u0628\u0647 \u067e\u0627\u06cc\u0627\u0646 \u0631\u0633\u06cc\u062f\u0647 \u0627\u0633\u062a \u06a9\u0647 \u0646\u06cc\u0627\u0632\u0647\u0627\u06cc \u0634\u0645\u0627 \u0631\u0627 \u0628\u0631\u0622\u0648\u0631\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f. \u0627\u06cc\u0646 \u0637\u0631\u062d \u0645\u0648\u0627\u0631\u062f \u0632\u06cc\u0631 \u0631\u0627 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u062f\u0647\u062f: \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc \u0627\u0632 \u0642\u0627\u0644\u0628 CSV \u0648 \u062a\u0634\u062e\u06cc\u0635 \u0646\u0648\u0639 \u0648\u0631\u0648\u062f\u06cc &#8211; \u0641\u0631\u0636 \u0628\u0631 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 CSV \u0646\u0642\u0634\u0647 \u0628\u0631\u062f\u0627\u0631\u06cc \u0627\u0632 \u0627\u06cc\u0646 \u0633\u062a\u0648\u0646 \u0647\u0627 \u0627\u0633\u062a: mapping_id \u060c source_name \u060c &hellip;<\/p>\n","protected":false},"author":2,"featured_media":110628,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/media2.dev.to\/dynamic\/image\/width=1000,height=500,fit=cover,gravity=auto,format=auto\/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh90i2f92eqz9o75tda0o.png","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-110627","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/110627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=110627"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/110627\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media\/110628"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=110627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=110627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=110627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}