Skip to content

Migrations (PRO) ​

Create a table and get its migration and model from the manager, without opening an editor.

PageBlocks → Constructor → Migrations.

sudo only

The tab writes files into core/App/ and runs migrations against the live database, so it is closed to everyone but an administrator. A content editor has no business here.

What you get ​

One row turns into three things:

  1. a Phinx migration file in core/App/Database/migrations/;
  2. once executed, core/App/Models/Base<Model>.php, built from the table's real columns;
  3. core/App/Models/<Model>.php — only if it does not exist yet.

The split matters: the base class is regenerated on every run, the child is written once and never touched again. Your methods, relations and casts live in the child.

Never edit the base model

It is silently overwritten by the next migration on that table.

The list ​

ColumnWhat it shows
NameThe human name, shown in the list
Table, ModelWhat it applies to. An empty model means "migration only"
TypeWhat the migration does
StatusPending, Executed, Rolled back or Failed
ExecutedWhen it was applied

Creating one ​

SettingWhat it does
NameFor the list. Required
Table nameNo prefix, lower case and underscores. Required
Model nameFilled in from the table name. Empty means no model is generated
Type"Create table" by default
Constructor fieldsAdds data, menuindex, published_at and the rest of the tail
Timestampscreated_at and updated_at
Soft deletesdeleted_at

All three boxes are ticked by default: a table created here is immediately ready for publishing, ordering, the recycle bin and constructor fields.

Ten types: create and drop a table, add, change, drop and rename a column, add and drop an index, add and drop a foreign key.

Columns are described in a child grid — type, length, precision, nullable, unsigned, default, comment, after, and an index with its kind (index, unique, fulltext). Foreign keys get their own grid, with on_delete and on_update.

Executing and rolling back ​

Execute writes the migration file, runs Phinx over the site layer and then generates the model. The status becomes Executed.

Roll back is allowed only for an executed migration — anything else answers 405. The execution log is kept and opens from the view button, including for a failed migration: that is the first place to look when something did not work.

A rollback undoes the change, not the data

Rolling back "drop column" brings the column back, not what was in it. Take a dump before a destructive migration on a live site — the component does not take one for you.

The table's current shape is not read from the database schema but recomputed from every executed migration for that table. That is how add_column knows what the table already has.

Model files survive a dropped table

drop_table deliberately leaves core/App/Models/ alone. Dropping a table is a decision about the schema; deleting your model along with everything you wrote in it is not the constructor's call.

When two migrations collide ​

Two rows saying "add a column to pb_cargo" would want the same class name. Names are disambiguated against the existing files, so the second migration on a table does not overwrite the first.

The unapplied migrations banner ​

Migration files can sit on disk without ever having reached the database. When that happens the component puts a banner on every one of its own manager pages, so that a half-finished install stops looking like a successful one.

The comparing is done by Database/PendingMigrations: the Phinx migration files on disk against the rows in the Phinx log tables. Four independent sets are checked.

SetPhinx configLog tableSeverity
PageBlockscore/components/pageblocks/src/phinx.phppb_migrationsred (error)
pbShopcore/components/pbshop/src/phinx.phppb_shop_migrationsred (error)
Repositorycore/components/repository/src/phinx.phprepository_migrationsred (error)
The site's own core/Appcore/App/phinx.phppb_app_migrationsyellow (info)

A set whose migrations directory does not exist is skipped without a word — that only means the satellite is not installed.

Two states are told apart: the log table is not there at all, meaning migrations were never run; and the log table is there, but some migrations are unapplied.

The banner lists the first five pending versions and then +N for the remainder, and it states the exact command to run:

bash
php core/components/pageblocks/vendor/bin/phinx migrate --configuration=<config> --environment=production

Why the site's own migrations are yellow rather than red

The packages' migrations are supposed to have been applied by the package installer, so a pending one means the installation failed — that is an error. The site's own core/App migrations are run by hand or by CI, so a pending one is a normal working state, not a fault.

The banner is the real guarantee, not a nicety

xPDO ignores a package resolver's return value, so the MODX package installer can report a successful install even when the migrations inside it failed. The banner is what actually tells you.

Where it writes ​

Into the site layer only, never into the component. Hence its safety: a component update cannot overwrite what was generated, and what was generated cannot travel into someone else's installation.

To write a migration by hand see Migrations; for what the generated model can do, Models.

© PageBlocks 2019-present