Skip to content

Connect

Commands for working with connections and deployed models. The connection model itself — sessions, profiles, workspace mode — is explained in Connections & sessions.

connect — set the active connection

tx connect [server] [database] [options]

No arguments shows the current connection and the session that holds it. For a Power BI Desktop session it shows the report name, and flags the session as (not running) — with the last-known report — once that Desktop window has been closed. The first argument can be a workspace name, an endpoint, or a local model path.

Option Description
--local Attach to a Power BI Desktop instance running on this machine (Windows only). The instance's database (a GUID) is looked up and saved automatically.
--list List without connecting or changing the active connection. With a server (tx connect <workspace> --list): the semantic models on that workspace or endpoint, with compatibility level and last update. With --local: running Desktop instances (report name, endpoint, database). Works without a TTY; use --output-format json for scripts and agents.
--remote Pick a workspace and model interactively from your tenant (requires a TTY; sign in first with tx auth login).
-p, --profile <name> Connect through a saved profile.
--clear Forget the active connection. Add --all to forget it in every session (every repository, worktree, and TOMIX_SESSION); that asks for confirmation, so pass --yes in scripts.
-w, --workspace [target] Enable workspace mode: mirror saves between the primary source and a secondary target. No value = pick interactively.
--workspace-format <fmt> How a local workspace is stored on disk (tmdl or bim); detected from the path when omitted.
--workspace-auth <auth> How to authenticate the remote side of workspace mode.
--force Allow workspace mode to initialize over a folder that already has content.
tx connect                          # show current
tx connect --remote
tx connect MyWorkspace Sales
tx connect ./model.tmdl
tx connect --local                  # Power BI Desktop (Windows only)
tx connect MyWorkspace --list       # models on a workspace, no connect
tx connect --local --list           # running Desktop instances, no connect
tx connect localhost:56164          # a specific Desktop instance from the list
tx connect ./model.tmdl -w MyWorkspace Sales
tx connect --clear --all             # forget the connection everywhere

A workspace that hosts more than one model cannot be opened without naming one: commands such as tx ls -s MyWorkspace fail with TOMIX_DATABASE_REQUIRED. List the models first, then pass one with -d:

tx connect MyWorkspace --list --output-format json
tx ls -s MyWorkspace -d Sales

With --output-format json the listing is {"server": "<endpoint>", "models": [{"name", "compatibilityLevel", "lastUpdate"}]} inside the standard envelope; compatibilityLevel and lastUpdate are null when the server does not report them.

deploy — deploy to a workspace

tx deploy [model] [options]

Runs the BPA gate before deploying. The gate blocks only on findings at or above the severity threshold: error-severity by default, or warnings too with --bpa-fail-on warning. A rule that cannot be evaluated is itself an error-severity finding — a broken rule expression blocks the deploy (named in the message) instead of silently skipping the rule. Rules that need VertiPaq statistics the model doesn't have are not checked. The deploy still proceeds, with a TOMIX_BPA_VERTIPAQ_STATS_MISSING warning that names them and says how to collect the statistics: tx vertipaq --annotate --save on a deployed model, or on a local model connected to one in workspace mode. The gate honors bpa rules disable: it skips any rule you disabled locally when that rule is among the gate's loaded rules. bpa run can load additional user and model rules, so the commands may report different findings.

Without -s/--server, the target comes from the active connection: a remote connection deploys to itself, and a local connection with a workspace-mode mirror deploys to the mirror.

Option Description
--dry-run Preview what the deploy would change on the target (+ = added to the target, - = removed from it). Compares the target against the exact model this deploy would leave behind, so anything granular deployment preserves is not reported as a change. A target that does not exist yet is reported as "will be created".
--xmla <file> Write the deployment as a TMSL script to a file instead of deploying (- for stdout).
--create-only Create the target model only if it does not exist; fail when it does.
--skip-bpa / --fix-bpa Skip the BPA gate, or apply rule fixes before deploying.
--bpa-rules <file> Additional BPA rule files for this deploy, alongside the built-in ruleset.
--bpa-fail-on <error\|warning> Severity threshold for the BPA gate: error (default) or warning. Applies before the deploy and again after --fix-bpa fixes. Rules that cannot be evaluated count as error-severity findings.
-p, --profile <name> Use a saved remote profile for this deploy only. List profiles with tx profile list; create one with tx profile set <name> -s <workspace> -d <database>.
--ci <github\|vsts> Print CI log-group commands to stderr.
--force Bypass validation checks.

