Safe EF Core Migrations workflow for FinanceHub PostgreSQL databases, covering migration creation, SQL script generation and validation, zero-downtime schema updates, lock timeout safety, and rollback procedures.
55
61%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/postgres-migration/SKILL.mdThis guide establishes the mandatory workflow for schema modifications in FinanceHub using EF Core 9/10 and PostgreSQL (Npgsql). Each microservice in FinanceHub manages its own PostgreSQL database under Database-per-Service isolation. Financial data safety, zero-downtime operations, and deterministic rollbacks are non-negotiable.
FinanceHub.AuthConsent or FinanceHub.TransactionAggregator). Cross-service database modifications are strictly prohibited.ACCESS EXCLUSIVE) for long periods.IF NOT EXISTS).Run migration commands targeting the specific microservice project (e.g., src/Services/FinanceHub.TransactionAggregator):
dotnet ef migrations add <MigrationName> \
--project src/Services/FinanceHub.TransactionAggregator \
--startup-project src/Services/FinanceHub.TransactionAggregator \
--output-dir MigrationsName migrations with action and subject in PascalCase:
AddReconciliationBatchesTableAddTransactionHashUnicoIndexMakeAccountMetadataNullableBefore applying migrations, generate the idempotent SQL script:
dotnet ef migrations script \
--project src/Services/FinanceHub.TransactionAggregator \
--startup-project src/Services/FinanceHub.TransactionAggregator \
--idempotent \
--output bin/migrations/<MigrationName>.sqlSET lock_timeout = '5s';NULL or with DEFAULT (PostgreSQL 11+ metadata-only)?CREATE INDEX CONCURRENTLY?CONCURRENTLY)Standard CREATE INDEX acquires a SHARE lock blocking concurrent writes (INSERT, UPDATE, DELETE). Always use concurrent index creation.
EF Core Builder Annotation:
builder.Entity<Transaction>()
.HasIndex(t => new { t.AccountId, t.TransactionDate })
.HasDatabaseName("IX_Transactions_AccountId_TransactionDate")
.IsCreatedConcurrently();Generated SQL Verification:
CREATE INDEX CONCURRENTLY IF NOT EXISTS "IX_Transactions_AccountId_TransactionDate"
ON "Transactions" ("AccountId", "TransactionDate");Note:
CREATE INDEX CONCURRENTLYcannot run inside a multi-statement transaction block. Ensure EF Core migration marks transaction usage appropriately or manually splits DDL steps.
NULLABLE.NOT NULL constraint once 100% of rows are populated.dotnet ef database update \
--project src/Services/FinanceHub.TransactionAggregator \
--startup-project src/Services/FinanceHub.TransactionAggregatorUse dotnet ef migration bundles to compile standalone deployment binaries per microservice:
# Build standalone migration executable bundle
dotnet ef migrations bundle \
--project src/Services/FinanceHub.TransactionAggregator \
--startup-project src/Services/FinanceHub.TransactionAggregator \
--output bin/efbundle \
--self-contained -r linux-x64
# Execute in production deployment pipeline for target microservice database:
./bin/efbundle --connection "$TRANSACTION_AGGREGATOR_DB_CONNECTION"Every schema change must have a tested, verified rollback strategy.
dotnet ef database update <PreviousMigrationName> \
--project src/Services/FinanceHub.TransactionAggregator \
--startup-project src/Services/FinanceHub.TransactionAggregatordotnet ef migrations script <TargetMigrationName> <PreviousMigrationName> \
--project src/Services/FinanceHub.TransactionAggregator \
--startup-project src/Services/FinanceHub.TransactionAggregator \
--output bin/migrations/rollback_<TargetMigrationName>.sqllock_timeout expires during execution, do NOT force locks without checking long-running queries in pg_stat_activity.SELECT indexrelname, indisvalid FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
WHERE indisvalid = false;a8dbf2a
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.