Taxonomy Import - 2 Running Import

Prev Next

Interest Manager – Importing Topic Types & Topics (Part 2: Running the Import)

Audience: Salesforce / technical admins
Prerequisite: A prepared CSV. See [Part 1 – Preparing Your Data]

Namespace: In a subscriber org, field and object API names start with T1C_Base__
(e.g. T1C_Base__Topic_Mapping__c, T1C_Base__Status__c). The Apex below already uses the
namespace. Add the prefix in SOQL and whereClause values.

There is no IM screen for this yet. Run each step from Setup → Data Import Wizard or the
Developer Console → Debug → Open Execute Anonymous Window.


Configuration (check once)

AFR feature ACE.FPM.Settings:

Attribute Default Purpose
ParentTypeName Flexible Preference Root Topic Type that every imported Topic Type sits under. Created automatically if it doesn't exist.
NonCanonicalTypeNames (blank) Comma-separated Topic Type Names whose Topics are deduped by tag path + value instead of type + name. Usually leave blank.

Step 1 (optional): Generate a draft CSV from RiXML

  1. Upload the RiXML file as a Static Resource, e.g. RIXMLSample.
  2. Run:
T1C_Base.FPMServiceFacade.ServiceRequest req = new T1C_Base.FPMServiceFacade.ServiceRequest();
req.action = 'generateMappingPreview';
req.params.put('staticResourceName', 'RIXMLSample');
T1C_Base.FPMServiceFacade.ServiceResult res = T1C_Base.FPMServiceFacade.execute(req);
System.debug('ContentVersion Id: ' + res.data.get('fileId'));
  1. Download RIXMLSample_MappingPreview.csv from Files. Every row defaults to
    Status__c = Pending. Topic_Type_Name__c defaults to the tag name with any @ removed, and
    Topic_Name__c defaults to the tag value.
  2. Hand the file to the business owner to curate (Part 1).

Step 2: Load the CSV into Topic Mapping

  1. Setup → Data Import Wizard → Launch Wizard.
  2. Custom Objects → Topic Mapping → Add new records.
  3. Upload the CSV and map each column to the field with the same name. Leave unmapped fields empty.
  4. Start Import.

For files over 50,000 rows, or for updating existing mapping rows, use Data Loader.


Step 3: Run the Topic Import

T1C_Base.FPMServiceFacade.ServiceRequest req = new T1C_Base.FPMServiceFacade.ServiceRequest();
req.action = 'runTopicImport';
// req.params.put('limitSize', 2000);   // optional, default 2000 rows per run
T1C_Base.FPMServiceFacade.ServiceResult res = T1C_Base.FPMServiceFacade.execute(req);
System.debug(res.data);   // {total, imported, skipped, failed}

Each run processes up to limitSize Pending rows. Repeat until total = 0.

What the import does:

  1. Validates Topic_Type_Name__c and Topic_Name__c.
  2. Finds or creates each Topic Type, keyed by Topic_Type_Unique_Key__c if you supplied one,
    otherwise by Topic Type Name.
  3. Finds or creates each Topic, keyed by Type::Name, or for non-canonical types by a
    SHA-256 hash of Tag_Path::Tag_Value.
  4. Links each mapping row to its Topic Type and Topic and updates its Status.
  5. Creates parent/child relationships for rows that have External_Id__c and Parent_Ids__c.

Step 4: Review results

SELECT T1C_Base__Status__c, COUNT(Id)
FROM T1C_Base__Topic_Mapping__c
GROUP BY T1C_Base__Status__c
SELECT Id, Name, T1C_Base__Topic_Type_Name__c, T1C_Base__Topic_Name__c,
       T1C_Base__External_Id__c, T1C_Base__Notes__c
FROM T1C_Base__Topic_Mapping__c
WHERE T1C_Base__Status__c IN ('Error','Skipped')
Status Meaning Action
Imported Linked to a Topic Type and a Topic, whether newly created or already existing. None
Error See Notes__c, e.g. Missing Topic_Type_Name__c or Topic_Name__c or Failed to resolve topic. Fix the row, set it back to Pending, re-run Step 3.
Skipped The parent Topic Type (ParentTypeName) could not be created. Nothing was imported. Check the AFR setting and permissions, reset the rows to Pending, re-run.
Pending Not processed yet (over limitSize). Re-run Step 3.

Notes__c on imported rows also reports relationship results: Relationships created: N,
No new relationships (already exist), or Relationship errors: Missing parent: X.


Step 5 (optional): Repair parent/child relationships

Relationships are built only when the parent row is already Imported. If a parent failed or
was loaded in a later file, fix it, import it, then run:

T1C_Base.FPMServiceFacade.ServiceRequest req = new T1C_Base.FPMServiceFacade.ServiceRequest();
req.action = 'repairRelationships';
// Optional filter, any SOQL condition on Topic_Mapping__c:
// req.params.put('whereClause', 'T1C_Base__Topic_Type_Name__c = \'Region\'');
// req.params.put('whereClause', 'T1C_Base__External_Id__c IN (\'RGN-NA\',\'CTY-US\')');
// req.params.put('whereClause', 'CreatedDate = TODAY');
T1C_Base.FPMServiceFacade.ServiceResult res = T1C_Base.FPMServiceFacade.execute(req);
System.debug(res.data);   // {totalMappings, created, alreadyExist, unresolved, errors}

This step is safe to re-run. Existing relationships are not duplicated.


Troubleshooting

Symptom Likely cause
Two Topic Types that look the same Names differ by case or spacing, e.g. Asset Class and Asset class.
Topics that should merge stayed separate Topic Names differ slightly, or the type is listed in NonCanonicalTypeNames.
Topics that should be separate merged Same Type + Name under a canonical type. Use distinct names, or add the type to NonCanonicalTypeNames and supply Tag_Path__c/Tag_Value__c.
Row loaded but never imported Status__c was blank or not Pending.
Missing parent: X in Notes No Imported mapping row has External_Id__c = X. Import it, then run Step 5.

Clean-up (optional)

Keep imported Topic Mapping rows as an audit trail, or delete them once you have verified the
Topics. Also delete the RiXML Static Resource and the preview CSV file once you no longer need them.