The dry-run diff ignores engine-derived calculated-table column data types, including type differences when a column exists on both the processed target and the planned model. Other column property changes remain visible.

tx deploy ./model.tmdl --dry-run
tx deploy ./model.tmdl --profile prod --dry-run
tx deploy --server MyWorkspace --database Sales
tx deploy ./model.bim --xmla deploy.xmla
tx deploy ./model.tmdl --bpa-fail-on warning

Granular deployment

When the target model already exists, deploy preserves everything the target owns by default: partitions (including processed incremental-refresh data), data source connection strings, shared expressions (M parameters), roles, and role members. Only the model structure — tables, columns, measures, relationships — is overwritten. Each aspect can be opted into deployment individually:

Option Description
--deploy-connections Overwrite the target's data sources. Default keeps the target's connection strings and bound credentials.
--deploy-partitions Overwrite the target's table partitions. Default keeps the target's partitions and their processed data. Calculated tables and calculation groups are exempt: their partitions are model structure (a DAX expression), so they always deploy from the source.
--deploy-policy-partitions With --deploy-partitions: also overwrite incremental-refresh policy partitions. Default keeps them even when other partitions deploy, so processed history is never discarded by accident.
--deploy-shared-expressions Overwrite the target's shared expressions (M parameters). Default keeps the target's values; expressions new in the source always deploy.
--deploy-roles Overwrite the target's security roles. Default keeps the target's roles untouched.
--deploy-role-members With --deploy-roles: also overwrite role members. Default keeps the target's membership even when role definitions deploy.
--deploy-full Overwrite everything from the source, including incremental-refresh partitions. Cannot be combined with the other --deploy-* flags.

Preservation only applies to an existing target; the first deploy of a model always ships the full source. --xmla reads the target when any aspect is preserved so the generated script matches what a real deploy would execute — use --deploy-full to generate a script offline. Generated scripts never contain credentials: only a direct deploy carries restricted connection-string information. On targets with dataSource objects (Azure AS, SSAS — Power BI and Fabric models keep connections in M instead), this means an --xmla script is not equivalent to a direct deploy: createOrReplace replaces each data source with the credential-stripped copy in the script, so executing it disconnects those data sources until credentials are re-entered on the server. Prefer a direct deploy when data sources are in play; treat --xmla output as a preview or an audit artifact there, not a deployment vehicle.

tx deploy ./model.tmdl                                   # promote structure, keep target data and config
tx deploy ./model.tmdl --deploy-roles                    # also push RLS definitions, keep members
tx deploy ./model.tmdl --deploy-partitions               # push partitions, keep incremental-refresh data
tx deploy ./model.tmdl --deploy-full                     # overwrite everything (first-deploy semantics)

--dry-run reflects preservation

The preview reads the target once and compares it against the model this deploy would actually leave behind, merged with the same rules a real deploy uses. Aspects the flags preserve — connection strings, M parameter values, role members, incremental-refresh partitions — are therefore absent from the diff, and changing a --deploy-* flag changes what the preview reports.

With default flags or --deploy-roles alone, a members-only source edit can show "No changes" in --dry-run because an existing target's role members are preserved. A real deploy also leaves those members unchanged; use --deploy-roles --deploy-role-members (or --deploy-full) to preview and deploy member changes.

When the target database does not exist, there is nothing to compare against: the preview reports that the deploy creates it with the full source model.

--xmla still shows the raw payload rather than a diff, and remains the way to inspect the exact TMSL that would be sent:

tx deploy ./model.tmdl --xmla preview.xmla --yes

refresh — trigger a data refresh

tx refresh [options]
Option Description
--refresh-type <type> full, dataonly, automatic (default), calculate, clearvalues, defragment, add. Named --refresh-type (not --type): --type means an object kind on every other command.
--table <name> Refresh specific table(s). Repeatable.
--partition <Table.Partition> Refresh specific partition(s). Repeatable.
--apply-refresh-policy [true\|false] / --skip-refresh-policy Let an incremental refresh policy choose the partitions (default: true); --skip-refresh-policy is shorthand for --apply-refresh-policy false.
--policy-only Apply one table's deployed policy without loading data. Requires exactly one --table; may remove expired partitions.
--effective-date <yyyy-MM-dd> Evaluate refresh policies as if today were this date.
--max-parallelism <n> Maximum parallel refresh operations.
--dry-run Preview without execution: TMSL for normal refresh, a validated operation summary for --policy-only.
--no-progress Turn off live progress tracking (useful in CI and when piping).
--trace [path] Write raw XMLA trace events (stderr, or a log file).
tx refresh --refresh-type full
tx refresh --table Sales --table Customers

