Tableau Migration SDK 6.1.0
  • Articles
  • Code Samples
  • Python API Reference
  • C# API Reference
Show / Hide Table of Contents
  • Filters
    • Filter projects by name
    • Filter users by SiteRole
    • Filter Custom Views by 'Shared' flag
  • Mappings
    • Username email
    • Rename projects
    • Change projects
  • Pulled Hooks
    • Filter Data Source Connections
  • Transformers
    • Add tags to content
    • Encrypt Extracts
    • Adjust 'Start At' to Scheduled Tasks
    • Change default users for Custom Views
    • Action URL XML Transformer
    • Modify Permissions
  • Post-Publish Hooks
    • Update permissions
  • Bulk Post-Publish Hooks
    • Bulk logging
  • Batch Migration Completed Hooks
    • Batch migration logging
  • Migration Action Completed Hooks
    • Migration action logging

Sample: Flow Connection Server URL JSON Transformer

This sample demonstrates how to read and write JSON to update server and serverUrl in the flow JSON file before publishing. JSON transformers for flows should use the JsonContentTransformerBase<IPublishableFlow> base class, which handles opening the flow file, parsing the JSON, and persisting the modified JSON back to the file.

JSON transformers require additional resource overhead to execute, so care should be taken when developing them.

  • Due to encryption, JSON transformers require the file to be loaded into memory to modify. For large flow files, this can require significant memory.
  • Implementing the NeedsJsonTransforming/needs_json_transforming method can reduce overhead by letting the transformer skip loading flow files that do not require changes.

JSON transformers are provided with "raw" JSON and no file format validation is performed by the SDK. Care should be taken when modifying flow files that the changes do not result in content that is valid JSON but invalid by the file format. File format errors can lead to migration errors during publishing, and can also cause errors that are only apparent after the migration is complete and reported success.

  • Python
  • C#

Transformer Class

To update flow connection server values in Python, you can use the following transformer class:

from tableau_migration import (
    IPublishableFlow,
    JsonContentTransformerBase
)


class FlowConnectionServerJsonTransformer(JsonContentTransformerBase[IPublishableFlow]):

    def needs_json_transforming(self, ctx: IPublishableFlow) -> bool:
        # Returning false prevents the transform method from running.
        # Implementing this method potentially allows flows to migrate
        # without loading the file into memory, improving migration speed.
        return len(ctx.connections) > 0

    def transform(self, ctx: IPublishableFlow, json_obj: dict) -> None:
        # Changes to the JSON are saved back to the flow file before publishing.
        for _, connection in json_obj.get("connections", {}).items():
            attrs = connection.get("connectionAttributes", {})
            if attrs.get("server") == "https://old-server":
                attrs["server"] = "https://new-server"

Registration

plan_builder.transformers.add(FlowConnectionServerJsonTransformer)

See hook registration for more details.

Transformer Class

To update placeholder server values in flow connection attributes and flow nodes in C#, you can use the following transformer class:


/// <summary>
/// Sample JSON transformer that updates placeholder server and serverUrl in prep flow connection attributes and nodes. These may differ depending on your Tableau Server configuration
/// and require custom tranformation, such as private network and self-hosted server configurations.
/// Demonstrates using <see cref="JsonContentTransformerBase{TPublish}"/> for flows with performance guidance.
/// </summary>
public class FlowConnectionServerJsonTransformer : JsonContentTransformerBase<IPublishableFlow>
{
    private const string PlaceholderServerUrl = "https://source-server";
    private const string DestinationServerUrl = "https://destination-server";

    protected override bool NeedsJsonTransforming(IPublishableFlow ctx)
    {
        /*
         * Returning false prevents TransformAsync from running and avoids loading the flow file.
         * Only transform flows that have connections; flows with no connections have nothing to update.
         */
        return ctx.Connections.Count > 0;
    }

    public override Task TransformAsync(IPublishableFlow ctx, JsonNode json, CancellationToken cancel)
    {
        // Changes to the JSON are saved back to the flow file before publishing.

        // Update server and serverUrl in nodes (e.g. output nodes have serverUrl; nodes may have connectionAttributes.server).
        if (json["nodes"] is JsonObject nodesObject)
        {
            foreach (var nodePair in nodesObject)
            {
                if (nodePair.Value is not JsonObject nodeObj)
                    continue;

                if (nodeObj["serverUrl"]?.GetValue<string>() == PlaceholderServerUrl)
                    nodeObj["serverUrl"] = DestinationServerUrl;

                if (nodeObj["connectionAttributes"] is JsonObject nodeAttrs)
                {
                    if (nodeAttrs["server"]?.GetValue<string>() == PlaceholderServerUrl)
                        nodeAttrs["server"] = DestinationServerUrl;
                }
            }
        }

        // Update connectionAttributes in top-level connections (server).
        if (json["connections"] is not JsonObject connectionsObject)
            return Task.CompletedTask;

        foreach (var connectionPair in connectionsObject)
        {
            if (connectionPair.Value is not JsonObject connectionObj ||
                connectionObj["connectionAttributes"] is not JsonObject attrs)
                continue;

            if (attrs["server"]?.GetValue<string>() == PlaceholderServerUrl)
                attrs["server"] = DestinationServerUrl;
        }

        return Task.CompletedTask;
    }
}

Registration

To register the transformer in C#, follow the guidance provided in the documentation.

_planBuilder.Transformers.Add<FlowConnectionServerJsonTransformer, IPublishableFlow>();

Dependency Injection

Learn more about dependency injection here.

services.AddScoped<FlowConnectionServerJsonTransformer>();
  • Edit this page
In this article