Tableau Migration SDK 5.1.1
  • 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
  • Transformers
    • Add tags to content
    • Encrypt Extracts
    • Adjust 'Start At' to Scheduled Tasks
    • Change default users for Custom Views
    • Action URL XML Transformer
  • 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: Change Projects

In this example, source data sources and workbooks in a project named Test are migrated to the destination's Production project.

Both the C# and Python mapping classes inherit from a base class that handles most of the work, and then create an IWorkbook and IDataSource version.

  • Python
  • C#

Mapping Class

from typing import TypeVar
from tableau_migration import(
    IWorkbook,
    IDataSource,
    ContentMappingContext,
    ContentMappingBase)

T = TypeVar("T")

class ChangeProjectMapping(ContentMappingBase[T]):
        
    def map(self, ctx: ContentMappingContext[T]) -> ContentMappingContext[T]:
        # Get the container (project) location for the content item.
        container_location = ctx.content_item.location.parent()

        # We only want to map content items whose project name is "Test".
        if not container_location.name.casefold() == "Test".casefold():
            return ctx
        
        # Build the new project location.
        new_container_location = container_location.rename("Production")
        
        # Build the new content item location.
        new_location = new_container_location.append(ctx.content_item.name)

        # Map the new content item location.
        ctx = ctx.map_to(new_location)
        
        return ctx


# Create the workbook version of the templated ChangeProjectMapping class
class ChangeProjectMappingForWorkbooks(ChangeProjectMapping[IWorkbook]):
    pass  

# Create the datasource version of the templated ChangeProjectMapping class
class ChangeProjectMappingForDataSources(ChangeProjectMapping[IDataSource]):
    pass

Registration

plan_builder.mappings.add(ChangeProjectMappingForWorkbooks)
plan_builder.mappings.add(ChangeProjectMappingForDataSources)

See hook registration for more details.

Mapping Class

public class ChangeProjectMapping<T> : ContentMappingBase<T>
    where T : IContentReference, IMappableContainerContent
{
    private static readonly StringComparer StringComparer = StringComparer.OrdinalIgnoreCase;

    private readonly ILogger<IContentMapping<T>>? _logger;

    public ChangeProjectMapping(ISharedResourcesLocalizer? localizer, ILogger<IContentMapping<T>>? logger) : base(localizer, logger)
    {
        _logger = logger;
    }

    public override Task<ContentMappingContext<T>?> MapAsync(ContentMappingContext<T> ctx, CancellationToken cancel)
    {
        // Get the container (project) location for the content item.
        var containerLocation = ctx.ContentItem.Location.Parent();

        // We only want to map content items whose project name is "Test".
        if (!StringComparer.Equals("Test", containerLocation.Name))
        {
            return ctx.ToTask();
        }

        // Build the new project location.
        var newContainerLocation = containerLocation.Rename("Production");

        // Build the new content item location.
        var newLocation = newContainerLocation.Append(ctx.ContentItem.Location.Name);

        // Map the new content item location.
        ctx = ctx.MapTo(newLocation);

        _logger?.LogInformation(
            "{ContentType} mapped from {OldLocation} to {NewLocation}.",
            typeof(T).Name,
            ctx.ContentItem.Location,
            ctx.MappedLocation);

        return ctx.ToTask();
    }

    public async Task<ContentMappingContext<IDataSource>?> MapAsync(ContentMappingContext<IDataSource> ctx, CancellationToken cancel)
        => await MapAsync(ctx, cancel);

    public async Task<ContentMappingContext<IWorkbook>?> MapAsync(ContentMappingContext<IWorkbook> ctx, CancellationToken cancel)
        => await MapAsync(ctx, cancel);
}

Registration

Learn more.

_planBuilder.Mappings.Add<ChangeProjectMapping<IDataSource>, IDataSource>();
_planBuilder.Mappings.Add<ChangeProjectMapping<IWorkbook>, IWorkbook>();

Dependency Injection

Learn more.

services.AddScoped<ChangeProjectMapping<IWorkbook>>();
services.AddScoped<ChangeProjectMapping<IDataSource>>();
  • Edit this page
In this article