Database migrations and warmup order¶
The invariant: only Raklet.Backend migrates the databases¶
Raklet.Backend's OWIN Startup.Configuration is the only place that applies
EF migrations. It runs MigrateDatabaseToLatestVersion and an eager
Database.Initialize(true) for each context, in this order:
RakletEmailContext(RakletEmail DB)RakletSmsContext(RakletSms DB)RakletDb(RakletV3 DB)
Every other web app — Application (v3 portal), Raklet.Login, Raklet.Admin,
Raklet.Api — calls Database.SetInitializer<RakletDb>(null) in its own Startup
and never migrates. They assume the schema is already current.
Consequence: until backend has started and completed migration against an
environment's databases, the schema lags the compiled EF model. Any app that then
writes through EF fails on the missing columns.
Failure signature¶
A write fails with EF6's generic message:
An error occurred while executing the command definition. See the inner exception for details.
The inner exception is almost always Invalid column name '<X>'. It means the
compiled model expects a column/table that a pending migration would create but
that hasn't been applied. Example seen in the wild: organisation creation on
login.raklet.org threw this because Announcements.AnnouncementType (added by
Models/Migrations/...AddPools) was missing — RakletDb was 3 migrations behind.
Why warmup must hit backend first¶
Because backend is the sole migrator, a warmup that recycles the
schema-dependent apps (v3/login/admin/api/crm) before backend migrates will
serve new code against an un-migrated DB → the error above. So both warmup scripts
warm backend first and abort if it can't start/migrate, instead of soft-warning
and warming the rest:
scripts/dev/pin-canonical-hosts.ps1— canonical*.raklet.orgIIS sites.scripts/dev/create-branch-preview.ps1— per-branch preview hosts.
The Azure deploy warmup (Deployment.Scripts/WarmUpTest.ps1 /
WarmUpDev.ps1) already lists backend first for the same reason.
If
backenditself 500s on warmup, fix that first — nothing downstream works until it can migrate. Do not "warm around" it.
Diagnosing a schema gap¶
Compare each context's applied migrations against the migration classes in the
code. For RakletDb (catalog RakletV3):
SELECT TOP 5 MigrationId
FROM dbo.__MigrationHistory
WHERE ContextKey LIKE '%Models.Migrations.Configuration%'
ORDER BY MigrationId DESC;
Compare the newest MigrationId to the newest file under Models/Migrations/
(RakletDb), Raklet.Email/Migrations/ (RakletEmail), or Raklet.Sms/Migrations/
(RakletSms). Any code migration newer than the newest history row is pending.
When backend is wedged on an earlier context¶
backend migrates RakletEmail → RakletSms → RakletDb in order, so a failure on an
earlier context blocks every later one. A common wedge is:
There is already an object named '<Table>' in the database.
This happens when the table exists but has no __MigrationHistory row for the
migration that creates it — so the migrator tries to CreateTable over an existing
table and throws. Tests that create tables out-of-band against a shared DB are a
typical source.
Reconciling an "already exists" migration (non-destructive)¶
If the existing table already matches the migration's definition, mark the migration applied instead of dropping data:
- Verify the live table matches the migration's columns, PK, indexes, and FKs
(
sys.columns/sys.indexes/sys.foreign_keys). If it does not match, stop — fix the schema first. - Insert the missing history row so EF skips the
CreateTable. TheModelblob is the migration's ownTargetresource from its*.Designer.resx(base64 →varbinary);ContextKeyandProductVersioncome from an existing row in that DB's__MigrationHistory. Run withSET QUOTED_IDENTIFIER ON(the XMLvalue()decode requires it). - Recycle the
backendapp pool and warmhttps://backend.raklet.org/soStartupre-runs and continues to the later contexts (RakletSms, RakletDb). - Re-check
__MigrationHistoryand the previously-missing columns/tables.
Dropping and recreating the table also works but loses any rows; prefer the history-row reconcile when the data matters.
Related¶
docs/agents/iis-worktree-branch-previews.md— the preview workflow whose warmup this ordering protects.