You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add reconcile mode for declarative database seeding
Seed sets can now operate in reconcile mode where the spec is the source
of truth. On each run, initium detects changes and converges the database:
new rows are inserted, changed rows are updated, removed rows are deleted.
- Add `mode: reconcile` option to seed sets (default: `once`)
- Add per-row tracking table for change detection and orphan deletion
- Add content hash on tracking table for fast skip when unchanged
- Add `--dry-run` flag to preview changes without modifying the database
- Add `--reconcile-all` flag to override all seed sets to reconcile mode
- Auto-migrate existing tracking tables (add content_hash column)
- Support auto_id + @ref resolution during reconciliation
- 12 new tests covering reconcile, dry-run, validation, and migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
### Added
11
+
- Reconcile mode for seed sets (`mode: reconcile`): declarative seeding where the spec is the source of truth. Changed rows are updated, new rows are inserted, and removed rows are deleted automatically.
12
+
-`--reconcile-all` CLI flag to override all seed sets to reconcile mode for a single run.
13
+
-`--dry-run` CLI flag to preview what changes reconciliation would make without modifying the database.
14
+
- Per-row tracking table (`initium_seed_rows`) for change detection and orphan deletion in reconcile mode.
15
+
- Content hash (`content_hash` column) on the seed tracking table for fast "anything changed?" checks before row-by-row comparison.
16
+
- Automatic migration of existing tracking tables: the `content_hash` column is added transparently on first run. Existing seed sets remain in `once` mode with no behavior change.
| `phases[].seed_sets[].tables[].order` | integer | No | Execution order within the seed set (default: 0) |
87
89
| `phases[].seed_sets[].tables[].unique_key` | string[] | No | Columns for duplicate detection |
@@ -213,6 +215,53 @@ rows:
213
215
password_hash: "{{ env.ADMIN_PASSWORD_HASH }}"
214
216
```
215
217
218
+
### Reconcile Mode
219
+
220
+
By default, seed sets are applied once and never modified (`mode: once`). Reconcile mode makes seeding declarative: the spec becomes the source of truth, and initium converges the database to match it on every run.
221
+
222
+
Enable reconcile mode per seed set:
223
+
224
+
```yaml
225
+
seed_sets:
226
+
- name: departments
227
+
mode: reconcile # "once" (default) or "reconcile"
228
+
tables:
229
+
- table: departments
230
+
unique_key: [name] # Required for reconcile mode
231
+
rows:
232
+
- name: Engineering
233
+
- name: Sales
234
+
```
235
+
236
+
Or override all seed sets for a single run:
237
+
238
+
```bash
239
+
initium seed --spec /seeds/seed.yaml --reconcile-all
240
+
```
241
+
242
+
**How it works:**
243
+
244
+
1. On each run, initium computes a content hash of the rendered seed set (after template/env expansion).
245
+
2. If the hash matches the stored hash, the seed set is skipped (no-op).
246
+
3. If the hash differs, initium reconciles row by row:
247
+
- **New rows** (in spec but not in DB) are inserted.
248
+
- **Changed rows** (different values for same unique key) are updated.
249
+
- **Removed rows** (in DB but not in spec) are deleted.
250
+
251
+
**Requirements:**
252
+
- Every table in a reconciled seed set must have a `unique_key`. Without it, there is no way to identify which rows correspond to which spec entries.
253
+
- Environment variable changes trigger reconciliation (resolved values are compared, not raw templates).
254
+
255
+
**Row tracking:** Initium creates a companion table (`{tracking_table}_rows`, e.g., `initium_seed_rows`) that stores the resolved values of each seeded row. This enables change detection and orphan deletion.
256
+
257
+
**Dry-run mode:** Preview what reconciliation would do without modifying the database:
258
+
259
+
```bash
260
+
initium seed --spec /seeds/seed.yaml --dry-run
261
+
```
262
+
263
+
This logs insert/update/delete counts per table without executing any changes.
264
+
216
265
### Reset Mode
217
266
218
267
Use `--reset` to delete all data from seeded tables and remove tracking entries before re-applying. Tables are deleted in reverse order to respect foreign key constraints:
0 commit comments