Database pages
Every page that is a row in a Notion database, with its title, its status, who created it and how long since anyone touched it.
- Grain
- page
- Built from
- 4Raw tables
- 4Staging
- 1Core
- 1Analytics
- Reads from Notion
- data_sourcepagepage_propertyuser
- Ships as
- Weld and dbt SQL, open source on GitHub
1-- core.notion.database_pages
2-- Every page that is a row in a Notion database, with its title, its status, who
3-- created it and how long since anyone touched it.
4-- Grain: page.
5--
6-- Pages are matched to a data source on parent_data_source_id. Pages that only
7-- carry a parent database id are matched to that database's data source when the
8-- database has exactly one; otherwise data_source_id stays NULL rather than
9-- guessing.
10--
11-- `status` is the value of the page's status-type property. A data source with
12-- more than one status property gets the one whose name sorts first; add a filter
13-- on property_name in staging.notion.page_property if you need another. Every
14-- other property stays in that staging model, one row per page x property.
15
16WITH data_sources AS (
17 SELECT
18 ds.data_source_id,
19 ds.database_id,
20 ARRAY_TO_STRING(
21 ARRAY(SELECT JSON_VALUE(r, '$.plain_text') FROM UNNEST(JSON_QUERY_ARRAY(ds.title_json)) AS r),
22 ''
23 ) AS data_source_title
24 FROM {{staging.notion.data_source}} ds
25),
26
27single_source_databases AS (
28 SELECT database_id, ANY_VALUE(data_source_id) AS data_source_id
29 FROM data_sources
30 GROUP BY 1
31 HAVING COUNT(*) = 1
32),
33
34titles AS (
35 SELECT page_id, string_value AS title
36 FROM {{staging.notion.page_property}}
37 WHERE property_type = 'title'
38 QUALIFY ROW_NUMBER() OVER (PARTITION BY page_id ORDER BY property_name) = 1
39),
40This model and the 5 it depends on. Deploy them together; refs like {{staging.…}} resolve to the matching folders in Weld, and the dbt view uses source() and ref().
How it counts. And where it stops.
Pages are matched to a data source on parent_data_source_id. Pages that only carry a parent database id are matched to that database's data source when the database has exactly one; otherwise data_source_id stays NULL rather than guessing. `status` is the value of the page's status-type property. A data source with more than one status property gets the one whose name sorts first; add a filter on property_name in staging.notion.page_property if you need another. Every other property stays in that staging model, one row per page x property.
Raw tables it reads
- raw.notion.data_source
- raw.notion.page
- raw.notion.page_property
- raw.notion.user
More Notion models
Put Notion in front
of your agents.
Connect Notion, deploy the models, and ask questions in Claude, Cursor or ChatGPT. Free for 14 days, no credit card.