Pulling schema changes into the model
bluep pull brings the schema of a source into a model's physical target and, by default, into the logical
layer too. The source is a live database (read through its command-line client), a DDL script, or a target of
another model directory. Nothing is written until you accept a plan.
Workflow
Produce a plan:
bluep pull my-model --target pg --from-db --database shop --plan plan.jsonor compare with another model directory or a DDL script:
bluep pull my-model --target pg --from-dir ../other-model --plan plan.json bluep pull my-model --target pg --from-ddl schema.sql --plan plan.jsonWithout
--planthe plan is printed with markers and the command exits 1 when there is anything to pull:[x] + column public.payment.refund_at [ ] - column public.order_line.qty [x] + column public.order_line.quantity [?] ? rename public.order_line.qty -> public.order_line.quantity (same type and nullability) plan: 3 changes (1 destructive), 1 rename candidates[x]items are applied,[ ]items are listed but skipped,[?]lines are rename candidates.Review the plan file. Every item has
"apply": true|false; flip the ones you want. Items marked"destructive": true(drops and type changes) start asfalseunless you pass--allow-destructive.Apply it:
bluep pull my-model --apply plan.jsonThe output names the files that changed:
applied 3, skipped 1; changed files: model.bluep--yesperforms both steps at once.
What applying does
Changes are applied to the named target and then propagated to entities, attributes, keys and relationships:
- a new table becomes a new entity (or is mapped to an existing entity with the same name);
- a new column becomes a new attribute of the mapped entity, placed next to its neighbours;
- a dropped column removes its attribute when no other table maps it;
- a type or nullability change updates the attribute, unless the attribute uses a domain;
- renames rename the mapped entity or attribute when the names were equal;
- a new foreign key becomes a relationship named after the key (without the
fk_prefix); - a dropped foreign key removes its relationship when no other key maps it.
Pass --no-logical to change only the physical target.
The model is validated after applying; if the result would be invalid nothing is written and the first problem is reported.
Minimal edits
Only the declarations that changed are rewritten, in canonical form. Every other declaration keeps its exact
bytes, including non-canonical spacing or extra blank lines, so a pull produces a small, reviewable diff in git.
New declarations are appended to the file that owns their kind of object (the main file when in doubt).
Run bluep fmt afterwards if you want the whole model in canonical form.
Options
| Option | Effect |
|---|---|
--target <name> |
the target of the model to compare and update |
--from-db --database <d> [--dialect --host --port --user --schema --option] |
live database source |
--from-ddl <file> [--dialect <id>] |
DDL script source |
--from-dir <dir> [--from-target <name>] |
another model directory |
--plan <file> |
write the plan as JSON |
--apply <file> |
apply a plan file |
--yes |
plan and apply in one step |
--allow-destructive |
also apply drops and type changes |
--no-logical |
do not touch entities and attributes |
--accept-renames |
treat rename candidates as renames |
--ignore-comments |
ignore comment differences |
Exit codes: 0 nothing to do or applied; 1 the printed plan has changes; 2 usage error; 3 any other error.