· By HeyData team

The Qlik Sense developer checklist: script, model, naming, security

This checklist takes a QlikView development checklist used by our consultants, itself shaped by best practices shared by the Qlik community, and updates it for Qlik Sense.

A model without synthetic keys, a script a colleague can pick up without calling you, an app that stays responsive over millions of rows: none of this happens by chance. It comes down to a handful of checks, always the same ones, that we run through before every delivery. Here is the list, adapted to Qlik Sense, both Client-Managed and SaaS.

Why a checklist

The original document carried an instruction in its header: “print and laminate”. The most expensive defects in production are rarely a matter of expertise: they are oversights. A synthetic key nobody noticed, a technical field kept “just in case”, a Section Access in lowercase. A short list, ticked at every delivery, catches them before the user does.

Grid of six cards summarizing the checklist: Script (info section first, one section per subject, commented and dated blocks, lib:// connections), Data model (no synthetic keys, no circular references, AutoNumber keys, optimized QVD reads), Naming (variables v, keys %, flags _, business names), Security (script in an include, values in Upper(), service account as ADMIN), Interface (few Count distinct, few nested Ifs, sparing use of Aggr, calculation conditions) and Delivery (custom theme, muted colors, same version in development and production, multi-device testing)

The checklist at a glance, by family of checks.

Script: code someone else can take over

  • The first section of the script is an information section: purpose of the app, sources, change history.
  • Each subject area (sales, customers, calendar…) has its own section in the data load editor; sections play the role of QlikView tabs.
  • Every code block starts with a comment, and every change is dated.
  • All sources go through data connections (lib://…). They replace the UNC paths and the ODBC strings that QlikView developers isolated in include files or in the hidden script, which does not exist in Qlik Sense.
  • The reload log is available and read: it is the counterpart of QlikView’s “Generate Logfile” option.
  • Flags are numeric (1/0) wherever possible.

Data model

  • No synthetic keys and no circular references (QlikView’s “loops”): the data model viewer flags them.
  • Granularity is right: the grain of each table matches the expected analyses.
  • QVDs are used wherever possible, and they are read in optimized mode.
  • Tables join on integers; large concatenated keys are replaced with AutoNumber().
  • System keys and technical timestamps are removed from the model; a useful timestamp is split into date and time.
  • Unused fields are removed.
  • Concatenated dimension fields are broken into distinct fields.
  • Unneeded snowflaked tables are consolidated; very large models do without link tables.
// Optimized QVD read: no transformation here
Orders_tmp:
LOAD * FROM [lib://Sales_QVD/Orders.qvd] (qvd);

Orders:
LOAD
    AutoNumber(Company & '_' & OrderNbr, 'Order')  as %OrderKey,
    CustNo                                         as "Customer Nbr",
    Date(Floor(OrderTimestamp))                    as "Order Date",
    Time(Frac(OrderTimestamp))                     as "Order Time",
    If(InYearToDate(OrderTimestamp, Today(), 0), 1, 0) as _YTDFlag,
    Amount
RESIDENT Orders_tmp;

DROP TABLE Orders_tmp;

Naming

The original conventions apply as they are: a prefix is enough to tell what you are dealing with.

Naming conventions table: prefix v for variables (vCurrentYear), % for key fields (%CustomerKey), _ for flag fields (_YTDFlag), < for a cyclic dimension (<ProductCycle), > for a drill-down dimension (>GeoDrillDown), suffix tmp for temporary tables and fields (Daily_Trans_tmp), the _ character as composite key separator (Company & '' & Nbr as Key); at the bottom, business names: Customer Nbr rather than CustNo, renamed in the script

The checklist prefixes, unchanged since QlikView.

  • Conventions cover tables, fields and variables.
  • Variables prefixed with v, key fields with %, flags with _, temporary tables and fields suffixed with _tmp.
  • The parts of a composite key are separated by _.
  • The < (cycle group) and > (drill-down group) prefixes apply, in Qlik Sense, to the names of cyclic and drill-down master dimensions.
  • Fields carry business names: Customer Nbr rather than CustNo.
  • Renaming happens in the script, not in each chart.

Security: Section Access

  • The security script lives in an include file, called with $(Must_Include=…), which makes the reload fail if the file is missing.
  • Upper() is applied to Section Access fields and to the reduction values on the data side: Qlik Sense compares in uppercase.
  • The reload service account is listed as ADMIN: in Client-Managed, INTERNAL\SA_SCHEDULER replaces the Publisher service account.
// section_access.qvs, called from the main script with:
// $(Must_Include=lib://Security/section_access.qvs);
Section Access;
Access:
LOAD * INLINE [
ACCESS, USERID, REGION
ADMIN, INTERNAL\SA_SCHEDULER, *
];
Concatenate (Access)
LOAD
    'USER'         as ACCESS,
    Upper(UserId)  as USERID,
    Upper(Region)  as REGION
FROM [lib://Security/users.qvd] (qvd);
Section Application;

On the data side, the reduction field is loaded the same way: Upper(Region) as REGION.

Interface performance

  • Few Count(distinct …), few nested Ifs, few string comparisons.
  • Set analysis kept in check on large fact tables; Aggr() avoided when possible.
  • No If in calculated dimensions.
  • No time functions such as InMonth() in expressions: a flag computed in the script does the same job.
  • Few visualizations per sheet, and few pivot tables in very large apps.
  • A calculation condition on large charts.
  • Common expressions are centralized: in Qlik Sense, master measures and dimensions often take over from expression variables.

Design and delivery

  • Color is used for contrast and focus; everything else is neutral and muted.
  • A custom theme carries the brand, and formatting is consistent across sheets and objects.
  • The most used selections sit at the top, the least used at the bottom.
  • The display suits users’ screen resolutions and is tested on their devices (browsers, mobile).
  • In Client-Managed, the development version matches production. In SaaS, the question does not arise.

Tuning an existing app

The original checklist ended with a tuning method that still holds:

  1. Reduce rows: keep only the history depth that is really needed.
  2. Reduce columns: find unused fields, then remove them with DROP FIELD statements in the very last section of the script. QlikView’s DocumentAnalyzer has a community counterpart, Qlik Sense Document Analyzer; in Qlik Cloud, the App Analyzer monitoring app provides comparable information.
  3. Reduce distinct values: timestamps and system keys first. The data model viewer shows that count for each field.
  4. Convert to numeric the fields compared in expressions, such as If(ClientType = 'Direct', …).
  5. Simplify the model: consolidate snowflakes towards a star schema.
  6. Simplify the app: fewer sheets, fewer objects per sheet.
  7. Run the full checklist again.

What no longer applies

Qlik Sense has no macros, no hidden script and no QlikView-style “Show Frequency” option on list boxes. QlikView Optimizer gives way to the tools mentioned above. Table columns can be filtered natively, which makes the drop-down instruction moot. Publisher is gone, and its abbreviations (APR, JOB, SDF, TSK, DSR) with it: reloads are QMC tasks in Client-Managed and scheduled reloads in SaaS. Only the DEV, TST and PRD environment prefixes remain useful, carried over to the names of streams, spaces and tasks.

Key takeaways

  • A clean model first. No synthetic keys, no loops, no unused fields: everything else depends on it.
  • A script that reads well. Information section, one section per subject, dated comments.
  • Names that speak. v, %, _ prefixes, _tmp suffix, business names set in the script.
  • Security in a single file. Mandatory include, Upper() everywhere, service account as ADMIN.
  • Performance is prepared in the script. Numeric flags, integer keys, fewer distinct values.

Source

QV Developer Checklist, QlikView development checklist (2017), internal document inspired by Qlik community practices; Qlik Sense update: HeyData.