3

I'm trying to import and export data between scratch orgs using force:data:tree:export, and I'm having trouble finding documentation that explains how to handle lookup relationships.

Lets's say that I have a "source" org and a "destination" org. My source org has two records: A and B. They are both of different types. Object A has a lookup field that is referencing object B. My goal is to export both A and B, and import them into my destination org with their lookup relationship intact. How do I make this happen? What should the SOQL query look like?

5

the data export feature is a little tricky with lookup relationships unless you do nested SOQL queries in the command. For example:

sfdx force:data:tree:export -q "SELECT Id, Name, (SELECT Name, Address__c FROM Properties__r) FROM Broker__c"

This will fill the lookup in for you. When creating sample data for our development team I had to do a lot of the lookup linking manually. This can be done by doing the following.

First you will need a plan.json. Here is a simple example:

[
    {
        "sobject": "Account",
        "saveRefs": true,
        "resolveRefs": true,
        "files": [
            "Accounts.json"
        ]
    },
    {
        "sobject": "Contact",
        "saveRefs": true,
        "resolveRefs": true,
        "files": [
            "Contacts.json"
        ]
    }
]

The important bit of this example is saveRefs and resolveRefs. What these will do is allow you to access the references that will be set in the following json files.

Since an Account is needed before a Contact we will set that file to import first so that the references are generated. Here is an example of the file:

Accounts.json

{
    "records": [
        {
            "attributes": {
                "type": "Account",
                "referenceId": "AccountRef1"
            },
            "Name": "Test Account",
            "Website": "www.website.com",
            "Phone": "Main Phone",
            "Fax": "Main Fax"
        }
    ]
}

The important piece in this file is "referenceId": "AccountRef1". This is how we will reference this Account in other json files. Now here is the Contact file using the reference that we specified above.

Contacts.json

{
    "records": [
        {
            "attributes": {
                "type": "Contact",
                "referenceId": "ContactRef1"
            },
            "FirstName": "Test",
            "LastName": "Contact",
            "AccountId": "@AccountRef1",
            "Phone": "Contact Phone"
        }
    ]
}

As you can see we use the reference id in the AccountId field. To reference the Id you should use a @ before the actual Id. Now when we run the plan by using the command sfdx force:data:tree:import --plan plan.json (which will change depending on where you keep these json files) it will load the Accounts first as well as save the references to be used later because you specified using "saveRefs": true, in the plan.json. Then when it imports the Contacts it will resolve the reference to use because of "resolveRefs": true,.

I hope this clears things up a little. I used https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_force_data.htm for reference. Let me know if you want me to expand further.

  • Thank you so much! However I am running into an issue. The account gets created successfully, but I get an error saying "id value of incorrect type: @AccountRef1". Is there an issue with the syntax in your example? – Ian Horner Feb 12 at 22:12
  • Are you using exactly what I provided or is this in your own implementation? – Zack Walton Feb 12 at 22:16
  • I tried your code just now, and it worked. So there must be something wrong with my implementation. The only difference from what I can tell is that in my implementation, the reference ID is for a custom object. Would that make a difference? If not I'll just have to keep digging to see if I made a dumb mistake or something. – Ian Horner Feb 12 at 22:27
  • @IanHorner My data plan loads custom objects as well. I figured I would use standard objects for an example as they are easier to relate to. Feel free to edit your initial post with you plan.json and the relevant json files and maybe I can see what is happening. Or maybe ask a new question. Not sure which would be the best way – Zack Walton Feb 12 at 22:31

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.