Skip to content

All versions since 4.2.0

4.2.0

Added

  • Data-hazard detection. plan and apply (via NSchema.Core 4.2.0) now flag changes that are valid against the schema but can fail on the data already in a table.

4.3.0

Added

  • Data migrations. A MIGRATION ['name'] FOR <trigger> <schema>.<table>.<member> AS $$…$$; block (via NSchema.Core 4.3.0) attaches raw SQL to an ADD COLUMN, ALTER COLUMN TYPE, or ADD CONSTRAINT change and runs only when that change is in the plan. A required column add with a matching block is applied as add-nullable → backfill → SET NOT NULL, a matching block silences the corresponding data-hazard warning, and a block matching nothing is reported as safe to delete. The plan output gains a “Data migrations” section (dataMigrations in --json). Executing a plan with a matched block requires a provider plugin at 4.3 or later.

Changed

  • The import command now writes the per-schema header to <schema>/schema.sql instead of <schema>.sql.

Fixed

  • The nschema lock release command suggested by lock status and lock acquire now carries the --environment and --directory arguments of the current invocation.
  • The diff now shows an added or removed column’s default expression and identity marker.
  • DDL syntax errors now name the file the error was found in, alongside the existing line and column.
  • The import command no longer repeats the CREATE SCHEMA statement in every object file; only the per-schema header declares the schema.

4.4.0

Added

  • Unified SCRIPT statement (via NSchema.Core 4.4.0). SCRIPT '<name>' RUN [ALWAYS | ONCE] ON <event> AS $$…$$; is the new canonical form of deployment scripts and data migrations: the event is PRE DEPLOYMENT, POST DEPLOYMENT, or a structural change (ADD COLUMN / ALTER COLUMN TYPE / ADD CONSTRAINT with a target path).
  • Run-once scripts. A RUN ONCE script is recorded in the state backend on a successful apply and skipped by later plans; a recorded script whose body has since changed stays skipped and warns. Plan output marks run-once scripts in the pre/post-deployment sections ((run once); runCondition in --json). Recording requires a state backend — planning without one warns.
  • Scripts in schema templates. Both script kinds can be declared inside a TEMPLATE … BEGIN … END; body and instantiate once per applied schema, with the {schema} token substituted in the name and the SQL.

Changed

  • Script names must be unique across the project (they identify scripts in diagnostics and run-once tracking); a template-declared script applied to multiple schemas can include {schema} in its name.

Deprecated

  • The PRE|POST DEPLOYMENT '<name>' AS $$…$$; and MIGRATION ['name'] FOR <trigger> <path> AS $$…$$; forms still work, but plan/apply/validate now surface a deprecations warning naming the SCRIPT replacement. They will be removed in NSchema 5.0.

4.5.0 Latest

Added

  • refresh --force refresh fails if it finds an unreadable state payload, instead of silently overwriting it; --force replaces it, resetting the script ledger.
  • state pull [file] to pull the raw recorded state payload out of the configured backend. Writes to a file or stdout.
  • state push <file> to push the raw recorded state payload into the configured backend. Push takes the state lock (--no-lock to skip).
  • script command group to manage the scripts recorded in the state:
    • script list shows the recorded scripts (name, execution time, body hash); --json emits them as a single array.
    • script hash [name] computes the body hash of the project’s script declarations, bare on stdout for one script, or a listing of all of them, for hand-editing pulled state.
    • script taint <name> removes a script’s record, so it runs again on the next apply.
    • script untaint <name> records a script as executed without running it, using the body hash from the script’s declaration. Taint and untaint take the state lock (--no-lock to skip).