Movatterモバイル変換


[0]ホーム

URL:


Skip to main content
New: Ask AI, SQL Imports and moreRead now

Automatic migration planning for Doctrine

TL;DR

  • Doctrine is an ORM library that's widely used in the PHP community.
  • Atlas is an open-source tool for inspecting, planning, linting andexecuting schema changes to your database.
  • Developers using Doctrine can use Atlas to automatically plan schema migrationsfor them, based on the desired state of their schema instead of crafting them by hand.

Automatic migration planning for Doctrine

Doctrine is a popular ORM widely used in the PHP community, used by projects likeSymfony.Doctrine allows users to manage their database schemas using itsorm:schema-tool Console Command,which is usually sufficient during development and in many simple cases.

However, at some point, teams need more control and decide to employ aversioned migrations methodology.Doctrine has amigration tool that can be used to manage versioned migrations.Doctrine can alsogenerate a migrationfor you by comparing the current state of your database schema to the state defined by using the ORM.

A downside of this approach is that in order for it to work, you must be connected to a pre-existing database with the current version of the schema.In many production environments, databases should generally not be reachable from developer workstations,which means this comparison is normally done against a local copy of the database which may haveundergone some changes that aren't reflected in the existing migrations.

More of the limitations of the Doctrine migration tool include:

  • Ensuring Migration Safety. Migrations are a risky business. If you're not careful, you can easily cause data loss ora production outage. The Doctrine migration tool does not provide a native way to ensure that a migration is safe to apply.
  • Modern Deployments. Doctrine does not provide native integrations with modern deployment practices such asGitOpsorInfrastructure-as-Code.

Using Atlas, you can enjoy automatic migration planning, automatic code review and integrations with your favorite CI/CD tools.

Atlas works in a similar way to the Doctrine migration tool, by calculating the diff between thecurrent state of the database.

In the context ofversioned migrations,the current state can be thought of as the database schema that would havebeen created by applying all previous migration scripts.

The desired schema of your application can be provided to Atlas via anExternal Schema Datasource,which is any program that can output a SQL schema definition to stdout.

To use Atlas with Doctrine, users can utilize theDoctrine Atlas Provider,which is a small program that loads the schema of a Doctrine project into Atlas.

In this guide, we will show how to use Atlas to automatically plan schema migrations for Doctrine users.

Prerequisites

If you don't have a Doctrine project, you can usesymfony/demo as a starting point:

git clone git@github.com:symfony/demo.git

Using the Atlas Doctrine Provider

In this guide, we will use theDoctrine Atlas Providerto automatically plan schema migrations for a Doctrine project.

Installation

  • macOS + Linux
  • Homebrew
  • Docker
  • Windows
  • Manual Installation

To download and install the latest release of the Atlas CLI, simply run the following in your terminal:

curl-sSf https://atlasgo.sh|sh

Install the provider, depending on thedoctrine/dbalversion you are using in thecomposer.json file:

  • Doctrine DBAL v4
  • Dcotrine DBAL v3
composer require ariga/atlas-provider-doctrine:^4

Configuration

The Atlas Doctrine Provider can be used in three modes:

  • Doctrine Command - If all of your Doctrine entities exist under a single directory,you can add theatlas-provider command to theDoctrine Console file.
  • Symfony Bundle - If you use aSymfony project, you can register the provider as a Symfony bundle.
  • Script - In other cases, you can use the provider as a PHP script to load your Doctrine schema into Atlas.

Using the Doctrine Command

Add theatlas-provider command to the Doctrine Console file:

#!/usr/bin/env php
<?php

use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;

require 'bootstrap.php';
+ require "vendor/ariga/atlas-provider-doctrine/src/Command.php";

ConsoleRunner::run(
new SingleManagerProvider($entityManager),
+ [new AtlasCommand()]
);

Next, in your project directory, create a new file namedatlas.hcl with the following contents:

data"external_schema""doctrine"{
program=[
"php",
"bin/doctrine",// path to your Doctrine Console file
"atlas:schema",
"--path","./path/to/entities",
"--dialect","mysql"// mariadb | postgres | sqlite | sqlserver
]
}

env"doctrine"{
src= data.external_schema.doctrine.url
dev="docker://mysql/8/dev"
migration{
dir="file://migrations"
}
format{
migrate{
diff="{{ sql . \" \" }}"
}
}
}

As Symfony Bundle

Add the following bundle to yourconfig/bundles.php file:

<?php

require "vendor/autoload.php";

return [
...
+ Ariga\AtlasDoctrineBundle::class => ['all' => true],
];

