Download the PHP package shipmonk/doctrine-two-phase-migrations without Composer

On this page you can find all versions of the php package shipmonk/doctrine-two-phase-migrations. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package doctrine-two-phase-migrations

Two-phase migrations for Doctrine

This lightweight library allows you to perform safer Doctrine migrations during deployment in cluster-based environments like kubernetes where rolling-update takes place. Each migration has two up phases, no down phase.

You can see Czech talk about this library on YouTube.

Installation:

Configuration in Symfony application:

Register the bundle in config/bundles.php:

Then configure it in config/packages/two_phase_migrations.yaml:

The bundle requires symfony/http-kernel ^6.4+. All commands and services are registered automatically, and Doctrine\ORM\EntityManagerInterface is autowired. If you register a custom MigrationExecutor, MigrationAnalyzer, or MigrationVersionProvider service, it will be picked up automatically.

All commands accept an optional Psr\Log\LoggerInterface. When a logger is available (e.g. via MonologBundle), structured log messages with context are emitted. When no logger is injected, commands fall back to Symfony\Component\Console\Logger\ConsoleLogger and write directly to the console output.

Manual service registration (without the bundle) If your `Doctrine\ORM\EntityManagerInterface` is autowired, just register few services in your DIC and tag the commands:

Commands:

Initialization:

After installation, you need to create migration table in your database. It is safe to run it even when the table was already initialized. When upgrading from 1.x, running it once also upgrades the existing table to the new schema (it makes finished_at nullable, see Concurrency & execution safety). Only that single column is altered, so it is safe to run against a populated table.

Generating new migration:

You can generate migration from database <=> entity diff automatically. This puts all the queries generated by Doctrine to before stage, which will NOT be correct for any destructive actions. Be sure to verify the migration and move the queries to proper stage or adjust them. When no diff is detected, empty migration class is generated.

The generated file then looks like this:

You can adjust it by providing custom $templateFilePath to MigrationConfig, but it needs to implement Migration interface.

Status verification:

You can check awaiting migrations and entity sync status:

Skipping all migrations:

You can also mark all migrations as already executed, e.g. when you just created fresh schema from entities. This will mark all not executed migrations in all stages as migrated.

Executing migration:

Execution is performed without any interaction and does not fail when no migration is present for execution.

When executing all the migrations (e.g. in test environment) you probably want to achieve one-by-one execution. You can do that by:

Concurrency & execution safety

migration:run is designed to be safe to run multiple times and in parallel (e.g. during a rolling deployment where several instances may start the command at once). "Safe" here means it will never silently corrupt your database — not that every invocation finishes the work. Two mechanisms provide this:

Parallel runs are serialized by a database lock

Before doing anything, migration:run acquires a database-level lock, so only one run executes migrations at a time:

A parallel run waits up to lock_timeout_seconds (default 300) for the lock and then proceeds once the holder finishes. If the timeout is exceeded, it aborts with exit code 2 instead of running concurrently. The lock is bound to the connection session, so it is released automatically if a runner is killed.

Interrupted migrations block all further runs until resolved

Each migration is recorded in two steps: a row with started_at (and finished_at = NULL) is committed before the migration body runs, and finished_at is set after it succeeds. If a runner is killed mid-migration, a finished_at = NULL row is left behind. This start marker is intentionally written outside any transaction, so it relies on the connection committing it immediately (autocommit, the Doctrine default); the detection guarantee does not hold for connections configured with auto_commit: false.

Because such a migration may be only partially applied, every subsequent migration:run fails loudly (exit code 1) instead of re-executing potentially non-idempotent SQL:

To recover, inspect the database to determine what the interrupted migration actually applied, then resolve the finished_at = NULL row in the migration table manually:

migration:run exit codes: 0 success, 1 unfinished migration found (manual resolution required), 2 lock could not be acquired, 3 migration table missing or not upgraded (run migration:init). migration:check also reports unfinished migrations (and adds 8 to its exit code bitmask).

Advanced usage

Run custom code for each executed query:

You can hook into migration execution by implementing MigrationExecutor interface and registering your implementations as a service. Implement executeQuery() to run checks or other code before/after each query. Interface of this method mimics interface of Doctrine\DBAL\Connection::executeQuery().

Alter generated migration SQLs:

You can implement custom MigrationAnalyzer and register it as a service. This allows you to alter generated SQLs (e.g. add ALGORITHM=INSTANT) and assign them to proper phase.

Hook to migration execution:

If you pass Psr\EventDispatcher\EventDispatcherInterface to MigrationService, you can hook into migration execution. Dispatched events are:

All events have MigrationPhase enum and Migration instance available.

Run all queries within transaction:

You can change your template (or a single migration) to extend TransactionalMigration. That causes each phases to be executed within migration. Be aware that many databases (like MySQL) does not support transaction over DDL operations (ALTER and such).

Checking execution duration:

Migration table has started_at and finished_at columns with datetime data with microseconds. But those columns are declared as VARCHARs by default, because there is no microsecond support in doctrine/dbal yet. That may complicate datetime manipulations (like duration calculation). You can adjust the structure to your needs (e.g. use DATETIME(6) for MySQL) manually in some migration.

finished_at is nullable: a NULL value marks a migration that was started but never finished (see Concurrency & execution safety).

Differences from doctrine/migrations

The underlying diff checking and generation is equal to what happens in doctrine/migrations as it uses doctrine/dbal features. Main difference is that we do not provide any downgrade phases.

This library is aiming to provide only core functionality needed for safe migrations within rolling-update deployments. Basically all the logic is inside MigrationService, which has only ~300 lines. We try to keep it as lightweight as possible, we do not plan to copy features from doctrine/migrations.


All versions of doctrine-two-phase-migrations with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
doctrine/dbal Version ^4.3.0
doctrine/orm Version ^3.3.3
psr/event-dispatcher Version ^1.0
psr/log Version ^2.0 || ^3.0
symfony/console Version ^5.4.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package shipmonk/doctrine-two-phase-migrations contains the following files

Loading the files please wait ...