DEV Community

Roger Rosset
Roger Rosset

Posted on

How to Import Salesforce Custom Metadata Records using CSV/JSON

Importing Salesforce Custom Metadata Records can be really tricky. Forget about using import wizard or dataloader to do that. These tools are amazing but simply do not support operations on Custom Metadata Records.

If you perform a quick search on Google about this theme, you probably will, at certain point of your search, get into an guide that will tell you to use the Custom Metadata Loader Loader. This tool may be useful if you have just s few records to import, and none of your records has an special character on it, otherwise you certainly will fail after a lot of bugs and errors.

I've developed an class using the official Salesforce Documentation as guidelines to achieve that requirement, and I'll help you to import your Salesforce Custom Metadata Records following steps below:

1:Prepare your Data

You can use any online service that converts csv into json. I recommend the service below:
https://csvjson.com/csv2json
Alt Text

Simply upload your CSV file containing the records you want to upload, click on CONVERT and copy the generated JSON.

1.1:Make your JSON inline

What we have to do next, is to parse that JSON into a single line, you can easily do that accessing the following link:
https://jsonformatter.curiousconcept.com/

Simply paste your JSON, select COMPACT on the JSON Template Option and click PROCESS. Copy the generated compact JSON and keep that safe for later steps.

2:Create the mdtImport Apex Class using the code below

//author: Roger Rosset
//description: Upload custom metadata records using CSV/JSON

public class mdtImport  {    
    public static void insertMetadata(String metaDataTypeName, String jsonString){
        try{
            Integer count = 1;
            Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();
            JSONCsvTemplate csv = (JSONCsvTemplate)JSON.deserialize(jsonStringMdt(jsonString), JSONCsvTemplate.class);
            for(JSONCsvTemplate.mdtRecords item : csv.data.mdtRecordsList){
            //Sets the custom metadata type you'll insert your records on

            //If you're using namespaces on your org set it here
            String nameSpacePrefix ='';                                     
            Metadata.CustomMetadata rec =  new Metadata.CustomMetadata();
            String label = 'Record '+count;                      
            rec.fullName = nameSpacePrefix+metaDataTypeName+'.'+label;
            rec.label = label; 

            //Sets the custom metadata custom fields to be inserted
            /*
            * Use the template below to setup any fields you want to:
            *    
            Metadata.CustomMetadataValue fieldX = new Metadata.CustomMetadataValue();     //New instance
            fieldX.field = 'Custom_Field_Name__c';              //Custom Metadata Field you want to fill
            field1.value = item.JSON_Matching_Key_Value;        //The matching key value on the wrapper
            rec.values.add(fieldX);                             //adds the value and the matching field
            *
            */

            Metadata.CustomMetadataValue field1 = new Metadata.CustomMetadataValue();
            field1.field = 'SubGroup__c';
            field1.value = item.SubGroup;
            rec.values.add(field1);            
            Metadata.CustomMetadataValue field2 = new Metadata.CustomMetadataValue();
            field2.field = 'Description__c';
            field2.value = item.Description;
            rec.values.add(field2);                       
            Metadata.CustomMetadataValue field3 = new Metadata.CustomMetadataValue();
            field3.field = 'keyId__c';
            field3.value = item.keyId;
            rec.values.add(field3);                        
            mdContainer.addMetadata(rec);  
            count++;
    } 
            Id jobId = Metadata.Operations.enqueueDeployment(mdContainer, null);
            system.debug('Container>>'+mdContainer);
            system.debug('Id>>'+jobId);
            return;
        }

            catch(Exception ex){             
            system.debug('Error on insert');
            system.debug('Error:'+ex.getMessage());
        }

    }
    private static String jsonStringMdt(String jsonString){
        String resultJson = '{"data":{"mdtRecordsList":'+jsonString+'}}';
        return resultJson;
    }

    private class JSONCsvTemplate{
        private class Data{
            private List<mdtRecords> mdtRecordsList;
    }
        private class mdtRecords{
            private String keyId;
            private String SubGroup;
            private String Description;
        }
        private Data data;
    }
}

Enter fullscreen mode Exit fullscreen mode

As you can see you can execute the methods insertMetaData passing the metaDataTypeName and jsonString as attributes, where metaDataTypeName is the API Name of your Custom Metadata Type (ending with __mdt) and jsonString is your inline JSON that you've copied on the step 1.1, But first you have to adjust the attributes on the JSONCsvTemplate>mdtRecords to fit like your csv database.

3:Adjust the Wrapper class to your requirements

    private class JSONCsvTemplate{
        private class Data{
            private List<mdtRecords> mdtRecordsList;
    }
        private class mdtRecords{
            private String keyId;
            private String SubGroup;
            private String Description;
        }
        private Data data;
    }
}
Enter fullscreen mode Exit fullscreen mode

As you can see above, we are uploading records that has 3 columns:
-keyId
-SubGroup
-Description

These values matches exactly as my csv database headers, and you can add, delete or modify the template to meet your criteria. Keep in mind that your csv database must fit the wrapper class, not only about the field names, but also the primitive data types (Integer, String, Etc.)

Csv Database used:
Alt Text

4:Execute the method

After following all the previous steps and making sure you've created and saved the class on your Salesforce Org, all you have to do next is to execute the insertMetadata
Get your Custom Metadata Type API Name (ending with __mdt) and your JSON String generated in the step 1.1, and execute the method on the Apex Anonymous Window inside the developer console (CTRL+E)
Alt Text

Keep in mind that your JSON String may be really big, and to avoid problems, it's highly recommended you to place the method template and quotes before pasting the "super string" on the parameter inside the method execution, as below:
Alt Text
After preparing the the method, simply paste your big JSON String inside the quotes, and click execute.
Alt Text

If you have checked the Open Log option, you should be taken to the log of this execution, where you can find the ID of your enqueued deploy, and check it's status on the deployment status of Salesforce on:
SETUP > DEPLOY > DEPLOYMENT STATUS

Attention

I've already tested the deploy of 600 records per execution, try to respect that limit to avoid errors.

Feel free to modify the code as you need to, keeping the credits if possible.

Hope it be useful.

Regards,
Roger Rosset

Based documentation:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Metadata_Operations.htm

Latest comments (3)

Collapse
 
hermanmoreno profile image
Herman • Edited

The article provides a fantastic guide on importing Salesforce custom metadata records. For those seeking further enhancement in their data management workflows, integrating Skyvia's Salesforce CSV file import and export tool can be a game-changer. This tool import csv into salesforce and export process, making it easier for developers and administrators to handle bulk data operations efficiently. It's an excellent recommendation for anyone looking to streamline their Salesforce data management tasks.

Collapse
 
kritikgarg profile image
kritikgarg • Edited

👍Great tutorial on importing Salesforce custom metadata records using CSV/JSON with Apex, Roger!
I found the step-by-step instructions on how to import custom metadata records using apex code to be super helpful🤩. I especially appreciate your utilization of screenshots and code snippets, which make it easy to follow along.
🤗 I also came across the article Import data in Salesforce.It to be a fantastic guide for importing data into Salesforce without any coding,just by using built-in features and third-party apps🤞

Collapse
 
klais profile image
Klais Laren

It describes in some detail how this process works. I can add that when we implemented it for our business, we asked for help from Ukrainian developers. They have enough knowledge to teach us and configure the software, which now very much helps us to implement the workflow. Therefore, if you also need to work with Salesforce, I recommend that you hire ukrainian developers and they will help you in this work significantly. They develop and consult on Salesforce in Ukraine and the guys are really talented. I am grateful for their help, because I think that this will be a useful solution for Salesforce beginners as well. Good luck and success.