5.2. Model Deployment

OrmFactory lets you use a database model as the source of truth and deploy model changes to live databases through CI/CD.

A typical workflow looks like this:

  1. Modify the database model.
  2. Commit and push the project to Git.
  3. CI runs ormfactory check against the target database.
  4. Review the generated report and resolve any operations requiring confirmation.
  5. Approve and merge the change.
  6. CI runs ormfactory deploy against the target database.

OrmFactory compares the model with the actual target database and generates the required database changes at deployment time. You do not need to maintain migration scripts manually.

Both commands operate on one database per invocation.

Commands

ormfactory check

Compares the model with the target database and generates a report. The database is not modified.

ormfactory deploy

Compares the model with the target database and applies the resulting changes.

Both commands validate the planned changes. A successful check does not guarantee that a later deployment will succeed: the database may change between the check and the deployment, or a database operation may fail during execution.

Configuration

--project=<path>

Path to the OrmFactory project file. This can be a .ormfactory file or a .0fproj project file.

--database=<name>

Selects the database defined in the project.

If the project contains exactly one database, it is selected automatically. If the project contains multiple databases, specify --database.

Each invocation targets one database. To deploy multiple databases, run separate commands for each database.

Connection

The target database connection can be specified using one of the following options:

  • --connection=<name>
    Uses a connection defined in the project.

  • --connection-string=<connection-string>
    Uses the specified connection string directly.

  • --connection-env=<variable>
    Reads the connection string from the specified environment variable.

Exactly one connection option must be specified.

The connection must be compatible with the database type selected for deployment.

For CI/CD environments, --connection-env allows connection credentials to be supplied through environment variables rather than stored in the project or written directly in the command.

Password override

--password=<password>

Overrides the password for a connection selected using --connection.

Use this option only when necessary. For automated deployments, prefer an environment variable containing the complete connection string when supported by your database provider.

Change validation

check compares the current model with the target database and attempts to construct the required database changes.

The report identifies changes such as:

  • Creating tables and columns.
  • Modifying existing columns.
  • Renaming tables and columns.
  • Dropping tables and columns.
  • Creating or modifying indexes and constraints.
  • Other supported schema changes.

Changes are not considered errors by themselves. However, certain destructive operations require explicit confirmation before deployment.

Including generated DDL

--include-ddl

Includes the generated DDL statements in the check report. The database is not modified.

Operations requiring confirmation

Dropping tables and columns requires confirmation by default. This applies to both check and deploy.

The report identifies these operations and provides example hints that can be added to the project. A confirmed drop is allowed to proceed.

The following options allow the corresponding operations without requiring individual confirmation. They can be used with either command:

  • --allow_drop_table allows table drops.
  • --allow_drop_column allows column drops.

For example:

ormfactory check \
  --project=model.0fproj \
  --connection-env=DATABASE_URL \
  --allow_drop_column

These options affect the specified invocation. Use them only when the corresponding destructive changes are intended.

If the check detects operations requiring confirmation, it exits with code 2 and outputs the full report, including the operations and suggested hints. The database is not modified.

Migration hints

OrmFactory compares the model with the actual database, but the difference alone does not always reveal the intended operation.

For example, if a column disappears from the model and another column appears, the intended change might be a rename rather than a drop followed by a creation.

Migration hints provide explicit information about the intended operation. They can also be used to exclude tables that exist in the database but are not part of the OrmFactory model, such as log, audit, or other application-managed tables.

Hints are stored separately for each model database in its hints directory.

Hints require the directory project format (.0fproj). They are not supported by single-file .ormfactory projects.

Hint storage

For a directory project:

project/
    project.0fproj
    users.database/
        ...
        hints/
            2026-10-02_09-13-12_Removed_columns.hint
            2026-10-03_08-21-55_Renamed_columns.hint

Hint files are regular text files and can be committed to source control.

Hint files are ordered by their UTC timestamps. This preserves the order of changes made to the same object. Hint files with the same timestamp have no defined order.

The order of elements inside a hint file is not significant.

Hint format

Hint files use the OrmFactory XML format:

<?xml version="1.0" encoding="utf-8"?>
<Hints>
    <RenameTable Name="erp.users" NewName="customers" />
    <RenameColumn Name="erp.users.name" NewName="surname" />

    <DropTable Name="erp.legacy_users" />
    <DropColumn Name="erp.users.old_name" />

    <IgnoreTable Name="erp.audit_log" />
