Loading...
Area: Optimizely B2B Commerce

Moving content between a Pilot/Sandbox to Production environment

Recommended reading 

Introduction

When a customer is working on a new site, they are generally creating and modifying their content in the pilot/sandbox environment until they are ready to go live. During that process, it is common to want to move the content from one site to another.

This data is contained within several tables: ContentItem, ContentItemField, and ContentPageState.

This document will outline the general approach to migrating this data from one place to another. There is an assumption that the database lives on separate servers.

General Approach

In general, the approach is to create a transfer database, populate it with the data to move, move the db to the new environment and merge the data. The scripts and documentation below adhere to this approach.

It is further presumed by this documentation that the user wishes to copy the content from the Sandbox (pilot) server to the Production server. We will be using the database named ContentTransfer for the transfer db and Insite.Commerce.SourceDB for the source database and Insite.Commerce.TargetDB for the targetDB. It is more likely that the source and target databases will be named the same, just reside on different servers.

Step by Step

  1. Create an empty transfer database on the Sandbox server.
  2. The scripts will resolve any differences in native IDs for the language, user, and persona but the website ID MUST MATCH EXACTLY between the two systems. If they don't once you have the data in the ContentTransfer tables, update the WebsiteId.
  3. The personas and language must exist in the target db even if they may not have the same ID values – the script will use the natural keys to find the corresponding language and persona and reassign it.
  4. Because content has users, language and persona associated with it, we will need to isolate the associated data in the content tables and insure it is available as we post it over ot the target db. Use the following:
    USE [ContentTransfer]
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ContentPageState')  DROP TABLE ContentPageState
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ContentItemField') DROP TABLE ContentItemField
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ContentItem') DROP TABLE ContentItem
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'UserProfile') DROP TABLE UserProfile
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Language') DROP TABLE Language
    IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Persona') DROP TABLE Persona
    GO
    
    USE [Insite.Commerce.SourceDB]
    SELECT * INTO ContentTransfer.dbo.ContentItem FROM ContentItem
    SELECT * INTO ContentTransfer.dbo.ContentItemField FROM ContentItemField
    SELECT * INTO ContentTransfer.dbo.ContentPageState FROM ContentPageState
    SELECT * INTO ContentTransfer.dbo.Language FROM Language
    SELECT * INTO ContentTransfer.dbo.Persona FROM Persona
    SELECT * INTO ContentTransfer.dbo.UserProfile FROM UserProfile WHERE ID IN
    (SELECT DISTINCT CreatedById FROM ContentItem WHERE CreatedById IS NOT NULL
    UNION
    SELECT DISTINCT ApprovedById FROM ContentItem WHERE ApprovedById IS NOT NULL
    UNION
    SELECT DISTINCT CreatedById FROM ContentItemField WHERE CreatedById IS NOT NULL
    UNION
    SELECT DISTINCT ApprovedById FROM ContentItemField WHERE ApprovedById IS NOT NULL)
    					
  5. The steps above effectively gather all the data required to transfer the data. Next take a backup of the ContentTransfer db and restore it in the target environment and run the following script to replace the target data with the source data.

    NOTE: This will overwrite any existing CMS content with the new data. Make sure to have a backup of the target db in case there is an issue and do this in off hours so that you can restore the db if there is a problem.

    Product content, dealer content, specifications and category content are stored in different tables and this is not going to affect that data.

    -- Script to reset any IDs in the source tables
    BEGIN TRANSACTION
    
    USE ContentTransfer
    ALTER TABLE Persona ADD  NewId uniqueidentifier NULL
    ALTER TABLE Language ADD  NewId uniqueidentifier NULL
    ALTER TABLE UserProfile ADD  NewId uniqueidentifier NULL
    GO
    
    UPDATE Persona SET NewId = (SELECT Id from [Insite.Commerce.TargetDB].dbo.Persona np WHERE np.Name = Persona.name)
    UPDATE Persona SET NewId = (SELECT Id from [Insite.Commerce.TargetDB].dbo.Persona np where np.IsDefault = 1) WHERE Persona.NewId IS NULL
    UPDATE Language SET NewId = (SELECT Id from [Insite.Commerce.TargetDB].dbo.Language nl WHERE nl.LanguageCode = Language.LanguageCode)
    UPDATE Language SET NewId = (SELECT Id from [Insite.Commerce.TargetDB].dbo.Language nl where nl.IsDefault = 1) WHERE Language.NewId IS NULL
    UPDATE UserProfile SET NewId = (SELECT Id from [Insite.Commerce.TargetDB].dbo.UserProfile nup WHERE nup.Id = UserProfile.Id)
    UPDATE UserProfile SET NewId = (SELECT Id from [Insite.Commerce.TargetDB].dbo.UserProfile nup WHERE nup.UserName = UserProfile.UserName) WHERE UserProfile.NewId IS NULL
    INSERT INTO [Insite.Commerce.TargetDB].dbo.UserProfile (Id, FirstName,LastName,Phone,UserName,IsGuest,IsDeactivated)
    (SELECT Id, FirstName,LastName,Phone,UserName,IsGuest, 1 FROM UserProfile WHERE NewId IS NULL)
    UPDATE UserProfile SET NewId = Id WHERE NewId IS NULL
    GO
    
    -- Copy IDs back into target tables
    UPDATE ContentPageState SET LanguageId = (SELECT NewId FROM Language WHERE Language.Id = ContentPageState.LanguageId)
    UPDATE ContentPageState SET PersonaId = (SELECT NewId FROM Persona WHERE Persona.Id = ContentPageState.PersonaId)
    UPDATE ContentItemField SET LanguageId = (SELECT NewId FROM Language WHERE Language.Id = ContentItemField.LanguageId)
    UPDATE ContentItemField SET PersonaId = (SELECT NewId FROM Persona WHERE Persona.Id = ContentItemField.PersonaId)
    UPDATE ContentItemField SET CreatedById = (SELECT NewId FROM UserProfile WHERE UserProfile.Id = ContentItemField.CreatedById)
    UPDATE ContentItemField SET ApprovedById = (SELECT NewId FROM UserProfile WHERE UserProfile.Id = ContentItemField.ApprovedById)
    UPDATE ContentItem SET CreatedById = (SELECT NewId FROM UserProfile WHERE UserProfile.Id = ContentItem.CreatedById)
    UPDATE ContentItem SET ApprovedById = (SELECT NewId FROM UserProfile WHERE UserProfile.Id = ContentItem.ApprovedById)
    GO
    
    -- Reform transfer files to original mode
    UPDATE Language SET Id = NewId
    UPDATE Persona SET Id = NewId
    UPDATE UserProfile SET Id = NewId
    ALTER TABLE Language DROP COLUMN NewId	
    ALTER TABLE Persona DROP COLUMN NewId
    ALTER TABLE UserProfile DROP COLUMN NewId
    GO
    
    -- Script to repopulate the data
    USE [Insite.Commerce.TargetDb]
    DELETE FROM ContentPageState
    DELETE FROM ContentItemField
    DELETE FROM ContentItem
    INSERT into ContentItem SELECT * FROM [ContentTransfer].dbo.ContentItem
    INSERT INTO ContentItemField SELECT * FROM [ContentTransfer].dbo.ContentItemField
    INSERT INTO ContentPageState SELECT * FROM [ContentTransfer].dbo.ContentPageState
    GO
    
    COMMIT TRANSACTION
    					
Do you find this information helpful? Please log in to provide feedback.

Last updated: Dec 11, 2020

Recommended reading