{"id":1410,"date":"2024-05-29T07:02:55","date_gmt":"2024-05-29T07:02:55","guid":{"rendered":"https:\/\/craftcookcode.com\/?p=1410"},"modified":"2024-05-29T22:27:51","modified_gmt":"2024-05-29T22:27:51","slug":"qlik-replicate-fight-of-the-filters-who-will-prevail","status":"publish","type":"post","link":"https:\/\/craftcookcode.com\/?p=1410","title":{"rendered":"Qlik Replicate &#8211; Fight of the filters. Who will prevail?"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Background<\/h2>\n\n\n\n<p>The business is doing their best to keep me on my toes with Qlik Replicate; finding new was to bend and stretch the system and consequently my sanity.<\/p>\n\n\n\n<p>The initial request was, \u201cCan we overwrite this field in a Qlik Replicate task with a SOURCE_LOOKUP?\u201d<\/p>\n\n\n\n<p>OK \u2013 we can do this.&nbsp; I abhor putting ETL logic in Qlik Replicate tasks and wanting to keep them as simple as possible and allow the power and the flexibility of the downstream systems to manipulate data.<\/p>\n\n\n\n<p>But project timelines were pressing, and I complied with their request.<\/p>\n\n\n\n<p>Later, they came back to me and requested a to add a filter to the derived field in question.<\/p>\n\n\n\n<p>And that led to me and our Tech Business analyst scratching our heads.&nbsp;<\/p>\n\n\n\n<p>If we apply a filter to our focus field; will it use the raw field that is in the table? Or will is use the new lookup field with the same name to base the filter on?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the filters &#8211; setting up<\/h2>\n\n\n\n<p>To start with; some simple tables in MS-SQL:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nCREATE TABLE dbo.TEST_LOOKUP\n(\n\tACCOUNT_ID INT PRIMARY KEY,\n\tFRUIT_ID INT,\n\tFRUIT_NAME VARCHAR(100),\n\tSOURCE_NAME VARCHAR(100)\n);\n\nGO\n\nCREATE TABLE dbo.FRUITS\n(\n\tFRUIT_ID INT PRIMARY KEY,\n\tNEW_FRUIT_NAME VARCHAR(100)\n)\n\nGO\n\nINSERT INTO dbo.FRUITS VALUES(1, &#039;NEW APPLES&#039;);\nINSERT INTO dbo.FRUITS VALUES(2, &#039;NEW ORANGES&#039;);\n<\/pre><\/div>\n\n\n<p>A simple Qlik Replicate task was created to replicate from the table dbo.TEST_LOOKUP.<\/p>\n\n\n\n<p>All columns were brought across instead of FRUIT_NAME. FRUIT_NAME will be overwritten with the source lookup:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nsource_lookup(&#039;NO_CACHING&#039;,&#039;dbo&#039;,&#039;FRUITS&#039;,&#039;NEW_FRUIT_NAME&#039;,&#039;FRUIT_ID =?&#039;,$FRUIT_ID)\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"541\" src=\"https:\/\/craftcookcode.com\/wp-content\/uploads\/2024\/05\/code_source_lookup-1024x541.png\" alt=\"\" class=\"wp-image-1412\" srcset=\"https:\/\/craftcookcode.com\/wp-content\/uploads\/2024\/05\/code_source_lookup-1024x541.png 1024w, https:\/\/craftcookcode.com\/wp-content\/uploads\/2024\/05\/code_source_lookup-300x159.png 300w, https:\/\/craftcookcode.com\/wp-content\/uploads\/2024\/05\/code_source_lookup-768x406.png 768w, https:\/\/craftcookcode.com\/wp-content\/uploads\/2024\/05\/code_source_lookup.png 1432w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>To test; a simple insert was added to ensure that the source lookup is working correctly:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nINSERT INTO dbo.TEST_LOOKUP VALUES(1, 1, &#039;OLD APPLES&#039;, &#039;Truck&#039;);\n<\/pre><\/div>\n\n\n<p>Result:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n    &quot;magic&quot;: &quot;atMSG&quot;,\n    &quot;type&quot;: &quot;DT&quot;,\n    &quot;headers&quot;: null,\n    &quot;messageSchemaId&quot;: null,\n    &quot;messageSchema&quot;: null,\n    &quot;message&quot;: {\n        &quot;data&quot;: {\n            &quot;ACCOUNT_ID&quot;: 1,\n            &quot;FRUIT_ID&quot;: 1,\n            &quot;SOURCE_NAME&quot;: &quot;Truck&quot;,\n            &quot;FRUIT_NAME&quot;: &quot;NEW APPLES&quot;\n        },\n        &quot;beforeData&quot;: null,\n        &quot;headers&quot;: {\n            &quot;operation&quot;: &quot;INSERT&quot;,\n            &quot;changeSequence&quot;: &quot;20240529060703760000000000000000005&quot;,\n            &quot;timestamp&quot;: &quot;2024-05-29T06:07:03.767&quot;,\n            &quot;streamPosition&quot;: &quot;0071a49f:000f8e09:001c&quot;,\n            &quot;transactionId&quot;: &quot;6EDBA1FA0E0000000000000000000000&quot;,\n            &quot;changeMask&quot;: &quot;0F&quot;,\n            &quot;columnMask&quot;: &quot;0F&quot;,\n            &quot;transactionEventCounter&quot;: 1,\n            &quot;transactionLastEvent&quot;: true\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p>Everything is working correctly; FRUIT_NAMES got overwritten with &#8220;NEW APPLES&#8221; in the json output.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the filters &#8211; placing bets <\/h2>\n\n\n\n<p>In the CDC task; a new filter was added:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\n$FRUIT_NAME == &#039;NEW ORANGES&#039;\n<\/pre><\/div>\n\n\n<p>And the following SQL statement was run on the source system:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nINSERT INTO dbo.TEST_LOOKUP VALUES(2, 2, &#039;OLD ORANGES&#039;, &#039;Fridge&#039;);\n<\/pre><\/div>\n\n\n<p>So &#8211; If Qlik Replicate filters on the base table&#8217;s field; the change <em>WILL NOT<\/em> be replicated through.<\/p>\n\n\n\n<p>Likewise if Qlik Replicate is using the new derived field for filter; the change <em>WILL <\/em>come through.<\/p>\n\n\n\n<p>And the results are&#8230;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n    &quot;magic&quot;: &quot;atMSG&quot;,\n    &quot;type&quot;: &quot;DT&quot;,\n    &quot;headers&quot;: null,\n    &quot;messageSchemaId&quot;: null,\n    &quot;messageSchema&quot;: null,\n    &quot;message&quot;: {\n        &quot;data&quot;: {\n            &quot;ACCOUNT_ID&quot;: 2,\n            &quot;FRUIT_ID&quot;: 2,\n            &quot;SOURCE_NAME&quot;: &quot;Fridge&quot;,\n            &quot;FRUIT_NAME&quot;: &quot;NEW ORANGES&quot;\n        },\n        &quot;beforeData&quot;: null,\n        &quot;headers&quot;: {\n            &quot;operation&quot;: &quot;INSERT&quot;,\n            &quot;changeSequence&quot;: &quot;20240529061434050000000000000000065&quot;,\n            &quot;timestamp&quot;: &quot;2024-05-29T06:14:34.050&quot;,\n            &quot;streamPosition&quot;: &quot;0071a49f:000f901a:0005&quot;,\n            &quot;transactionId&quot;: &quot;28DCA1FA0E0000000000000000000000&quot;,    \n            &quot;changeMask&quot;: &quot;17&quot;,\n            &quot;columnMask&quot;: &quot;17&quot;,\n            &quot;transactionEventCounter&quot;: 1,\n            &quot;transactionLastEvent&quot;: true\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p>Qlik will use the derived source lookup field over the original field in the table.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Once again this highlights the danger of putting ETL code into Qlik Replicate tasks. It obscures business rules and can lead to confusion in operations like the scenario above. <\/p>\n\n\n\n<p>It is best to use Qlik Replicate to get the data out of the source database as quickly and as pure as possible and then use the power of the downstream systems to manipulate the data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Background The business is doing their best to keep me on my toes with Qlik Replicate; finding new was to bend and stretch the system and&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":1415,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[16],"tags":[36],"class_list":["post-1410","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-qlik-replicate","tag-qlikreplicate"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/posts\/1410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1410"}],"version-history":[{"count":4,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/posts\/1410\/revisions"}],"predecessor-version":[{"id":1417,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/posts\/1410\/revisions\/1417"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=\/wp\/v2\/media\/1415"}],"wp:attachment":[{"href":"https:\/\/craftcookcode.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/craftcookcode.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}