Creating parent relationships with the Partner API

When using the insert option with the APEX Data Loader there are no prompts to allow you to pick external IDs for any parent relationships.  Let’s say you were trying to upload contacts and you want to specify which account the contact should use as its parent.  When using the insert option with the APEX data loader you do not have any way to specify the parent account unless you first retrieve the actual Salesforce id for each account that will be used as a parent for the new contacts.

However, if you use the Upsert option with the APEX Data Loader, then you will be prompted to select the external id field to use for selecting the correct parent account.  This makes sense, but the confusing part of this is that you will also be prompted to pick an external id on the Contact object.  This is really not needed in one sense because you know that you are creating new contacts and not updating them.  So in this situation you are going to have to ‘jump through the hoops’ of needing to…
1) Create a new custom field on the contact of type external id and
2) Making sure you specify a unique value for each contact.

Under the covers the APEX Data Loader is using the Partner API to communicate with Salesforce.  Here are the APEX Data Loader actions and the associated Partner API commands.
APEX Data Loader Command (Partner API Command)
Insert (Create)
Update (Update)
Upsert (Upsert)

So the Insert option with the APEX Data Loader is not allowing you to specify a parent unless you know the actual Salesforce ID.  But the underlying Create Partner API command does allow you to specify this.  So if you are building an integration with Salesforce and you know you are only doing inserts where you have to specify a parent id, then you are not limited to using the Upsert command.  You can use the Partner API Create command, but you have to wrap the parent relationship properly so that the correct parent will be selected.

Let’s look at a couple of examples.
The Create XML for the partner API when inserting a contact with a specific parent account would look like this…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<soap:header>
<sessionheader xmlns="urn:partner.soap.sforce.com">
<sessionid>
Call Login on Parent API to get Session ID
</sessionid>
</sessionheader>
</soap:header>
<soap:body>
<create xmlns="urn:partner.soap.sforce.com">
<sobjects>
<type xmlns="urn:sobject.partner.soap.sforce.com">Contact</type>
<id xsi:nil="true" xmlns="urn:sobject.partner.soap.sforce.com">
<firstname xmlns="">Joe</firstname>
<lastname xmlns="">Johnson</lastname>
<account xmlns="">
  <type>Account</type>
  <external_id_name__c>1234</external_id_name__c>
</account>
</id></sobjects></create>
</soap:body>
</soap:envelope>

Notice how the Id field is specified as being null since we are doing an insert.  Also look at the Account tag and notice that it has two parts.  It has one part, which is the type, that tells us what type of object we are dealing with.  The other part is the name of the external id field to use when picking that parent object and also the value to use.  Notice that we are using the Account field, which is the relationship field, and not the AccountID field, which holds the actual Salesforce ID.  So now we have used the Create command of the Partner API to specify an insert that will also place our new object under its correct parent. Yeah!

Here is an example using custom objects instead of standard objects like account and contact.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<soap:header>
<sessionheader xmlns="urn:partner.soap.sforce.com">
<sessionid>
Call Login on Parent API to get Session ID
</sessionid>
</sessionheader>
</soap:header>
<soap:body>
<create xmlns="urn:partner.soap.sforce.com">
<sobjects>
<type xmlns="urn:sobject.partner.soap.sforce.com">Child__c</type>
<id xsi:nil="true" xmlns="urn:sobject.partner.soap.sforce.com">
<description__c xmlns="">My Description</description__c>
<parent__r xmlns="">
  <type>Parent__c</type>
  <external_id_name__c>1234</external_id_name__c>
</parent__r>
</id></sobjects></create>
</soap:body>
</soap:envelope>

Notice that the wrapper tag for the parent object is using the relationship name of Parent__r and not the object name which would be parent__c.  In the XML we need to tell the API what field we are trying to populate, which is the Parent__r field.  We are not trying to populate the Parent__c field because we do not know the actual Salesforce id.  We also need to tell the API what type of object the parent is with the

Parent__c tags.  Finally, we need to tell the API what field to use on the parent object which is the

field with a value of 1234.

As I mentioned in a previous post a great way to see this underlying XML is to do some calls to the Partner API using a program like JAVA or .NET and then view the XML that is produced with a tool like Fiddler.

Here is a link that explains details about this same parent/child relationship topic.  Parent Relationship.  SimonF, a moderator on this topic, does a great job explaining these API subtleties.

I hope that this has given you some insight into how to use the Create and Upsert Partner API functions effectively.  The method described above saves us from having to make extra calls to retrieve actual Salesforce IDs.  Let’s leverage these external IDs to their maximum potential!

Happy Coding!

This entry was posted in Technology and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>