While it runs, a live panel shows the elapsed time, how many tables are done and in progress, and the rows loaded so far, then one line per in-progress table — oldest first, capped at six — with its current step (querying, reading, compressing, hierarchies, calculated columns), the partition for multi-partition tables, its rows, and how long it has been running. Once no table is in progress it shows the model-level step (relationships, calculation script, commit). The summary lists each table with Rows, Query (source query), Read, Process (post-load hierarchies and calculated columns), and Total, with a sub-row per partition when a table has several, followed by a phase table (data load, hierarchies, calculated columns, relationships, calculation script, commit) in wall-clock time. With --output-format json the same detail is in tables[].processMs, tables[].partitions, and phases; the CSV columns are unchanged. Power BI / Fabric delivers the trace a few seconds behind the refresh, so the summary can appear a little after the refresh itself finishes; the reported duration is the refresh's own.

Routine refreshes run without prompting. The partition-risky variants — --refresh-type clearvalues (wipes partition data), --skip-refresh-policy / --apply-refresh-policy false (refreshes all historical partitions), --policy-only, and --effective-date (shifts policy window boundaries) — ask for confirmation first; --dry-run never does. Pass --yes to skip the prompt in scripts.

Apply a saved policy with data loading, or bootstrap empty partitions:

tx refresh --table Sales --apply-refresh-policy true -s MyWorkspace -d MyModel
tx refresh --table Sales --policy-only -s MyWorkspace -d MyModel --dry-run
tx refresh --table Sales --policy-only -s MyWorkspace -d MyModel --yes

--policy-only uses the deployed policy; it does not deploy local edits. It accepts --effective-date and positive --max-parallelism. It cannot be combined with --partition, an explicit --refresh-type, --trace, or disabling policy application. Its preview verifies the target table and policy without applying it; exact partition changes are determined by the server during execution. JSON execution results include policyApplication (operations, date, and refreshed: false); previews include policyPreview. Ordinary refresh output remains unchanged.

After an empty policy-only bootstrap, a normal policy refresh loads the incremental window; historical partitions can remain empty. To backfill all existing partition ranges without moving the policy window, use:

tx refresh --table Sales --refresh-type full --skip-refresh-policy -s MyWorkspace -d MyModel --yes

save — export a model

tx save [model] [options]
Option Description
-o, --output-file <path> Where to write. Omit to save back to the source.
--serialization <tmdl\|bim> Output format (defaults to the loaded model's).
--supporting-files Write a {modelName}.SemanticModel/ folder (with .platform and definition.pbism) around the output.
--fix-bpa / --bpa-rules <file> Apply BPA rule fixes before saving, optionally with specific rule files.
--overwrite Replace an existing output file or directory.
tx save -s MyWorkspace -d Sales -o ./sales.tmdl          # download a deployed model
tx save ./model.tmdl --serialization bim -o ./model.bim  # convert formats

auth — authentication

tx auth <login|logout|status>

auth login options:

Option Description
-u, --username <id> Service-principal application (client) id.
-p, --password <source> Service-principal client secret source: pass - to read one line from stdin. Secret values on the command line are rejected.
--password-file <file> Path to a file containing the client secret (trailing newline ignored).
-t, --tenant <tenant> Tenant id or domain (required for service principal).
--certificate <file> Certificate file (PEM or PKCS12) for service-principal auth.
--certificate-password <source> / --certificate-password-file <file> Certificate password via stdin (-) or file; plain values on the command line are rejected.
-I, --identity Sign in with a managed identity (Azure-hosted; use --username for user-assigned).
--device-code Use the device-code flow instead of a local browser.
--client-id <id> Override the Azure AD client id used for interactive/device-code sign-in.
--save Keep the service principal credentials for future sign-ins (default: true). --save false uses them for this login only.
tx auth login                          # interactive browser login
tx auth login --device-code            # no local browser (SSH, containers)

# Service principal — secret from stdin (CI) or a file, never argv
printf '%s' "$SECRET" | tx auth login -u $APP_ID -t $TENANT --password -
tx auth login -u $APP_ID -t $TENANT --password-file ./secret.txt

tx auth status
tx auth logout