[recipes] Preserve full frontmatter in obsidian-vault-import metadata#301
[recipes] Preserve full frontmatter in obsidian-vault-import metadata#301dhanjit wants to merge 1 commit into
Conversation
|
Hey @dhanjit — welcome to Open Brain Source! 👋 Thanks for submitting your first PR. The automated review will run shortly and check things like metadata, folder structure, and README completeness. If anything needs fixing, the review comment will tell you exactly what. Once the automated checks pass, a human admin will review for quality and clarity. Expect a response within a few days. If you have questions, check out CONTRIBUTING.md or open an issue. |
The recipe parses YAML frontmatter into a Python dict but only persists 6 hardcoded keys (source, title, folder, tags, date, wikilinks) to the row's metadata column. Any other user-defined frontmatter fields are silently dropped on import — the information is in the source file, parsed correctly, then thrown away on the way into the database. Add a `frontmatter` side-car key under `metadata` carrying a JSON-safe deep copy of every parsed frontmatter key/value. A new private helper `_jsonify_frontmatter` recursively converts `datetime.datetime` / `datetime.date` values (which YAML auto-parses from `date: YYYY-MM-DD`) to ISO strings so they're safe for the JSONB column, and deep-copies nested dicts and lists. All existing top-level metadata keys remain unchanged. No schema change is required — `thoughts.metadata` is already `jsonb`. Existing rows are unaffected; only new inserts populate `frontmatter`.
a9a57b0 to
1725717
Compare
|
Thanks for the contribution. This is a real bug fix — YAML frontmatter with — Alan (community reviewer; non-binding) |
Contribution Type
/recipes)This modifies an existing recipe (
recipes/obsidian-vault-import); it does not introduce a new recipe folder, so there is no newREADME.md/metadata.jsonto ship.What does this do?
This fixes a standard information-loss problem in the Obsidian vault import recipe: any user-defined frontmatter fields are silently dropped on ingestion.
import-obsidian.pyparses YAML frontmatter into a Pythonmetadict but only persists 6 hardcoded keys (source,title,folder,tags,date,wikilinks) to the row'smetadataJSONB column. Everything else — custom fields, plugin-generated metadata, structured properties, references — never makes it into the database. The information is in the source file, it's parsed correctly, and then it's thrown away.This PR adds a
frontmatterside-car key undermetadatacarrying a JSON-safe deep copy of every parsed frontmatter key/value. A new private helper_jsonify_frontmatterconvertsdatetime.datetime/datetime.datevalues (which YAML auto-parses fromdate: YYYY-MM-DD) to ISO strings so they're safe for the JSONB column, and recurses into nested dicts and lists.All existing top-level metadata keys remain unchanged. Existing readers that look at
metadata.source,metadata.title,metadata.date, etc. are unaffected. The side-car simply preserves everything else undermetadata.frontmatterfor downstream queries likemetadata->'frontmatter'->>'<custom_key>'.Example
Input note with a mix of standard and custom frontmatter:
Before this PR, only
tagsanddatewould survive intometadata. After:{ "source": "obsidian", "title": "note", "folder": "", "tags": ["tag-a", "tag-b"], "date": "2024-05-13", - "wikilinks": [] + "wikilinks": [], + "frontmatter": { + "title": "My Custom Title", + "date": "2024-05-13", + "tags": ["tag-a", "tag-b"], + "status": "active", + "priority": 2, + "authors": ["Alice", "Bob"], + "external_id": "abc-123", + "nested": {"key": "value", "list": [1, 2, 3]} + } }Note that
metadata.frontmatter.dateis the ISO string"2024-05-13"rather than adatetime.dateobject — the helper handles this so the row stays JSONB-insertable.Requirements
No new dependencies. Uses stdlib
datetimeonly.No schema migration needed —
thoughts.metadatais alreadyjsonb.Backward compatibility
frontmatterkey retroactively — only new inserts (and re-imports of modified notes) populate it.--forceor modify notes.Testing
Verified with a manual smoke test against a fixture vault containing a note with mixed-type frontmatter (strings, ints, lists, nested dicts, a YAML date):
metadata.frontmatter.source,title,folder,tags,date,wikilinks) are unchanged.datetime.datevalue (date: 2024-05-13) becomes the ISO string"2024-05-13"inmetadata.frontmatter.date.note['meta']).json.dumps(metadata)round-trips without error — no non-JSON-native types remain.End-to-end
python import-obsidian.py /path/to/fixture-vault --dry-run --verboseruns to completion with the change applied.Checklist
README.md— N/A; this modifies an existing recipe and is not a new contribution foldermetadata.jsonhas all required fields — N/A; existing recipe's metadata is unchanged