I've used the Data Export feature to pull down ContentVersion data for Files and (Enhanced) Notes from a Salesforce org that's being migrated into a different org. I've been unable to locate the ContentDocument and ContentDocumentLink data connecting these records to their parents.

Is this data included or is it possible to include it in the data export ZIP file? If not, can I rely on a SOQL query run as a System Administrator to get back all of the linking data, even for private files?

  • ContentDocument is created automatically when you insert the ContentVersion into the target org; Hence, you will need to do the migration in steps - first ContentVersion + other Sobjects, then insert ContentDocumentLinks that you build manually in Excel using the IDs of the parents to ContentDocumentLink in the target org – cropredy Jan 13 '18 at 18:13
  • Thanks, @cropredy - I had forgotten about automatic creation of ContentDocument. ContentDocumentLink has weird query restrictions (requires a LinkedEntityId or ContentDocumentId filter). Any ideas on the best way to extract the entire table for migration and matching? – David Reed Jan 16 '18 at 15:30
  • I could imagine scripting a loop over the Ids of all the ContentDocuments in the instance and batching them for IN query filters, but that just sounds tedious. – David Reed Jan 16 '18 at 15:31
  • 1
    hmm -- a batch class that queried all ContentDocuments (start()) whose execute() did query on ContentDocumentLink and wrote results to some custom migration object? – cropredy Jan 16 '18 at 15:38
  • I like that idea. If you'd like to post an answer, I'll accept it. – David Reed Jan 16 '18 at 16:11

One thing to realize is that ContentDocument can't be directly inserted; it is inserted automatically when the first ContentVersion is inserted. ContentDocument acts as a parent for each version of the file - i.e., each child ContentVersion

So an approach would be:

  • Export all ContentVersion from the source (including the ID)
  • Insert the ContentVersion to the target org. Associate in some place (Excel), the target ContentVersion.Id to the source org's ContentVersion.Id
  • Export and insert all Sobjects (like Account, Opportunity, etc - i.e., those Sobjects that are the parents of ContentDocumentLink as LinkedEntityId. Be sure to keep track of the new (target) sobject Ids and associate them (Excel) back to the source Sobject Ids.
  • Export the ContentDocumentLink from the source org. This is tricky because you can't SOQL all of the ContentDocumentLink without a Where clause. If you don't have too many ContentDocument, you can do this in one SOQL but if you have way too many (exceed size of SOQL string), you will need to write a small batchable class to export the ContentDocumentLinks to a custom object that you can in turn export using DataLoader.
  • Manipulate the exported ContentDocumentLink from the source org (Excel) to replace the source LinkedEntityId with the ID of that Sobject in the target; do the same for the ContentDocumentId.
  • Use DataLoader to insert the ContentDocumentLink into the target

Details on the batchable:

start() - query all ContentDocument

execute() - query all ContentDocumentLink for the execute's scope argument (i.e. a list of ContentDocument. Write results to a custom migration object - ContentDocumentLink_Migration__c that has two fields: SourceLinkedEntityId__c and SourceContentDocumentLink__c

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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