完整备份从压榨 API 返回的所有数据开始
每个工具都说自己「完整」,却没有哪个能完全做到。NotionManager 做三件事:把 API 肯给的全部拿走,把各部分之间的关系重建起来,把边界如实说清楚。
把 API 肯给的全部读下来
第一步是全部读下来,不做任何解释。从你共享的每个根对象开始,每个页面,每个数据库,每个属性、每个 block,都沿着子页面一直向下读,直到没有东西可读。副本从原始数据开始。你在这个阶段过滤或改写掉的内容,之后都找不回来。
除非刻意要求过滤(如跳过不备份注释,或者跳过不下载文件),NotionManager 尝试抓取所有可能的东西,确保本地备份的完整性。最终的渲染效果可能因为样式差异而不同,但是数据本身永远是完整可靠的。
再重建原始数据的含义
后一半是把结构放回去。Notion 既是树,也是图。页面通过提及和关联互相指向,rollup 在这些关联上算出数值,数据库要通过视图来呈现,视图还提供筛选和排序。一个装满 JSON 的文件夹字节相同,却没有这层含义。
重建关联之后,副本就能浏览、能核查。你可以顺着一条关联,走到它指向的页面。你会看到 rollup 当时的值,而不是一个已经算不出的公式。打开数据库,你就能读到视图当时展示的那些行。
重建覆盖了什么
页面结构
完整的页面结构,所有的支持的 block 类型的渲染,如richtext,callout等。
页面引用
页面提到另一个页面时,这条链接会留在副本里。离线也能顺着它走。
数据库关联
如果一行指向另一个数据库里的某一行,还原后它就是两个已复制页面之间的关联。它不会变成一个找不到目标的标识符。
rollup
计算出的值按本次运行当时的值保留。一份历史副本应当展示那一刻的值。
视图
每个视图都随它呈现的数据一起复制,包括行、行的属性,以及视图给它们排的顺序。
外部媒体文件
图片,视频,声音,PDF等,完全和它们在 Notion 中的样子一样
清单,如实列出
| 工作区的一部分 | 在备份里吗? |
|---|---|
| 页面、它们的 block 与嵌套 | 是。一直读到最底层的子页面。 |
| 数据库、它们的数据源与属性 | 是,包括每一行携带的属性。 |
| 作为页面的行 | 是。每一行都是页面,都有自己的内容。 |
| 页面之间的关联与提及 | 是。关联已重建,链接在副本内部可用。 |
| rollup 与其他计算值 | 是。按运行当时的值保留。 |
| 每个视图背后的行与顺序 | 是。视图呈现过的数据都在。 |
| 视图的外观:颜色、分组、布局 | 部分。API 不返回部分,尽可能按照Notion的样式呈现。 |
| 注释 | 部分。仅仅尚未解决的注释会被备份。备份注释需要单独打开开关,因为备份注释会严重拖慢备份速度 |
| 外部媒体文件 | 是。为了最佳的本地浏览效果,默认下载全部外部媒体文件到本地。如果不想这样,可以关闭外部文件的下载 |
| API 拒绝描述的 block 类型 | 部分。按它声明的类型和位置保留,页面有明确提示,所以你能看到哪里缺了数据。 |
| 工作区权限、共享与访客访问 | 否。那是 Notion 的配置,不是内容。 |
| 任何你没有共享给集成的内容 | 否。副本里就是你授权的那些内容。 |
为什么这份清单不长,但很诚实
说能备份一切的工具,并没有仔细看过 API。上面那份清单,就是 Notion API 能交给任何人的全部内容。最后三行最重要:它们说明备份是 Notion 的补充,而不是替代品。
有用的检验标准不是理论上的完整,而是你能不能打开副本,自己看一眼。可浏览的副本正是为此而存在。
幸运的是,作为用户来说,Notion可见数据都是可以备份的,不能备份都往往都是样式,特殊的结构等,这些并不影响备份的价值和有效性。
接下来可以看
常见问题
完整备份包含附件文件吗?
文件属于内容的一部分。只要 API 提供,NotionManager 就会把文件一起读进来,包含外链文件。有些文件链接由 API 临时签发,文件链接会失效,所以 NotionManager 倾向于下载所有文件到本地,当然你可以控制这个行为。
为什么视图的颜色和布局没有备份?
因为 Notion 没有提供返回这些信息的接口。NotionManager 尽可能还原视图的样式,但是不保证和 Notion 完全一致。
如果 rollup 按值存储,还原之后它们错了吗?
它们对取副本的那一刻是正确的。历史副本展示的是工作区当时的内容,而不是公式现在算出的结果。
「完整」等于「全部」吗?
不。没有哪个 Notion 备份能诚实地这么说。完整的意思是:API 肯给的全部内容,都按 Notion 组织它的方式组织好;API 拒绝提供的部分,就公开写明。
