将 Markdown 文件同步到 Notion 数据库页面。支持加粗、斜体、代码、链接、表格、callout、引用、公式等富文本格式,并提供 upsert 语义(同标题先删后插,自动去重)。
编辑 scripts/sync.py 开头的配置区:
python
# ============ 配置区(修改这里) ============
NOTION_KEY = "your-notion-api-token-here"
DB_ID = "your-database-id-here"
OBSIDIAN_ROOT = "/path/to/your/obsidian/vault"
TARGET_DIRS = ["C-我的日志", "B-知识内容/论文阅读"] # 要同步的子目录
EXCLUDE = ["README.md", "template.md"] # 排除的文件
# ===========================================
获取方式:
notion.so/workspace/{DB_ID})text
obsidian-notion/
├── SKILL.md # 本文档
├── scripts/
│ └── sync.py # 同步脚本(主程序)
└── README.md # 使用说明(可选)
数据库需包含以下 5 个属性(名称必须完全一致):
属性名类型说明名称title页面标题日期dateYYYY-MM-DD 格式笔记分类select单选分类主要标签multi_select多选标签整理状态select单选状态
笔记分类选项:
主要标签选项:
整理状态选项:
Notion rich_text 结构(annotations 与 text 同级,不是嵌套!):
json
// 加粗
{"type": "text", "text": {"content": "加粗文字"}, "annotations": {"bold": true}}
// 斜体
{"type": "text", "text": {"content": "斜体文字"}, "annotations": {"italic": true}}
// 行内代码
{"type": "text", "text": {"content": "代码"}, "annotations": {"code": true}}
// 链接
{"type": "text", "text": {"content": "链接"}, "text": {"link": {"url": "https://..."}}}
自动识别规则(正则优先级):
text
`**bold**` → bold=true
`*italic*` → italic=true
`` `code` `` → code=true
`$公式$` → code=true
`[文字](url)` → link
MarkdownNotion Block# 标题heading_1## 标题heading_2### 标题heading_3#### 标题heading_4##### 文字paragraph + bold(非标题块)---divider普通段落paragraph
MarkdownNotion Block- 项目bulleted_list_item1. 项目numbered_list_item嵌套列表children 内嵌 list_item(最多2层)
json
{
"object": "block",
"type": "code",
"code": {
"rich_text": [{"type": "text", "text": {"content": "code"}}],
"language": "python"
}
}
语言标准化映射: py → python, js → javascript, c++ → cpp, sh → bash, yml → yaml 等。不在白名单内的语言统一映射为 plain text。
json
{
"object": "block",
"type": "table",
"table": {
"table_width": 3,
"has_column_header": true,
"has_row_header": false,
"children": [
{
"object": "block",
"type": "table_row",
"table_row": {
"cells": [
[{"type": "text", "text": {"content": "列1"}}],
[{"type": "text", "text": {"content": "列2"}}],
[{"type": "text", "text": {"content": "列3"}}]
]
}
}
]
}
}
json
{
"object": "block",
"type": "callout",
"callout": {
"rich_text": [...],
"icon": {"emoji": "💡"},
"color": "blue_background"
}
}
Markdown 语法: > [!info] 标题 → 多行 callout body
颜色映射:
类型coloremojiinfoblue_backgroundℹ️tipgreen_background💡successgreen_background✅warningyellow_background⚠️danger/errorred_background🚨abstractpurple_background📋notegray_background📝
[!note]
[!type]标签不会显示在 callout 正文中,只用于确定类型
json
{
"object": "block",
"type": "quote",
"quote": {"rich_text": [...]}
}
Markdown 语法: > 引用文字
MarkdownNotion Block$$E=mc^2$$equation block$公式$code 格式 rich_textjson
{"object": "block", "type": "equation", "equation": {"expression": "E=mc^2"}}
同名页面先删后插,确保数据库中每个标题只有最新版本。
流程:
bash
# 1. 编辑配置
vim scripts/sync.py # 修改 NOTION_KEY, DB_ID, OBSIDIAN_ROOT
# 2. 运行同步
python3 scripts/sync.py
# 3. 查看结果
# Found 51 files
# Progress: 20/51 | Success: 20 | Failed: 0
# Progress: 40/51 | Success: 38 | Failed: 2
# === DONE ===
# Total: 51, Success: 49, Failed: 2
错误信息原因解决table_width should be definedtable 缺 table_width必须指定列数rich_text[...].annotations should be an objectannotations 嵌套在 text 内修正为同级结构language should be one of "abap"...语言不在白名单映射到 plain text``body.children.length should be ≤ 100超过 block 限制分批创建Can't edit block that is archived页面已在垃圾箱跳过或先恢复Invalid URL for link链接格式错误确保以 http:/// https:// 开头
re.sub(r'^---\n.*?\n---\n', '', content, flags=re.DOTALL)YYYY-MM-DD,否则使用默认值re.sub(r'<[^>]+>', '', text)