Whether you are planning a massive data migration, cleaning up years of technical debt, or preparing for a strict compliance audit, you need a clear map of your Salesforce architecture. Gathering this information manually is a painful and error-prone process. Thankfully, Salesforce provides multiple programmatic ways to extract your schema definitions instantly.
📌 Key Points Summary
- Creating an offline data dictionary is vital for org cleanups, third-party integrations, and governance audits.
- Dynamic Apex allows you to build a reusable utility class that emails the CSV dictionary directly to your inbox.
- The Tooling API offers the fastest modern route by allowing you to query object and field definitions directly using SOQL.
- Browser extensions like Salesforce Inspector Reloaded make exporting schema a quick, one-click process for Admins.
- Always run schema exports as a System Administrator to avoid missing fields hidden by Field-Level Security (FLS).
🛠️ Method 1: The Automated Apex Utility Class
For developers who want to generate schema reports automatically (or schedule them), you can use Dynamic Apex. The Schema namespace lets you inspect object tokens and field definitions at runtime. This script filters the objects, builds an RFC-compliant CSV string (escaping commas so your spreadsheet doesn't break), and emails it out.
SchemaDictionaryExporter.cls)
public with sharing class SchemaDictionaryExporter {
public static void generateAndEmailDictionary(String targetNamespace, String recipientEmail) {
if (String.isBlank(recipientEmail)) {
throw new IllegalArgumentException('A valid recipient email is required.');
}
List<String> csvRows = new List<String>();
// 1. Build the CSV Header
csvRows.add('Object API Name,Object Label,Field API Name,Field Label,Data Type,Is Custom');
// 2. Fetch all SObjects
Map<String, Schema.SObjectType> globalDescribe = Schema.getGlobalDescribe();
for (String objName : globalDescribe.keySet()) {
Schema.SObjectType objType = globalDescribe.get(objName);
Schema.DescribeSObjectResult objDescribe = objType.getDescribe();
// Filter: Target a specific namespace or just custom objects
Boolean matchesFilter = false;
if (String.isNotBlank(targetNamespace)) {
matchesFilter = objName.startsWithIgnoreCase(targetNamespace.toLowerCase() + '__') && objName.endsWithIgnoreCase('__c');
} else {
matchesFilter = objName.endsWithIgnoreCase('__c'); // Default: All Custom Objects
}
if (!matchesFilter) continue;
String objectApi = objDescribe.getName();
String objectLabel = escapeCsv(objDescribe.getLabel());
// 3. Inspect fields for the matched object
Map<String, Schema.SObjectField> fieldsMap = objDescribe.fields.getMap();
for (String fieldKey : fieldsMap.keySet()) {
Schema.DescribeFieldResult fieldDescribe = fieldsMap.get(fieldKey).getDescribe();
csvRows.add(String.format('{0},{1},{2},{3},{4},{5}', new List<String>{
objectApi,
objectLabel,
fieldDescribe.getName(),
escapeCsv(fieldDescribe.getLabel()),
String.valueOf(fieldDescribe.getType()),
String.valueOf(fieldDescribe.isCustom())
}));
}
}
// 4. Construct CSV File and Email
String csvContent = String.join(csvRows, '\n');
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
attachment.setFileName('Salesforce_Data_Dictionary_' + DateTime.now().format('yyyyMMdd') + '.csv');
attachment.setContentType('text/csv');
attachment.setBody(Blob.valueOf(csvContent));
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setToAddresses(new List<String>{ recipientEmail });
email.setSubject('Salesforce Schema Data Dictionary Export');
email.setPlainTextBody('Attached is your automatically generated schema report.');
email.setFileAttachments(new List<Messaging.EmailFileAttachment>{ attachment });
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{ email });
}
// Helper: Prevent commas inside labels from breaking the CSV columns
private static String escapeCsv(String value) {
if (String.isBlank(value)) return '""';
if (value.contains(',') || value.contains('"') || value.contains('\n')) {
value = value.replaceAll('"', '""');
return '"' + value + '"';
}
return value;
}
}
You can then trigger this report anytime from Anonymous Apex via the Developer Console:
// Generate a dictionary of all custom objects and email it
SchemaDictionaryExporter.generateAndEmailDictionary(null, 'admin@yourcompany.com');
⚡ Method 2: The Modern Way (SOQL & Tooling API)
If writing Apex feels like overkill, you can query Salesforce's metadata directly using the Tooling API. Open the Developer Console Query Editor, check the Use Tooling API box at the bottom, and run this simple SOQL query.
Run this to extract all fields on the Account object. You can copy the results directly into Excel.
SELECT QualifiedApiName, DeveloperName, DataType, Length
FROM FieldDefinition
WHERE EntityDefinition.QualifiedApiName = 'Account'
💻 Method 3: The Salesforce CLI (sf)
For modern developers using VS Code, the Salesforce CLI (sf) makes retrieving object metadata incredibly simple right from your terminal.
sf sobject describe --sobject Account
This command returns a detailed JSON structure of the object schema. You can easily pipe this output into a custom Node.js or Python script to parse the JSON into a beautiful CSV file for your stakeholders.
🖱️ Method 4: Free Browser Extensions (No Code)
For Admins who want a purely point-and-click experience, modern browser extensions are a lifesaver.
- Salesforce Inspector Reloaded: This free Chrome extension is the holy grail for Salesforce professionals. Go to the "Data Export" tab, run the Tooling API query above, and click the "Copy to Excel" button.
- Salesforce Schema Builder: While native to Salesforce and fantastic for visualizing relationships (ERD), it does not export to CSV cleanly. Stick to data tools for spreadsheet exports.
🚨 Common Developer Traps & Best Practices
Calling
Schema.getGlobalDescribe() across an enterprise org with thousands of custom objects and managed packages can easily crash your code by exceeding the 10,000ms synchronous CPU limit or the 6MB Heap limit. Always filter your Apex exports by namespace or a specific list of objects, or use Batch Apex to chunk the workload.
Both Apex Describes and SOQL Tooling API queries respect the logged-in user's profile permissions. If your profile does not have "Read" access to a specific field, that field will be completely invisible in your export. Always generate your data dictionaries logged in as a System Administrator.
- Admins: Use Salesforce Inspector Reloaded & the Tooling API.
- Developers: Use the
sf sobject describeCLI command. - Automation: Use Dynamic Apex (
Schema.getGlobalDescribe) for scheduled, emailed reports. - Best Practice: Regenerate your CSV dictionary after every major sandbox deployment to ensure your documentation matches production.
❓ Frequently Asked Questions (FAQ)
Q: Can I export all fields for all objects at once using the Tooling API?
FieldDefinition object in a large org will likely timeout or hit governor limits. It is much safer to iterate through specific objects one by one, or use a dedicated AppExchange metadata tool.
Q: Does the native Salesforce "Data Export" tool in Setup include schema data?
Answer: No. The weekly Data Export service only exports the actual record data (the rows/values), not the metadata or schema definitions (the columns/configuration).
Q: Can I extract picklist values into my CSV export?
Answer: Yes! If you are using the Apex method, you can add fieldDescribe.getPicklistValues() to your inner loop and append it to your CSV row. However, be cautious: fields with hundreds of picklist values can make your CSV file incredibly messy and hard to read.
🔗 Follow-Up Question
Q: How can I use this Data Dictionary during a data migration?
Answer: Once you have your CSV, you can add a new column named "Source System Field." This allows you to hand the spreadsheet to a business analyst or external vendor so they can do field-level mapping (e.g., mapping a legacy SAP field to your Salesforce API name) before you ever open Data Loader or MuleSoft. It acts as your blueprint.
Comments
Questions, corrections and your own experience are all welcome.
Post a Comment