Edit PostgreSQL database data as JSON files with schema validation and three-way merge support
https://github.com/hediet/database-editor.git
A CLI tool for PostgreSQL that converts relational database schemas into editable hierarchical JSON and back.
Work with your database data as nested, hierarchical JSON rather than flat relational tables. Edit the JSON in VS Code (with full schema validation), then sync changes back to the database.
PostgreSQL ββ Hierarchical JSON ββ Edit in VS Code
Instead of flat tables like:
-- Organization table
| id | name |
|----|---------|
| 1 | Acme |
-- Project table
| id | name | organizationId |
|----|--------|----------------|
| 10 | Alpha | 1 |
You edit nested JSON:
{
"$schema": "./.db-editor/data.schema.json",
"organizations": [
{
"id": "1",
"name": "Acme",
"projects": [
{ "id": "10", "name": "Alpha" }
]
}
]
}
npm install
npm run build
See src/demo.test.ts for a complete CI-verified workflow example that demonstrates:
Export database tables to a JSON file (nested format by default):
# Dump all tables as nested JSON
db-editor dump -c "postgresql://..." -o data.json
# Dump with row limits
db-editor dump -c "postgresql://..." -o data.json --limit 100
# Dump with nested limits (max children per parent)
db-editor dump -c "postgresql://..." -o data.json --nested-limit 20
# Dump as flat JSON (table-per-key)
db-editor dump -c "postgresql://..." -o data.json --flat
The dump command creates three files:
data.json β Main file you edit.db-editor/data.base.json β Base snapshot for diffing.db-editor/data.schema.json β JSON Schema for autocompleteShow changes that would be applied without executing them:
# Preview changes
db-editor preview -c "postgresql://..." -f data.json
# Preview with SQL output
db-editor preview -c "postgresql://..." -f data.json --sql
Apply changes from file to database (interactive by default):
# Interactive sync (shows diff, asks for confirmation)
db-editor sync -c "postgresql://..." -f data.json
# Non-interactive sync
db-editor sync -c "postgresql://..." -f data.json --yes
Reset database to match file exactly:
# Interactive reset
db-editor reset -c "postgresql://..." -f data.json
# Non-interactive reset
db-editor reset -c "postgresql://..." -f data.json --yes
Export database schema as a Mermaid ER diagram:
# Output to stdout
db-editor mermaid -c "postgresql://..."
# Output to file
db-editor mermaid -c "postgresql://..." -o diagram.mmd
# Hide column details
db-editor mermaid -c "postgresql://..." --no-columns
Foreign keys are classified based on ON DELETE behavior:
| ON DELETE Action | Classification |
|---|---|
CASCADE | composition (parent owns child) |
SET NULL | reference |
RESTRICT | reference |
NO ACTION | reference |
| Self-referencing | reference (always) |
For tables with multiple incoming compositions (multi-parent), exactly one is designated as dominant. The dominant relationship determines where the child appears nested in the JSON tree.
Dominance is selected by:
{
"$schema": "./.db-editor/data.schema.json",
"organizations": [
{
"id": "org-1",
"name": "Acme",
"projects": [
{
"id": "proj-1",
"name": "Alpha"
}
]
}
]
}
{
"Organization": [
{ "id": "org-1", "name": "Acme" }
],
"Project": [
{ "id": "proj-1", "name": "Alpha", "organizationId": "org-1" }
]
}
Partial marker β Indicates truncated lists (from --limit):
{ "$partial": true, "skipped": 1000 }
Reference marker β Collapsed child (FK only, not expanded):
{ "$ref": true, "id": "proj-1" }
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLI Layer β
β (commander, argument parsing, output formatting) β
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β DatabaseEditor β
β (orchestrates dump, preview, sync, reset operations) β
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
ββββββββββββββββ¬ββββββββββββββββΌββββββββββββββββ¬ββββββββββββ
βΌ βΌ βΌ βΌ βΌ
ββββββββββββ ββββββββββββ ββββββββββββββ βββββββββββββ ββββββββββββ
βSchema β βOwnership β β Nested β β Diff β β SQL β
βExtractor β βTree β β Serializer β β Algorithm β βGenerator β
ββββββββββββ ββββββββββββ ββββββββββββββ βββββββββββββ ββββββββββββ
β
βββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β SyncEngine β
β (fetch, diff, apply changes in transaction) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Module | Description |
|---|---|
| schemaExtractor.ts | Extracts tables, columns, FKs from PostgreSQL |
| ownershipTree.ts | Builds ownership tree, classifies relationships |
| nested.ts | Converts between flat and nested representations |
| diff.ts | Diffs two flat datasets (insert/update/delete) |
| sqlGenerator.ts | Generates SQL from change sets |
| syncEngine.ts | Orchestrates sync with transaction support |
| jsonSchemaGenerator.ts | Generates JSON Schema for autocomplete |
| mermaidGenerator.ts | Generates Mermaid ER diagrams |
| databaseEditor.ts | High-level API (dump, preview, sync, reset) |
npm install
npm run build # Compile TypeScript
npm test # Run tests (watch mode)
npm run test:run # Run tests once
All tests use PGLite β PostgreSQL running in-process via WebAssembly. No Docker or external database needed.
npm run test:run
# 95 tests passing across 11 test files
ISC