Adding or changing a field

Adding or changing a field normally requires updates to:

  1. The domain model and all constructors/usages
  2. The SeaORM entity in the domain object's db.rs
  3. A new migration under src/leicmin/src/data/migrations/
  4. Queries, services, seeds, and tests that depend on the field

The entity and migration must agree on the field's PostgreSQL type, nullability, default, enum type, index, and constraints.

Adding a column safely

For an existing table, use an additive deployment sequence:

  1. Add the entity field as nullable, or add it with a safe constant default
  2. Deploy the migration and backfill existing rows when necessary
  3. Update application writes and reads to handle both old and new rows
  4. Verify the backfill and only then enforce NOT NULL or remove a temporary default in a later migration

For large tables, consider lock duration and batch the backfill. Do not add a NOT NULL column without a default to a populated table.

Example for a constant default:

manager
    .alter_table(
        Table::alter()
            .table(Widgets::Table)
            .add_column_if_not_exists(
                ColumnDef::new(Widgets::Enabled)
                    .boolean()
                    .not_null()
                    .default(false),
            )
            .to_owned(),
    )
    .await?;

Use add_column_if_not_exists only when accepting an already-present, compatible column is safe. It does not verify that an existing column has the correct definition.

Renaming, removing, or changing types

Do not combine a destructive rename or type change with an application release that still expects the old shape. Prefer a compatibility sequence:

  1. Add the replacement column or structure
  2. Backfill it from the old value
  3. Deploy code that reads/writes the compatible representation
  4. Remove the old column in a later migration after all callers are updated

Dropping or rewriting data requires an explicit data-loss review. Do not use a blind cast or overwrite existing values without checking the data first.

Enums and PostgreSQL-specific operations

Use guarded execute_unprepared SQL for PostgreSQL enum changes or other operations SeaORM cannot express. Check pg_enum before adding or renaming a value. PostgreSQL generally cannot remove enum values, so document the limitation and leave the value in place in down.

Metadata

Project

Forges