Set up the Openflow Connector for Microsoft Dataverse¶
Note
This connector is subject to the Snowflake Connector Terms.
This topic describes the steps to set up the Openflow Connector for Microsoft Dataverse.
Prerequisites¶
- Ensure that you have reviewed About Openflow Connector for Microsoft Dataverse.
- Ensure that you have Set up Openflow - BYOC or Set up Openflow - Snowflake Deployments.
- If using Openflow - Snowflake Deployments, ensure that you’ve reviewed configuring required domains and have granted access to the required domains for the Microsoft Dataverse connector.
Get the credentials¶
As a Microsoft Dataverse administrator, perform the following steps:
- Ensure you have a Dataverse Environment to work with, and you have access to that environment through https://admin.powerplatform.microsoft.com/.
- Ensure that you have an application registered in Microsoft Entra ID in portal.azure.com. This application must have access to the tenant we have our Dataverse Environment available. To register the application follow this guide.
- Generate and store ClientID and Client Secret within that application.
- Go to Power Apps Admin Center and configure your Dataverse Environment to be accessed via applications registered before. To do that, go to Manage » Environments and select the environment to configure. Then go to Settings » Users & permissions » Application users. Previously created applications must be added and granted with privileges necessary to read data from Microsoft Dataverse.
- Copy and save the Environment URL of the selected Dataverse Environment from https://admin.powerplatform.microsoft.com/.
Set up Snowflake account¶
As a Snowflake account administrator, perform the following tasks:
-
- Create a Snowflake user with the type as SERVICE.
Create a database and schema to store the replicated data, and set up privileges for the service user to create tables in destination schema by granting the USAGE and CREATE TABLE privileges.
-
Create a pair of secure keys (public and private). Store the private key for the user in a file to supply to the connector’s configuration. Assign the public key to the Snowflake service user:
For more information, see pair of keys.
-
Snowflake strongly recommends this step. Configure a secrets manager supported by Openflow, for example, AWS, Azure, and Hashicorp, and store the public and private keys in the secret store.
Note
If for any reason, you do not wish to use a secrets manager, then you are responsible for safeguarding the public key and private key files used for key-pair authentication according to the security policies of your organization.
- Once the secrets manager is configured, determine how you will authenticate to it. On AWS, it’s recommended that you the EC2 instance role associated with Openflow as this way no other secrets have to be persisted.
- In Openflow, configure a Parameter Provider associated with this Secrets Manager, from the hamburger menu in the upper right. Navigate to Controller Settings » Parameter Provider and then fetch your parameter values.
- At this point all credentials can be referenced with the associated parameter paths and no sensitive values need to be persisted within Openflow.
-
If any other Snowflake users require access to the raw ingested documents and tables ingested by the connector (for example, for custom processing in Snowflake), then grant those users the role created in step 1.
-
Designate a warehouse for the connector to use. Grant the USAGE privilege on the warehouse to the role created before. Start with the smallest warehouse size, then experiment with size depending on the number of tables being replicated, and the amount of data transferred. Large table numbers typically scale better with multi-cluster warehouses, rather than larger warehouse sizes.
Set up the connector¶
As a data engineer, perform the following tasks to install and configure the connector:
Install the connector¶
To install the connector, do the following as a data engineer:
-
Navigate to the Openflow overview page. In the Featured connectors section, select View more connectors.
-
On the Openflow connectors page, find the connector and select Install.
-
In the Select runtime dialog, select your runtime from the Available runtimes drop-down list and click Install.
Note
Before you install the connector, ensure that you have created a database and schema in Snowflake for the connector to store ingested data.
-
Authenticate to the deployment with your Snowflake account credentials and select Allow when prompted to allow the runtime application to access your Snowflake account. The connector installation process takes a few minutes to complete.
-
Authenticate to the runtime with your Snowflake account credentials.
The Openflow canvas appears with the connector process group added to it.
Configure the connector¶
- Right-click on the imported process group and select Parameters.
- Populate the required parameter values as described in Flow parameters.
Flow parameters¶
This section describes the flow parameters that you can configure based on the following parameter contexts:
- Dataverse Source Parameters: Used to establish connection with Dataverse.
- Dataverse Destination Parameters: Used to establish connection with Snowflake.
- Dataverse Ingestion Parameters: Used to define the configuration of data downloaded from Dataverse.
Dataverse Source Parameters¶
| Parameter | Description |
|---|---|
| Source Dataverse Environment URL | The main identifier of a source system to fetch data. The URL indicates a namespace where Dataverse tables exist. It also lets you create a scope parameter for OAuth. |
| Source Tenant ID | Microsoft Azure Tenant ID. It’s used to create OAuth URLs. Microsoft Dataverse Environment must belong to this tenant. |
| Source OAuth Client ID | Microsoft Azure Client ID used to access Microsoft Dataverse API. Microsoft Dataverse Web API uses OAuth authentication to secure access, and the connector uses the client credentials flow. To learn about client ID and how to find it in Microsoft Entra, see Application ID (client ID). |
| Source OAuth Client Secret | Microsoft Azure Client Secret used to access Microsoft Dataverse API. Microsoft Dataverse Web API uses OAuth authentication to secure access, and the connector uses the client credentials flow. To learn about client secret and how to find it in Microsoft Entra, see Certificates & secrets. |
Dataverse Destination Parameters¶
| Parameter | Description | Required |
|---|---|---|
| Destination Database | The database where data will be persisted. It must already exist in Snowflake. The name is case-sensitive. For unquoted identifiers, provide the name in uppercase. | Yes |
| Destination Schema | The schema where data will be persisted, which must already exist in Snowflake. The name is case-sensitive. For unquoted identifiers, provide the name in uppercase. See the following examples:
| Yes |
| Snowflake Authentication Strategy | When using:
| Yes |
| Snowflake Account Identifier | When using:
| Yes |
| Snowflake Private Key | When using:
| No |
| Snowflake Private Key File | When using:
| No |
| Snowflake Private Key Password | When using:
| No |
| Snowflake Role | When using:
| Yes |
| Snowflake Username | When using:
| Yes |
| Snowflake Warehouse | Snowflake warehouse used to run queries. | Yes |
Dataverse Ingestion Parameters¶
| Parameter | Description |
|---|---|
| Ingestion Schedule Interval | Interval used as the triggering interval for the processor that fetches the list of tables and initializes ingestion. The default is 300 s. |
| Source Tables Filter Strategy | Strategy for filtering tables to be ingested. Can be one of REGEXP and LIST. |
| Source Tables Filter Value | Value of the tables filter. When Source Tables Filter Strategy is set to REGEXP - this is the regular expression to be matching selected tables. When LIST is provided, then it is a comma separated list of table names. |
| Column Filter JSON | Optional. A JSON array specifying per-table column filters. Columns can be included or excluded by name (included, excluded) or by regular expression pattern (includedPattern, excludedPattern). The table value must be the singular logical entity name (e.g., annotation), not the plural entity set name used in Source Tables Filter Value (e.g., annotations). For example: [ {"table": "mytable", "excluded": ["binarycolumn", "binarycolumn_binary"]} ] excludes large binary columns from mytable. See Replicate a subset of columns in a table for full details. |
| Max Page Size | Number of records fetched from a Dataverse table in a single request. It can’t be larger than 5000. A higher value can increase ingestion speed, but it can also cause timeouts. The default is 1000. |
| Merge Task Schedule CRON | CRON expression that defines when data is merged from the journal table into the destination table. The default is * * * * * ?, which merges continuously. Use a narrower schedule to reduce how long the warehouse runs. For example, * 0 * * * ? merges for one minute at the top of every hour. |
| Include Formatted Values | Optional. Whether the connector also fetches Dataverse formatted values and writes them to the _DATAVERSE_FORMATTED_VALUES column of the destination table. The default is false. See Include formatted values. |
Note
When configuring Source Tables Filter Value, use the entity set name (plural form,
e.g., annotations) rather than the table name displayed in the Microsoft Dataverse
interface. To find the entity set name for a table, go to
Power Apps, select Tables, find your table,
then select Advanced » Tools » Copy set name.
The Column Filter JSON parameter uses a different naming convention — it requires the
singular logical entity name (e.g., annotation). See
Replicate a subset of columns in a table for details.
Run the flow¶
- Right-click on the plane and select Enable all Controller Services.
- Right-click on the imported process group and select Start. The connector starts the data ingestion.
Replicate a subset of columns in a table¶
The connector can filter the data replicated per table to a subset of configured columns.
To apply filters to columns, set the Column Filter JSON parameter in the Dataverse ingestion parameters to a JSON filter.
Add an array of configurations, one entry for every table to which you want to apply a filter.
Important
The table field must use the singular logical entity name (e.g., annotation),
not the plural entity set name used in Source Tables Filter Value (e.g., annotations).
To find the logical entity name in Power Apps, go to Power Apps,
select Tables, find your table, then select Advanced » Tools
» Copy logical name.
Some columns have a binary representation stored under a _binary-suffixed column name
(for example, a column mycolumn may also appear as mycolumn_binary). To fully
exclude such a column, list both names in the excluded array.
The following example excludes large binary columns from a table:
Columns can be included or excluded by name or pattern. You can apply a single condition per table, or combine multiple conditions, with exclusions taking precedence over inclusions.
The following example shows all available fields. The table field is mandatory. One or
more of included, excluded, includedPattern, excludedPattern is required.
Include formatted values¶
Microsoft Dataverse stores many columns as raw values, such as an option set integer, a lookup GUID, or an unformatted amount. For those columns, Dataverse can also return a display value, called a formatted value: the localized label of a choice, yes/no, status, or status reason column, the primary name of a lookup or owner column, and locale-formatted numbers, currencies, and dates. For details about which columns have formatted values, see Select columns using OData in the Microsoft documentation.
By default, the connector replicates raw values only. To also replicate formatted values,
set the Include Formatted Values parameter in the Dataverse ingestion parameters to
true, then restart the connector process group so that the change takes effect.
Raw columns are unchanged when you enable this parameter. Instead, the connector adds a
single _DATAVERSE_FORMATTED_VALUES column of type OBJECT to each replicated table. The
keys of the object are source column names and the values are always strings:
Keep the following in mind when you query the column:
- Lookup and owner columns keep the
_<column>_valueform that Dataverse uses, as shown by_transactioncurrencyid_valuein the preceding example. - Columns that don’t have a formatted value are absent from the object. If a row has no
formatted values at all,
_DATAVERSE_FORMATTED_VALUESisNULLfor that row. - Rows that were deleted at the source don’t carry formatted values. For more information about how deletes are replicated, see Connector-managed columns.
- If you enable the parameter for a connector that already replicated data, the column is
populated from the next ingestion onwards. Rows that were replicated earlier keep
NULLuntil they change at the source again. - If a source table already has a column named
_DATAVERSE_FORMATTED_VALUES, ingestion of that table fails.
To read a single formatted value, extract it by key and cast it:
Dataverse column names are lowercase, so quote them in queries. The connector-managed columns are uppercase and don’t need quoting.
Note
Formatted values are display strings that depend on the locale and configuration of your Dataverse environment, so they can change without the underlying data changing. Use the raw columns for joins, filters, and calculations, and use formatted values for presentation.
Manage table state¶
The connector maintains per-table ingestion state in the Dataverse Table State Service
controller service. Each entry records the current ingestion status and the delta token
used for change tracking.
View connector state¶
To view the current state of all tables:
- Right-click on the canvas and select Controller services.
- Locate the controller service named Dataverse Table State Service.
- In the Dataverse Table State Service menu, click View state.
The state is a set of key/value pairs where the key is the table entity set name
(for example, accounts). The value has the format
<STATUS>;<deltaToken>;<skipToken>;<staleFlag>, for example:
The STATUS can be one of the following:
FETCHING— the connector is actively fetching records for this table.PROCESSING— the table is queued for ingestion but not currently being fetched.DONE— all available data was fetched successfully. The connector will check for new data on the next scheduled run according to the Ingestion Schedule Interval parameter.FAILED— an unrecoverable error occurred. Review the connector logs for details. If the logs indicate a configuration issue or a known limitation, resolve it and restart ingestion for the affected table. If no known cause is found, this may indicate a bug or an unsupported scenario; contact Snowflake Support.
Restart ingestion for a single table¶
Removing a table from the filter and re-adding it causes the connector to perform a full re-ingestion of that table. All currently available records are fetched again and merged into the destination table by primary key, so existing rows are updated in place rather than duplicated. However, the connector doesn’t recover delete operations that occurred during downtime.
To restart ingestion for a specific table:
-
Make sure the connector is running and open the connector process group.
-
Right-click on the canvas, select Parameters and remove the target table’s entity set name from the Source Tables Filter Value parameter.
-
Stop the List Dataverse Tables processor and start it again to trigger removal of the table state.
-
Wait until the table’s state has been removed:
- Right-click on the canvas and select Controller services.
- Locate the controller service named Dataverse Table State Service and select View state from its ellipsis menu.
- Wait until the table’s entity set name no longer appears in the list.
-
Stop the List Dataverse Tables processor and wait until all queues are empty.
-
(Optional) DROP the destination objects in Snowflake and let the connector recreate them.
Since a full re-ingestion only upserts records that currently exist at the source, rows deleted at the source during downtime are not removed from the destination table automatically. After you delete the destination table and re-ingest it, the table includes only records that are still present in the source.
DROP the following objects, where
<TABLE>is the table’s entity set name in uppercase:- Destination table:
<destination_database>.<destination_schema>.<TABLE> - Journal table:
<destination_database>.<destination_schema>.<TABLE>__JOURNAL - Journal stream:
<destination_database>.<destination_schema>.<TABLE>__JOURNAL_STREAM
- Destination table:
-
Re-add the table’s entity set name to Source Tables Filter Value and start the List Dataverse Tables processor again.
-
Verify that an entry for the table is present in Dataverse Table State Service state again.
Note
To restart ingestion for all replicated tables, repeat this procedure for each table, or remove all entity set names from the Source Tables Filter Value parameter and then re-add them.
Do not delete FlowFiles manually while the connector is running. Doing so can leave a table in the
FETCHING status indefinitely. If this occurs, restart ingestion for that table as described above.