App GUIDs in Qlik Sense are unique for each environment. Different environment, different GUID. Different URL for the app. That is life in Qlik Sense. This setup, while frustrating for developers, generally is a non-issue that we accept and accommodate in our design. However, this limitation can become challenging or even an obstacle in several instances:
- There is a custom app navigation bar (bypassing the Qlik Sense Hub & App Overview)
- URL links in a chart/object in one app to navigate a sheet in a different app
- ETL processes that may be centralized/optimized by having a model app & binary load into one or several Qlik Sense apps (this is a pain-point for those of us who are accustomed to QlikView development)
- Testers/Quality control department pushes back against the URL differences beyond the domain changing from Dev / Test / Prod environments
- The developer in charge of the Qlik environments (or deployment) is OCD & cannot stand having differences on the Qlik front end
The first two use cases can be bypassed without issue with conscientious design (that is why we are paid, after all). Writing a customized extension & referencing the Qlik API to populate the custom sidebar is a solution, and setting the app ID as a variable using Peek() and the app list from the Qlik Postgres database can solve the second. However, the third case (binary load) is where those innovations come to a complete stop.
What makes this case different? It has to do with the Binary command in Qlik and the restrictions around using it. The binary load must be the first executed command in the Load Script. I am not sure what the reason for that is; my theory is that the binary load executes a Copy command and replaces sections of the app running the script, and so to avoid catastrophe Qlik added restrictions around the command. The Binary load was much more useful in QlikView since a failed load in the front-end app would drop triggers and generally wreak havoc on the developed app (I do not recall what else, but there were several items and could set a developer back several hours of work). I have found binary loads useful in Qlik Sense when sharing data models between apps or needing to refresh apps with hourly data but also refreshing the historic data nightly (which could take 45+ minutes to load). Qlik Sense does not support an easy method to execute a partial reload in the QMC, and the binary load method helps keep the task management in the Qlik QMC. Binaries can also be made to QlikView models, so do not break up / duplicate the data pipeline if there is a dual environment in production.
But how is a binary load referenced? The name of apps in Qlik Sense are stored as GUIDs, so the binary must reference the GUID of the target app. Since it must be the first executed command in the load script, there is no opportunity to set a variable to the GUID of the app. There are two solutions: either change the GUID in the binary load command of the load script when moving it to the test/production environment (automation of this process would be preferred) or move apps into the new environment and assign the GUID from the previous environment as the GUID in the new one.
Another reason to move the GUID (and one most of us find ourselves in) is that there is a requirement of having the production environment match the development environment as much as possible. URL in production matching the URL in development with an exception for the domain can be a sticking point in your SDLC.
OK, let’s say one or two of those points above convinced me. Now how can I migrate the GUIDs in Qlik Sense?
I was convinced they could be because that is the whole reason the GUID was invented in the first place: to make DB mergers possible without key collision. If you have poked around enough on the Qlik Sense server, the first spot that comes to mind is the PostGres database that Qlik uses to save all of its information about various apps. After reading dozens of blogs & Qlik Help files that cautioned emphatically against tampering with the database as it is always unsupported & could hopelessly corrupt it, I moved away from pgAdmin & started studying the APIs which is the supported endpoint for manipulating the database. After many fruitless internet searches, I reached out to some very helpful Qlik representatives (Thank you, Dustin Baxa). After several iterations of troubleshooting where apps would not upload, or they would upload, but without a Script object, the import worked with the assigned GUID (see code below).
The solution uses Powershell Qlik CLI to make the API calls (note: Qlik does not support the Powershell Qlik CLI, but the API calls it uses are supported). Some of the API endpoints used can only be hit if the script is run on the central node of your Qlik cluster. I hope this helps if you find the need to change the GUIDs in your environments.