import yamlimport frontmatterimport osimport jsonfrom pathlib import Pathdef extract_vault(vault_path: str, output_path: str): """解析 Obsidian Vault 所有条目为结构化 JSON""" data = { "hexagrams": [], "concepts": [], "classics": [], "persons": [], "methods": [], "relations": [] } for md_file in Path(vault_path).rglob("*.md"): if ".obsidian" in str(md_file) or "模板" in str(md_file): continue post = frontmatter.load(md_file) meta = post.metadata content = post.content # 提取双向链接 links = re.findall(r'\[\[([^\]]+)\]\]', content) # 按 id 类型分类到对应集合 if meta.get('id', '').startswith('hexagram-'): data['hexagrams'].append(meta) elif meta.get('id', '').startswith('concept-'): data['concepts'].append(meta) elif meta.get('id', '').startswith('classic-'): data['classics'].append(meta) elif meta.get('id', '').startswith('person-'): data['persons'].append(meta) elif meta.get('id', '').startswith('method-'): data['methods'].append(meta) # 导出 for key, items in data.items(): with open(f"{output_path}/{key}.json", "w") as f: json.dump(items, f, ensure_ascii=False, indent=2) return data
链接解析规则
链接模式
含义
映射为关系
[[卦名]]
双向链接
N:N 关系
[[人物名|显示名]]
带别名的链接
N:N 关系
#tag
标签
标签索引
[[]] 空链接
待填充的占位符
忽略
Phase 2: 数据库 Migration
PostgreSQL Schema (核心表)
-- 卦象表CREATE TABLE hexagrams ( id TEXT PRIMARY KEY, name TEXT NOT NULL, symbol TEXT, order_num INT, upper_trigram_id TEXT REFERENCES trigrams(id), lower_trigram_id TEXT REFERENCES trigrams(id), gua_ci TEXT, tuan_ci TEXT, xiang_ci TEXT, yao_ci JSONB, wuxing TEXT, direction TEXT, keywords TEXT[], sources JSONB, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW());-- 八卦表CREATE TABLE trigrams ( id TEXT PRIMARY KEY, name TEXT NOT NULL, symbol TEXT, binary TEXT, wuxing TEXT, direction_pre_heaven TEXT, direction_post_heaven TEXT);-- 概念表CREATE TABLE concepts ( id TEXT PRIMARY KEY, name TEXT NOT NULL, category TEXT, definition TEXT, super_concepts JSONB, sub_concepts JSONB, related_concepts JSONB, classic_quotes JSONB, keywords TEXT[]);-- 典籍表CREATE TABLE classics ( id TEXT PRIMARY KEY, title TEXT NOT NULL, authors JSONB, dynasty TEXT, school TEXT[], volumes INT, collection TEXT, source_urls JSONB, structure JSONB);-- 人物表CREATE TABLE persons ( id TEXT PRIMARY KEY, name TEXT NOT NULL, courtesy_name TEXT, birth_year INT, death_year INT, dynasty TEXT, school TEXT[], cbdb_id TEXT, works JSONB);-- 术数表CREATE TABLE methods ( id TEXT PRIMARY KEY, name TEXT NOT NULL, type TEXT, theory_basis JSONB, classic_sources JSONB, steps JSONB);-- 关系表 (泛化关系表)CREATE TABLE relations ( id SERIAL PRIMARY KEY, source_id TEXT NOT NULL, target_id TEXT NOT NULL, type TEXT NOT NULL, properties JSONB, UNIQUE(source_id, target_id, type));