>
dbwarden
/ tool scope / safety

Database Migration Safety
& Impact Analysis.

Destructive intent is visible before the file reaches review. Operations are classified, the application is scanned for references, and risky changes stop for explicit consent. Impact analysis is one of the features that makes dbwarden meaningfully different from a simple migration runner.

Operations are classified before they run.

The classifier reads the migration plan before any SQL executes and grades every operation. The rule is simple: dbwarden does not silently drop data. INFO operations are expected-safe schema additions; WARNING operations need review and will not pass check without acknowledgement; ERROR operations are destructive or ambiguous and fail the check outright.

dbwarden check inspects the pending plan and reports the classification. --force is an acknowledgement, not a bypass: it records that a human reviewed the classified plan and accepted the risk, which is why it should not be a default in CI. The classification is written to the .plan.json next to the generated migration, so the intent sits in the file a reviewer opens, not in a plan only the generator reads.

the severity model
INFO      expected safe: create table, add nullable column
WARNING   needs review: SET NOT NULL, type change
ERROR     blocked: DROP TABLE, DROP COLUMN, lossy engine change
What makes an operation ERROR?

Anything destructive or ambiguous: dropping a table or column, renaming without explicit intent, or a lossy engine change. It fails the safety check until an operator acknowledges it explicitly.

What does the force flag do?

It records that a human reviewed the classified plan and accepted the risk. It is an acknowledgement, not a bypass, and should not be a default in CI.

What code would a destructive change break?

Schema changes are the highest-risk operation in most deployments: dropping a column that application code still references causes runtime errors, and changing a type can break queries. check-impact finds the code that would break before the change ships.

It scans your application code, not just the migration files, for references to objects a destructive change would remove, a column, a table, an index. The scan uses AST analysis with a grep fallback, so it catches attribute access in Python (user.username) and string matches in templates alike, and reports each hit with the access pattern, the file, and the line number, grouped by change type.

Schema safety and application safety come from the same command, so there is no separate step to forget.

the scan output
$ dbwarden check-impact

drop_column on users.username
  References: 2
    app/routes/users.py:34  attribute_access
    app/templates/profile.jinja2:12  grep
Does safety cover application code?

Yes, with check-impact. It scans Python files and templates for references to objects a destructive change would remove, so schema and application safety are reviewed together.

How does check-impact find references?

AST analysis with a grep fallback. It reports each hit with the access pattern: attribute access in Python, grep match in templates, plus the file and line number.

The multi-step path, generated.

Changing a column type is where ALTER COLUMN TYPE can lock a table for the duration of a rewrite. --safe-type-change expands the change into the boring multi-step sequence instead: add a temporary column, a data migration comment, a verification step, then a swap and drop, the same sequence a careful engineer would write by hand, generated as reviewable SQL like any other migration.

Related flags tune the same operation for the backend: --postgres-auto-using emits an active USING col::newtype clause on the ALTER COLUMN TYPE instead of a commented-out line for manual review, and PostgreSQL index creation defaults to --concurrent, with --no-concurrent for migrations that run inside a transaction block.

the flag
$ dbwarden make-migrations "widen bio" --safe-type-change
What does --safe-type-change generate?

The full multi-step sequence as reviewable SQL: add the new column, backfill it from the old one, swap, then drop. Each step is a normal migration artifact with its own classification.

Where does the classification come from?

make-migrations writes a companion .plan.json next to the generated SQL with the typed operations. The safety check inspects that plan before the SQL is applied.