Programmatically Obtaining All Fields on an Object

Its possible to programmatically obtain a list of all fields on an object using Python and the simple_salesforce library.

Credentials below are for a trailhead org created for purposes of this note, only. It contains only default data provided by Salesforce.

from simple_salesforce import Salesforce
import pandas as pd
pd.options.display.max_rows = 999

sf = Salesforce(username='[email protected]',

pd.options.display.max_rows = 999 sets options such that Pandas will print as many as 999 rows in a single returned table.

Obtain All Objects

Iterate through the ordered dict returned by sf.describe() to build a list of objects on the org. Use it to create a DataFrame.

desc = sf.describe()
objects = []
obj_labels = [obj['label']  for obj in desc['sobjects']]
obj_names  = [obj['name']   for obj in desc['sobjects']]
obj_custom = [obj['custom'] for obj in desc['sobjects']]
for label, name, custom in zip(obj_labels, obj_names, obj_custom):
    objects.append((label, name, custom))
objects = pd.DataFrame(objects,
                       columns = ['label','name','custom'])
print(str(objects.shape[0]) + ' objects')
411 objects
label name custom
0 Accepted Event Relation AcceptedEventRelation False
1 Account Account False
2 Account Change Event AccountChangeEvent False
3 Account Clean Info AccountCleanInfo False
4 Account Contact Role AccountContactRole False
5 Account Feed AccountFeed False
6 Account History AccountHistory False
7 Account Partner AccountPartner False
8 Account Share AccountShare False
9 Action Link Group Template ActionLinkGroupTemplate False

Obtain All Fields on a Specific Object

.describe() returns an ordered dictionary of attributes on the specified object including a list of all fields and their attributes. Use the object name (like those in the table above) in the following call to .describe(). Iterate through the ordered dict getting a list of fields on the object. Use it to create a DataFrame.

This example uses the Account object.

desc = sf.Account.describe()
fields = []
field_labels = [field['label'] for field in desc['fields']]
field_names =  [field['name']  for field in desc['fields']]
field_types =  [field['type']  for field in desc['fields']]
for label, name, dtype in zip(field_labels, field_names, field_types):
    fields.append((label, name, dtype))
fields = pd.DataFrame(fields,
                      columns = ['label','name','type'])
print(str(fields.shape[0]) + ' fields')
65 fields
label name type
0 Account ID Id id
1 Deleted IsDeleted boolean
2 Master Record ID MasterRecordId reference
3 Account Name Name string
4 Account Type Type picklist
5 Parent Account ID ParentId reference
6 Billing Street BillingStreet textarea
7 Billing City BillingCity string
8 Billing State/Province BillingState string
9 Billing Zip/Postal Code BillingPostalCode string

Obtain All Data Across All Fields on a Specific Object

Append the name column in the fields DataFrame together such that it can be added to a SQL query string.

obj = 'Account'
field_list = ', '.join(list(fields['name']))
query = 'SELECT ' + field_list + '''
FROM ''' + obj
SELECT Id, IsDeleted, MasterRecordId, Name, Type, ParentId, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry, BillingLatitude, BillingLongitude, BillingGeocodeAccuracy, BillingAddress, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry, ShippingLatitude, ShippingLongitude, ShippingGeocodeAccuracy, ShippingAddress, Phone, Fax, AccountNumber, Website, PhotoUrl, Sic, Industry, AnnualRevenue, NumberOfEmployees, Ownership, TickerSymbol, Description, Rating, Site, OwnerId, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, SystemModstamp, LastActivityDate, LastViewedDate, LastReferencedDate, Jigsaw, JigsawCompanyId, CleanStatus, AccountSource, DunsNumber, Tradestyle, NaicsCode, NaicsDesc, YearStarted, SicDesc, DandbCompanyId, CustomerPriority__c, SLA__c, Active__c, NumberofLocations__c, UpsellOpportunity__c, SLASerialNumber__c, SLAExpirationDate__c
FROM Account
q = sf.query_all(query)
a = (pd.DataFrame(q['records'])
print(str(a.shape) + ': records, fields')
(12, 65): records, fields
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 12 entries, 0 to 11
Data columns (total 65 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   Id                       12 non-null     object 
 1   IsDeleted                12 non-null     bool   
 2   MasterRecordId           0 non-null      object 
 3   Name                     12 non-null     object 
 4   Type                     11 non-null     object 
 5   ParentId                 0 non-null      object 
 6   BillingStreet            12 non-null     object 
 7   BillingCity              11 non-null     object 
 8   BillingState             11 non-null     object 
 9   BillingPostalCode        4 non-null      object 
 10  BillingCountry           4 non-null      object 
 11  BillingLatitude          0 non-null      object 
 12  BillingLongitude         0 non-null      object 
 13  BillingGeocodeAccuracy   0 non-null      object 
 14  BillingAddress           12 non-null     object 
 15  ShippingStreet           10 non-null     object 
 16  ShippingCity             2 non-null      object 
 17  ShippingState            1 non-null      object 
 18  ShippingPostalCode       2 non-null      object 
 19  ShippingCountry          2 non-null      object 
 20  ShippingLatitude         0 non-null      object 
 21  ShippingLongitude        0 non-null      object 
 22  ShippingGeocodeAccuracy  0 non-null      object 
 23  ShippingAddress          10 non-null     object 
 24  Phone                    12 non-null     object 
 25  Fax                      12 non-null     object 
 26  AccountNumber            11 non-null     object 
 27  Website                  12 non-null     object 
 28  PhotoUrl                 12 non-null     object 
 29  Sic                      11 non-null     object 
 30  Industry                 11 non-null     object 
 31  AnnualRevenue            8 non-null      float64
 32  NumberOfEmployees        11 non-null     float64
 33  Ownership                11 non-null     object 
 34  TickerSymbol             8 non-null      object 
 35  Description              6 non-null      object 
 36  Rating                   7 non-null      object 
 37  Site                     0 non-null      object 
 38  OwnerId                  12 non-null     object 
 39  CreatedDate              12 non-null     object 
 40  CreatedById              12 non-null     object 
 41  LastModifiedDate         12 non-null     object 
 42  LastModifiedById         12 non-null     object 
 43  SystemModstamp           12 non-null     object 
 44  LastActivityDate         0 non-null      object 
 45  LastViewedDate           0 non-null      object 
 46  LastReferencedDate       0 non-null      object 
 47  Jigsaw                   0 non-null      object 
 48  JigsawCompanyId          0 non-null      object 
 49  CleanStatus              12 non-null     object 
 50  AccountSource            0 non-null      object 
 51  DunsNumber               0 non-null      object 
 52  Tradestyle               0 non-null      object 
 53  NaicsCode                0 non-null      object 
 54  NaicsDesc                0 non-null      object 
 55  YearStarted              0 non-null      object 
 56  SicDesc                  0 non-null      object 
 57  DandbCompanyId           0 non-null      object 
 58  CustomerPriority__c      9 non-null      object 
 59  SLA__c                   11 non-null     object 
 60  Active__c                10 non-null     object 
 61  NumberofLocations__c     11 non-null     float64
 62  UpsellOpportunity__c     11 non-null     object 
 63  SLASerialNumber__c       11 non-null     object 
 64  SLAExpirationDate__c     11 non-null     object 
dtypes: bool(1), float64(3), object(61)
memory usage: 6.1+ KB
Id 0014W000026oyWmQAI
IsDeleted False
MasterRecordId None
Name Express Logistics and Transport
Type Customer - Channel
ParentId None
BillingStreet 620 SW 5th Avenue Suite 400\nPortland, Oregon ...
BillingCity Portland
BillingState OR
BillingPostalCode None
BillingCountry None
BillingLatitude None
BillingLongitude None
BillingGeocodeAccuracy None
BillingAddress {'city': 'Portland', 'country': None, 'geocode...
ShippingStreet 620 SW 5th Avenue Suite 400\nPortland, Oregon ...
ShippingCity None
ShippingState None
ShippingPostalCode None
ShippingCountry None
ShippingLatitude None
ShippingLongitude None
ShippingGeocodeAccuracy None
ShippingAddress {'city': None, 'country': None, 'geocodeAccura...
Phone (503) 421-7800
Fax (503) 421-7801
AccountNumber CC947211
Website www.expressl&
PhotoUrl /services/images/photo/0014W000026oyWmQAI
Sic 8742
Industry Transportation
AnnualRevenue 9.5e+08
NumberOfEmployees 12300
Ownership Public
TickerSymbol EXLT
Description Commerical logistics and transportation company.
Rating Cold
Site None
OwnerId 0054W00000CKU8EQAX
CreatedDate 2020-10-19T13:31:40.000+0000
CreatedById 0054W00000CKU8EQAX
LastModifiedDate 2020-10-19T13:31:40.000+0000
LastModifiedById 0054W00000CKU8EQAX
SystemModstamp 2020-10-19T13:31:40.000+0000
LastActivityDate None
LastViewedDate None
LastReferencedDate None
Jigsaw None
JigsawCompanyId None
CleanStatus Pending
AccountSource None
DunsNumber None
Tradestyle None
NaicsCode None
NaicsDesc None
YearStarted None
SicDesc None
DandbCompanyId None
CustomerPriority__c Medium
SLA__c Platinum
Active__c Yes
NumberofLocations__c 150
UpsellOpportunity__c Maybe
SLASerialNumber__c 4724
SLAExpirationDate__c 2020-05-15
col_rename = {'Id'   : 'AccountId',
              'Name' : 'AccountName'}
a = (a
AccountId AccountName
0 0014W000026oyWmQAI Express Logistics and Transport
1 0014W000026oyWoQAI United Oil & Gas, UK
2 0014W000026oyWjQAI Dickenson plc
3 0014W000026oyWqQAI GenePoint
4 0014W000026oyWkQAI Grand Hotels & Resorts Ltd

Single Code Snippet

desc = sf.Contact.describe()
fields = []
field_labels = [field['label'] for field in desc['fields']]
field_names =  [field['name']  for field in desc['fields']]
field_types =  [field['type']  for field in desc['fields']]
for label, name, dtype in zip(field_labels, field_names, field_types):
    fields.append((label, name, dtype))
fields = pd.DataFrame(fields,
                      columns = ['label','name','type'])
print(str(fields.shape[0]) + ' fields')
obj = 'Contact'
field_list = ', '.join(list(fields['name']))
query = 'SELECT ' + field_list + '''
FROM ''' + obj
q = sf.query_all(query)
c = (pd.DataFrame(q['records'])
print(str(c.shape) + ': records, fields')
col_rename = {'Id'    : 'ContactId',
              'Name'  : 'ContactName',
              'Phone' : 'ContactPhone'}
c = (c
61 fields
(20, 61): records, fields
ContactId ContactName ContactPhone
0 0034W00002FamUeQAJ Jack Rogers (336) 222-7000
1 0034W00002FamUrQAJ Liz D'Cruz (650) 450-8810
2 0034W00002FamUpQAJ Ashley James +44 191 4956203
3 0034W00002FamUlQAJ Babara Levy (503) 421-7800
4 0034W00002FamUfQAJ Pat Stumuller (014) 427-4427


Org-Level Desc Dictionary Deep Dive

desc = sf.describe()

['encoding', 'maxBatchSize', 'sobjects']
OrderedDict([('activateable', False),
             ('createable', False),
             ('custom', False),
             ('customSetting', False),
             ('deletable', False),
             ('deprecatedAndHidden', False),
             ('feedEnabled', False),
             ('hasSubtypes', False),
             ('isSubtype', False),
             ('keyPrefix', None),
             ('label', 'Accepted Event Relation'),
             ('labelPlural', 'Accepted Event Relations'),
             ('layoutable', False),
             ('mergeable', False),
             ('mruEnabled', False),
             ('name', 'AcceptedEventRelation'),
             ('queryable', True),
             ('replicateable', False),
             ('retrieveable', True),
             ('searchable', False),
             ('triggerable', False),
             ('undeletable', False),
             ('updateable', False),

Object-Level Desc Dictionary Deep Dive

desc = sf.Account.describe()

OrderedDict([('aggregatable', True),
             ('autoNumber', False),
             ('byteLength', 18),
             ('calculated', False),
             ('calculatedFormula', None),
             ('cascadeDelete', False),
             ('caseSensitive', False),
             ('compoundFieldName', None),
             ('controllerName', None),
             ('createable', False),
             ('custom', False),
             ('defaultValue', None),
             ('defaultValueFormula', None),
             ('defaultedOnCreate', True),
             ('dependentPicklist', False),
             ('deprecatedAndHidden', False),
             ('digits', 0),
             ('displayLocationInDecimal', False),
             ('encrypted', False),
             ('externalId', False),
             ('extraTypeInfo', None),
             ('filterable', True),
             ('filteredLookupInfo', None),
             ('groupable', True),
             ('highScaleNumber', False),
             ('htmlFormatted', False),
             ('idLookup', True),
             ('inlineHelpText', None),
             ('label', 'Account ID'),
             ('length', 18),
             ('mask', None),
             ('maskType', None),
             ('name', 'Id'),
             ('nameField', False),
             ('namePointing', False),
             ('nillable', False),
             ('permissionable', False),
             ('picklistValues', []),
             ('polymorphicForeignKey', False),
             ('precision', 0),
             ('queryByDistance', False),
             ('referenceTargetField', None),
             ('referenceTo', []),
             ('relationshipName', None),
             ('relationshipOrder', None),
             ('restrictedDelete', False),
             ('restrictedPicklist', False),
             ('scale', 0),
             ('searchPrefilterable', False),
             ('soapType', 'tns:ID'),
             ('sortable', True),
             ('type', 'id'),
             ('unique', False),
             ('updateable', False),
             ('writeRequiresMasterRead', False)])