Omnata Product Documentation
  • Omnata Sync for Snowflake
    • What is Omnata Sync for Snowflake?
    • How it works
      • Terminology
      • Branching Mode
      • Sync Directions and Strategies
        • Outbound
        • Inbound
      • Rate Limiting
      • Access Control
      • Notifications
      • Security and Privacy
      • Internal tables
      • Internal Stored Procedures
      • FAQ
    • Step-by-step guides
      • 1. Install the Omnata Sync Engine
      • 2. Install the Omnata Plugin
      • 3. Configure the Plugin
      • 4. Create a connection
      • 5. Create a sync
    • Apps
      • Aerobotics
        • 📘Release History
      • Airtable
        • 📘Release History
      • Amazon Ads
        • Privacy Notice
      • ApprovalMax
        • 📘Release History
      • Bamboo HR
        • 📘Release History
      • Clockify
        • 📘Release History
      • Contentful
        • 📘Release History
      • GitHub
        • 📘Release History
      • Github
      • Google Ads
        • 📘Release History
      • Google Sheets
        • 📘Release History
      • HubSpot
        • 📘Release History
      • Hubspot
      • Infor Data Lake
        • 📘Release History
      • Jira
        • 📘Release History
      • LinkedIn Ads
        • 📘Release History
      • Mailgun
        • 📘Release History
      • Marketo
        • 📘Release History
      • Meta Marketing
        • 📘Release History
      • Microsoft Ads
        • 📘Release History
      • Microsoft Dynamics 365 Business Central
        • 📘Release History
        • 📘Release History
        • 📘Release History
        • 📘Release History
        • 📘Release History
      • Microsoft Entra ID
        • 📘Release History
        • 📘Release History
        • 📘Release History
        • 📘Release History
      • Microsoft Excel
      • Microsoft SQL Server
        • 📘Release History
      • Monday.com
        • 📘Release History
      • MRPeasy
        • 📘Release History
      • PayHero
        • 📘Release History
      • Pinterest Ads
        • Privacy Policy
      • PostgreSQL
        • 📘Release History
      • Salesforce
        • Salesforce Permissions needed
        • Formula Fields
        • How we use the Salesforce APIs
        • 📘Release History
      • Salesforce Marketing Cloud
        • OAuth for APIs, SFTP for file transfer with GPG on outbound
        • OAuth for APIs, SFTP for file transfer
        • OAuth for APIs, Cloud Storage for file transfer
        • 📘Release History
      • Shopify
        • Outbound sync data structures
        • 📘Release History
      • Slack
        • 📘Release History
      • Tiktok Ads
        • Privacy Policy
      • Typeform
        • 📘Release History
      • Wise
        • 📘Release History
      • Xero
        • 📘Release History
      • Zendesk Support
        • 📘Release History
        • 📘Release History
    • Plugins
      • Anatomy of a Plugin
      • Example Plugins
        • Example Plugin: Slack
        • Example Plugin: Zoho CRM
      • Creating Plugins
      • Advanced Plugin topics
        • Advanced rate limiting / concurrency
        • Custom Jinja filters
        • Custom Record Transformers
        • Dynamic Configuration Forms
        • Test case generation
    • Branching
      • Inbound Sync branching
      • Outbound Sync branching
    • Integrations
      • dbt
        • Validation Tests (coming soon)
    • 📘Release History
  • Omnata Connect for Salesforce
    • Overview
    • Getting Started
      • Install the Salesforce App
      • Connect to your data warehouse
        • Snowflake
        • BigQuery
        • Rockset
        • Firebolt
        • SingleStore (previously MemSQL)
      • Deciding which mode to use
    • Omnata with Salesforce Connect (External Objects)
      • Object Configuration
      • View your data in a list
      • Link to other objects
      • Use in a Report
      • Database schema changes
      • Writing to External Objects
    • Omnata with Salesforce Lightning Components
      • Object Configuration
      • View your data in a list
      • Link to other objects
      • Using the Lightning Component on a page
      • Assigning Permissions
    • Advanced Features
      • Row Level Filtering
      • Multi-Currency handling
        • About Multi-Currency
        • Support in Omnata Connect
        • Apex Features
    • Integrations
      • Datadog
    • Omnata with Salesforce Apex
    • Security
    • Use cases
      • Linked object drill-downs
      • Global Search
      • ERP and historical data
      • Embedded product metrics
    • Best Practices
      • Global Search
      • Change Management
      • Snowflake table design
      • Salesforce page layout
      • Salesforce Caching
Powered by GitBook
On this page
  • Background
  • Omnata's Approach
  • Example
  • Requirements
  1. Omnata Sync for Snowflake
  2. Apps
  3. Salesforce

Formula Fields

PreviousSalesforce Permissions neededNextHow we use the Salesforce APIs

Last updated 1 month ago

This feature is currently in public preview

Background

Many Salesforce customers define Custom Fields that are . These are expressions that can include:

  • References to other fields, both from the immediate object and from other objects via relationships

  • Various operators and functions to modify data

  • Functions that are temporal in nature (e.g. TIMENOW(), TODAY())

Since these formula fields often contain business logic, it can be very useful to have them available in Snowflake.

