How to map Notion relation properties in Notion automations with Make
There is common knowledge as of December 2023 that you cannot share a part/section/view of a Notion database with a guest/the public without also sharing the source database.
This has been a consistently highly requested feature in the small bubble of the Notion ecosystem of users: the ability to only share a part/view of a database without exposing the entire source. In particular, this use case would benefit agencies and anyone seeking to develop a Notion workspace that acts both as an internal operations hub and as a client/stakeholders portal, for example.
Developing this feature would likely require a fundamental systemic change in the Notion data model, a significant endeavor that would involve lots of resources and trade-offs to consider along the way. There could be other creative ways to implement this use case within Notion in the future, as new features are launched.
As a consequence of this seeming limitation for a portion of users who still would like to implement Notion in their workflows, one major common workaround to circumvent the issue has been to create a simpler, synced version of a client-facing/public database, kept up to date from the source database via automation.
One common tool to build this type of automation is Make because of its powerful capabilities working with the Notion (and any other) API and reasonable pricing. Here is one example guide explaining how to use Make to create a synced version of a database in Notion.
Sometimes, you use relation properties (e.g., a parent-task > sub-task relation in a Tasks database) in your source database, and you would like to keep those relations in the synced version of the database created via the Notion API. Relation properties in the API are based on page IDs, and mapping those out requires some extra steps in your automation.
This essay (and the video above) explains how to tackle this scenario so that you can create your synced databases while keeping the desired relation properties from the source database. Below are all the necessary steps to implement this use case. This is one of the possible solutions I have found, and there may be other ways to achieve the same outcome.
The steps involve a real-life example of syncing an internal tasks database with a simplified replica database. The objective is to maintain the relations between parent and sub-tasks from the source database into the replica when creating pages. This essay only considers the creation of pages with relation properties, not their automatic update. For updating pages, you can follow the same mental model once you understand it.
1. Retrieve internal tasks
The first step is to get the tasks from your internal source database. This can happen in two ways depending on your preference and specific circumstance: (1) via a “watch database items” module; or (2) via a “search objects” module. The former outputs only newly created/updated database items from the source database between every execution cycle. The latter retrieves all database pages that meet a certain filter condition (or all of them if you do not specify any filter condition) from the source database.
You will map the tasks output from this module in subsequent ones so that you can create replicas. You can also include filters after this module if you intend the scenario to continue only when meeting specific conditions.
2. Create replicas
In the second module of the scenario, it is time to create the replicas. These are tasks created in the replica database, composed of property values mapped from the trigger module (step 1). At this stage, the relation properties are left empty (you will handle those in the following modules). In the replica database, I included a property for storing the task IDs from the internal Tasks database.
3. Store relations in a Data Store
Third, you will use the “Add/replace record” Data Store module. This allows you to map out the parent-child task relations and their page IDs to use in subsequent modules. Before this module, you can include the filter to continue only if the “parent task” property is populated, as you do not need to store empty values in the Data Store (for tasks that do not have a parent task).
When setting up the Data Store, you will create a dedicated Data Structure. I called mine “parent item relation”. In the Data Structure, you can include two fields of type Text
: Parent Item Internal ID, and Replica ID. In the former, map the “Parent task ID” value from the trigger module; in the latter, map the “database item ID” from the newly-created replica (from step #2 above).
3. Retrieve relations and update replica items
After the Data Store mapping happens for all the bundles included in the scenario execution, I created a second route (using the router module) and included a filter to run this route only for the last bundle that is processed (total number of bundles = bundle order position).
This allows us to create all the necessary records in the Data Store, which we can retrieve in one place now, and use for mapping the relations in subsequent modules. So, I used the “Search records” data store module (without any filter) to retrieve all the newly created records.
Next up, I used an Array Aggregator and Iterator to manipulate the data and group the “Search records” output data in one single array that I iterate on through the Iterator module.
Finally, the “Search objects” module finds the replica parent item, based on the task ID stored in the Data Store and in a dedicated Notion property of the replica database. Once the parent task replica is found, I use the “Update database item” module to update the parent-child task relation in the replica database. Here, I mapped the page ID from the previous “Search objects” Notion module into the dedicated “Parent task” property in the replica database.
4. Delete Data Store records
Finally, after every execution cycle, you may delete the records from the Data Store using the dedicated “Delete all records” module — unless you think you will need them for your specific automation logic and use case. In my solution, I used a filter to only run this module for the last bundle that is processed.
Similar Articles
Affiliate Links
Build your web forms with Tally (integrates natively with many tools)
Get one free month on the pro plan in Make (automation software)
Get 20% off any Centered subscription (deep work sessions tracker with AI coaches) by using the discount code
SIMONE20
here.