Creating Migration Scripts

A script is the atomic, versioned, content-hashed unit of change. This page covers authorship, the target-resolution model, type classification, versioning semantics, and dependency declaration.

Authorship Paths

Upload or paste

On Migration Scripts, choose Upload Script. Upload Files takes SQL (.sql, .ddl, .dml), MongoDB (.js), Cassandra (.cql), Neo4j (.cypher, .cyp), Redis (.redis) and Elasticsearch (.json) files; any other file is refused with its name. Paste Script takes a name and the script; the panel shows which engine the script is for as you type.

Pull from provider

With a configured repository/storage source, open it under Repo Sources and choose Pull Scripts; every file under the source's path (including subfolders) that matches its patterns is imported as a Pending script named by its path inside the pulled folder, in the environment you choose (and on the instance and database you choose, if any). Providers: GitHub, GitLab, Bitbucket, Azure DevOps, S3, Azure Blob, GCS, Dropbox. See Environments & Repository Sources.

Choosing the Target

Every uploaded or pasted script is for one environment, and its target is an instance in that environment:

  1. Environment lists the environments that exist (Environments page). A script is saved under the environment's own name.
  2. Instance lists only the instances in that environment, and only those of the script's engine: a Redis script is offered Redis instances, a SQL script SQL instances. When there are none, the list says so, for example No Redis instances in Staging. Connections that are not in any environment are not offered; add them to an environment first.
  3. Database lists the databases on that instance, read through its engine: PostgreSQL, CockroachDB and TimescaleDB databases, MySQL and MariaDB schemas, SQL Server databases, MongoDB databases, Oracle open pluggable databases (or the connected service), Redis numbered databases with their key counts, and SQLite's main database. System databases are listed apart. Engines without a list of databases (Cassandra, Neo4j, Elasticsearch, ClickHouse) say so, and their scripts run against the database set on the connection. If the instance cannot be reached the reason is shown with Retry.

Changing the environment clears the instance and database. When the chosen instance lists the database set on its connection, that database is chosen for you. The same picker is used when you edit a script: choosing an instance there picks its database the same way, and opening the editor leaves the saved database as it is.

A script's instance is always in the script's environment. If a connection is later moved to another environment, the scripts that target it keep theirs, so they no longer agree: the script's card reads Instance is in Staging (hover it for the details), and its detail and editor say, for example, Demo PostgreSQL (Pagila) is in Staging, not Development: choose an instance in Development, or set the script's environment to Staging. Changing the script's environment or instance is refused until the two agree; other edits are not held up.

Author-Set Properties

PropertyRequiredNotes
NameYesShown exactly as written, up to 500 characters, e.g. alter-orders-add-status-column. A file's name without its extension.
ContentYesThe script; up to 5 MB.
TypeYesRelease (promotes through environments in a release) or Ad-hoc (runs on its own).
EnvironmentYesAn environment that exists. Scripts pulled from a repository source have none until edited.
InstanceWhen uploadingAn instance in the environment, of the script's engine.
DatabaseWhen the instance lists databasesA database on that instance.
DependenciesNoScripts that must complete a run first.

Each card on Migration Scripts shows the script's name, approval status and where it runs (instance / database · environment), with its version, author and creation date. A note on the card says when the script's instance is in another environment, and why that matters. Opening a card shows its version, author, creation date, environment and target. The list can be filtered by status, environment and type.

Editing a Script

Open a script and choose Edit. The editor shows the version, author, creation time and status, then the same fields as uploading: Dependencies (Optional) with a search box (each chosen script appears as a chip; select the chip to remove it), Script Configuration (Type, Environment and, for a Release script, the release) and Target (Instance and Database). Saved values show with a pencil button; select it to change the value. Below them is the Script with its character and line count. Save Changes stores the script and shows Script saved; changing the SQL of an approved script returns it to Pending.

Compare with Target

Compare with Target puts the script next to the current definition of the object it changes, read from a live instance:

EngineObject types
PostgreSQL, CockroachDB, TimescaleDB, Redshift, Aurora PostgreSQL, YugabyteDBTable, View, Function, Procedure, Sequence
MySQL, MariaDB, Aurora MySQL, TiDB, SQL ServerTable, View, Function, Procedure
OracleTable, View, Function, Procedure, Package, Sequence
SQLiteTable, View, Index, Trigger
ClickHouseTable, View, Dictionary

Scripts for MongoDB, Redis, Cassandra, Neo4j and Elasticsearch have no object definitions, so the editor does not offer Compare with Target for them.

System-Managed Properties

PropertySemantics
Approval StatusPending → Approved | Rejected; a rejected script returns to Pending when resubmitted, and an approved one when its SQL or rollback SQL changes or its approval is revoked. Moves to Approved or Rejected only through the Approve / Reject actions; it cannot be set by creating or editing a script.
VersionInteger, starts at 1, increments on every content edit.
Content HashSHA-256 of content; binds reviewed bytes to executed bytes and gates approval invalidation.
Created / Updated At, Created ByProvenance timestamps and author.

Edit Semantics & Approval Invalidation

Changing the SQL or the rollback SQL of an approved script returns it to Pending: the approval covered what was reviewed, including the rollback that rolling back one of its runs executes, so the new version needs approval again. Any signed-off release that contains the script also returns to Pending and must be signed off again before it runs. Changes that leave the SQL and rollback SQL as they were (name, description, target) keep the approval.

Edits are validated by the same rules as a create: the name length limit, the maximum SQL content size, and the allowed execution-mode values all apply, and an edit that breaks any of them is refused with the reason rather than saved partially. An edit cannot change approval status. An update request whose approval status differs from the script's stored status is refused with 400 Bad Request and the error Approval status changes only through approve or reject. An update that sends back the stored status unchanged, as the edit form does, is accepted. Status changes only through Approve or Reject, so every decision passes the separation-of-duties check and lands in the audit log.

A request that addresses a script by a malformed identifier returns 404 Not Found, the same response as a script that does not exist.

Delete removes a script only after the server confirms it. A refused delete, for example while a release, execution, or approval still references the script, or when your role cannot delete scripts, keeps the script in place and shows the reason.

A script cannot be deleted while a release contains it, an execution ran it, or an approval request exists for it. Such a delete is refused with that reason and nothing is removed. To delete a script that belongs to a release, remove it from its releases first. Scripts with run or approval history are kept for audit and cannot be deleted.

Pre-flight Checks

A script can guard itself with lines like -- @check no_null_emails: (SELECT count(*) FROM users WHERE email IS NULL) = 0. Each time the script runs, alone or in a release, its checks are evaluated read-only first, and the script does not run if one fails. See Schema Ops → Pre-flight Checks for the format and the supported engines.

Dependencies

Declaring "B depends on A" means A must complete successfully before B runs. Dependencies are added via search and shown as removable badges, and each must be an existing script listed once.

Cycle Detection

Saving a script whose dependencies would form a loop (A→B→C→A) is refused, and the message shows the loop.

Canonical patterns

Authoring Discipline

Lifecycle

  1. Create, author content + properties. Status: Pending, revision 1.
  2. Request Approval, open an approval request for the current SQL. The script stays Pending.
  3. Review, reviewer decides. Status: Approved | Rejected.
  4. Resubmit (if rejected), edit (a change to the SQL or the rollback SQL moves the script to its next revision), then back to Pending.
  5. Compose, add scripts to a release; the release can be signed off once every script is approved.
  6. Execute, run against the resolved target; each run is recorded under Executions. The script stays Approved. A release script runs only once it is approved; an ad-hoc script can also run before approval, except against a connection in an environment that requires approval.