</Hints>

The following hint types are supported:

Hint Description
RenameTable Identifies a table rename.
RenameColumn Identifies a column rename.
DropTable Confirms that a table should be removed.
DropColumn Confirms that a column should be removed.
IgnoreTable Excludes a database table from model synchronization and deployment.

Name identifies the existing object. NewName specifies the new name for rename hints.

Table names use the following format:

Schema.Table

Column names use:

Schema.Table.Column

Applying hints

When an operation requires confirmation, the report provides an example hint and the suggested file path. Add the required hint to a .hint file in the database's hints directory and commit it to source control.

Hints are persistent project information. They are not automatically deleted after deployment because the same information may be needed when deploying to another environment whose database is at a different stage.

When hints are no longer needed by any supported environment, they can be removed manually.

Deploy

deploy validates the current model against the target database and then executes the resulting database changes.

The database is read again when deploy runs. A previous successful check does not replace this validation because the database may have changed since the check.

ormfactory deploy \
  --project=model.0fproj \
  --connection-env=DATABASE_URL

If operations requiring confirmation are detected, deployment stops before executing the changes and exits with code 2.

Generating DDL without execution

--ddl-only

Generates and outputs the DDL statements without executing them against the database.

The command still validates the planned changes. If unconfirmed table or column drops are detected, it stops and exits with code 2 instead of outputting the DDL.

Deployment reports

During deployment, OrmFactory reports the DDL commands being executed and whether each command succeeded.

If a DDL command fails, the report includes the command and the database error. The process exits with code 3.

A failed deployment does not necessarily mean that no changes were applied. Commands executed before the failure may already have modified the database, depending on the database provider and transaction behavior.

Review the report and the actual database state before retrying a failed deployment.

Exit codes

Exit code Meaning
0 The command completed successfully.
1 An argument, configuration, or other CLI error occurred.
2 Unconfirmed table or column drops were detected.
3 A DDL command failed during deployment.
130 The operation was cancelled by the user.

When operations require confirmation, the complete report is written to standard output. When a DDL command fails, the deployment report includes the failed command and its error message.

CI/CD

A typical CI/CD workflow checks the model before merging and deploys it after approval.

Each invocation targets one database. Projects containing multiple databases can run separate jobs for each target database.

GitHub Actions

name: Database Deployment

on:
  push:
    branches: [main]
  pull_request:

jobs:
  check:
    runs-on: ubuntu-latest
    container:
      image: ormfactory/cli:latest
    steps:
      - uses: actions/checkout@v4
      - name: Check database
        run: ormfactory check --project=model.0fproj --connection-env=DATABASE_URL
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

  deploy:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    needs: check
    runs-on: ubuntu-latest
    environment: production
    container:
      image: ormfactory/cli:latest
    steps:
      - uses: actions/checkout@v4
      - name: Deploy database changes
        run: ormfactory deploy --project=model.0fproj --connection-env=DATABASE_URL
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

Configure the production environment with the required deployment approval rules and secrets.

Jenkins

pipeline {
    agent any

    stages {
        stage('Check') {
            steps {
                withCredentials([string(
                    credentialsId: 'database-url',
                    variable: 'DATABASE_URL'
                )]) {
                    sh '''
                        docker run --rm \
                            -e DATABASE_URL \
                            -v "$WORKSPACE:/work" \
                            -w /work \
                            ormfactory/cli:latest \
                            check --project=model.0fproj \
                            --connection-env=DATABASE_URL
                    '''
                }
            }
        }

        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                input message: 'Deploy database changes?'

                withCredentials([string(
                    credentialsId: 'database-url',
                    variable: 'DATABASE_URL'
                )]) {
                    sh '''
                        docker run --rm \
                            -e DATABASE_URL \
                            -v "$WORKSPACE:/work" \
                            -w /work \
                            ormfactory/cli:latest \
                            deploy --project=model.0fproj \
                            --connection-env=DATABASE_URL
                    '''
                }
            }
        }
    }
}

Store credentials in your CI system's secret or credential storage. Avoid committing database credentials to source control or writing them directly in pipeline configuration.