The challenge for ETL products is that:

  1. These are evaluated at a point in time, which means their values quickly become outdated

  2. A change to the evaluated value of a formula does not result in the system modified timestamp of the record, which means they cannot be maintained via incremental export

  3. They often reference other objects, which means they are not simply scalar functions

  4. The formula itself can be edited by Salesforce users, which must be reflected in Snowflake as soon as possible.

As you may already know, Omnata provides two objects for querying data from each inbound stream:

  • A raw table which contains all field values in a single object column

  • A normalized view which dynamically extracts values from the raw table into their own column and performs conversion to native Snowflake types

Omnata's Approach

Support for Salesforce functions is enabled via a sync parameter.

When enabled, Omnata will inspect the formula field definitions and transpile them into an equivalent Snowflake expression. This expression will be used in the normalized view to calculate the current value of the formula.

This solves challenges 1 and 2, bearing in mind that the calculated values are only as fresh as the data in the fields they reference.

If a formula field references another Salesforce object, then that object must also be included in the sync in order for the formula field to be available. The normalized view will automatically join to the corresponding local table in order to calculate the value, solving challenge 3.

When you enable Salesforce function support, all streams will automatically become dependent on the CustomField stream. The CustomField stream syncs all custom field metadata into Snowflake, so that you can see a full list of all custom fields that have been created in Salesforce.

Because the CustomField stream syncs incrementally, the plugin is able to see which objects in Salesforce have had formula field changes, and notify the sync engine of the need to recalculate the normalized view accordingly. This avoids bulk re-creation of

Example

Imagine the Contact object has two custom formula fields:

Name
Formula Value
Description
How to resolve

AccountCreatorEmail__c

Account.CreatedBy.Email

The email address of the user who created the account that this contact belongs to

Joins to an Account object via the "Account" relationship, then joins to a User object via the "CreatedBy" relationship, then returns the email address of that user

Account_Calc__c

`NumericField__c + Account.NumericField2__c

Adds together NumericField__c and NumericField2__c, which both belong to the Account that this contact belongs to

Joins to an Account object via the "Account" relationship, then adds together the values NumericField__c and Account.NumericField2__c

To implement this, in the normalized view for Contact, we have to join the Account table as well as the User table (via Account).

The final query for the normalized view looks something like this:


with
"Contact" as (
    select APP_IDENTIFIER as "OMNATA_APP_IDENTIFIER",
        RETRIEVE_DATE as "OMNATA_RETRIEVE_DATE",
        RECORD_DATA as "OMNATA_RAW_RECORD",
        IS_DELETED as "OMNATA_IS_DELETED",
        RUN_ID as "OMNATA_RUN_ID",
        RECORD_DATA:"AccountId"::VARCHAR as "AccountId",
        RECORD_DATA:"CreatedById"::VARCHAR as "CreatedById", 
        -- other columns...
    from "OMNATA_SYNC_ENGINE"."INBOUND_RAW"."formula-field-testing-to-snowflake_Contact"
),
"Account" as (
    select APP_IDENTIFIER as "OMNATA_APP_IDENTIFIER",
        RETRIEVE_DATE as "OMNATA_RETRIEVE_DATE",
        RECORD_DATA as "OMNATA_RAW_RECORD",
        IS_DELETED as "OMNATA_IS_DELETED",
        RUN_ID as "OMNATA_RUN_ID",
        RECORD_DATA:"AccountNumber"::VARCHAR as "AccountNumber",
        IFF(RECORD_DATA:"NumericField__c"='',null,RECORD_DATA:"NumericField__c")::NUMERIC(38,19) as "NumericField__c",
        IFF(RECORD_DATA:"NumericField2__c"='',null,RECORD_DATA:"NumericField2__c")::NUMERIC(38,19) as "NumericField2__c",
        RECORD_DATA:"OwnerId"::VARCHAR as "OwnerId",
        -- other columns...
    from "OMNATA_SYNC_ENGINE"."INBOUND_RAW"."formula-field-testing-to-snowflake_Account"
),
"User" as (
    select APP_IDENTIFIER as "OMNATA_APP_IDENTIFIER",
        RETRIEVE_DATE as "OMNATA_RETRIEVE_DATE",
        RECORD_DATA as "OMNATA_RAW_RECORD",
        IS_DELETED as "OMNATA_IS_DELETED",
        RUN_ID as "OMNATA_RUN_ID",
        RECORD_DATA:"Email"::VARCHAR as "Email",
        RECORD_DATA:"Username"::VARCHAR as "Username",
        -- other columns...
    from "OMNATA_SYNC_ENGINE"."INBOUND_RAW"."formula-field-testing-to-snowflake_User"
    )
select "Contact".*,
    "Account.CreatedBy"."Email" as "AccountCreatorEmail__c",
    ("Account"."NumericField__c" + "Account"."NumericField2__c") as "Account_Calc__c"
    from "Contact"
JOIN "Account" as "Account" ON "Contact"."AccountId" = "Account"."Id"
JOIN "User" as "Account.CreatedBy" ON "Contact"."CreatedById" = "Account.CreatedBy"."Id"

As you can see, we use CTEs to bring in any of the referenced objects, and join to them from the main object by following their Salesforce relationships. Note that an object may be referenced multiple times via different relationships that join on different fields.

In the final query, we use various Snowflake expressions to implement the equivalent formula logic.

Requirements

In order to retrieve formula field definitions in bulk, we must use the Metadata API. This means that the Salesforce profile for the configured user must have the following privilege enabled:

Formula fields