Next, in your project directory, create a new file namedatlas.hcl with the following contents:

data"external_schema""doctrine"{
program=[
"php",
"bin/console",
"atlas:schema"
]
}

env"doctrine"{
src= data.external_schema.doctrine.url
dev="docker://mysql/8/dev"
migration{
dir="file://migrations"
}
format{
migrate{
diff="{{ sql . \" \" }}"
}
}
}
note

The provider does not support loading entities viaentity listeners.To load Symfony schema with entity listeners, use theDoctrine Bundle directly:

data "external_schema" "doctrine" {
program = [
"php",
"bin/console",
- "atlas:schema"
+ "doctrine:schema:create",
+ "--dump-sql"
]
}

As a PHP Script

Create a new file namedatlas.php with the following contents:

<?php

require"vendor/autoload.php";
require"vendor/ariga/atlas-provider-doctrine/src/LoadEntities.php";

print(DumpDDL(["./path/to/first/entities","./path/to/more/entities"],"mysql"));

Next, in your project directory, create a new file namedatlas.hcl with the following contents:

data"external_schema""doctrine"{
program=[
"php",
"atlas.php"
]
}

env"doctrine"{
src= data.external_schema.doctrine.url
dev="docker://mysql/8/dev"
migration{
dir="file://migrations"
}
format{
migrate{
diff="{{ sql . \" \" }}"
}
}
}

Usage

Atlas supports a versioned migrations workflow, where each change to the database is versioned and recorded in a migration file. You can use theatlas migrate diff command to automatically generate a migration file that will migrate the databasefrom its latest revision to the current Doctrine schema.

Suppose we have the following files in oursrc/entities directory:

  • User.php
  • Bug.php
<?php

namespaceentities;

useBug;
useDoctrine\Common\Collections\Collection;
useDoctrine\ORM\MappingasORM;

#[ORM\Entity]
#[ORM\Table(name:'users')]
classUser
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type:'integer')]
privateint|null$id=null;

#[ORM\Column(type:'string')]
privatestring$name;

#[ORM\OneToMany(targetEntity:Bug::class,mappedBy:'reporter')]
privateCollection$reportedBugs;

#[ORM\OneToMany(targetEntity:Bug::class,mappedBy:'engineer')]
private$assignedBugs;
}

We can generate a migration file by running the following command:

atlas migratediff--env doctrine

Running this command will generate files in themigrations directory, similarly to:

migrations
|-- 20240310094824.sql
`-- atlas.sum

0 directories, 2 files

Examining the contents of the20240310094824.sql:

-- Create "users" table
CREATETABLE`users`(
`id`intNOTNULLAUTO_INCREMENT,
PRIMARYKEY(`id`)
)CHARSET utf8mb4COLLATE utf8mb4_0900_ai_ci;
-- Create "bugs" table
CREATETABLE`bugs`(
`id`intNOTNULLAUTO_INCREMENT,
`description`varchar(255)NOTNULL,
`created`datetimeNOTNULL,
`status`varchar(255)NOTNULL,
`engineer_id`intNULL,
`reporter_id`intNULL,
PRIMARYKEY(`id`),
INDEX`IDX_1E197C9E1CFE6F5`(`reporter_id`),
INDEX`IDX_1E197C9F8D8CDF1`(`engineer_id`),
CONSTRAINT`FK_1E197C9E1CFE6F5`FOREIGNKEY(`reporter_id`)REFERENCES`users`(`id`)ONUPDATENOACTIONONDELETENOACTION,
CONSTRAINT`FK_1E197C9F8D8CDF1`FOREIGNKEY(`engineer_id`)REFERENCES`users`(`id`)ONUPDATENOACTIONONDELETENOACTION
)CHARSET utf8mb4COLLATE utf8mb4_0900_ai_ci;

Amazing! Atlas automatically generated a migration file that will create theusers andbugs tables in our database.

Next, alter theUser entity to include a$name property.

   #[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int|null $id = null;

+ #[ORM\Column(type: 'string')]
+ private string $name;

Re-run this command:

atlas migratediff--env doctrine

Observe that a new migration file is generated:

-- Modify "users" table
ALTERTABLE`users`ADDCOLUMN`name`varchar(255)NOTNULL;

Conclusion

In this guide, we demonstrated how projects using Dcotrine can use Atlas to automaticallyplan schema migrations based only on their data model. To learn more about executingmigrations against your production database, read the documentation about themigrate apply command.

Have questions? Feedback? Find our teamon our Discord server


[8]ページ先頭

©2009-2025 Movatter.jp