MongoDB Migrations
This guide describes how to create and run mongodb migrations.
Introduction
From time to time there are structural or other changes to the data in the MongoDB persistence layer. When we make them we need a way to ensure that all our entities get updated.
While doctrine odm suggests that we do it manually by implementing migration code on the document level, this does not cut it for us since most of our document classes get generated by graviton. For this reason we support mongodb-migrations that are similar to regular doctrine orm migrations.
Preparing Bundles for Migrations
Each graviton bundle that contains migrations needs to be prepared in a specific way. It needs a migrations configuration and the path to the migrations directory needs to be added to the autoloader.
For the purpose of this documentation we are assuming that a bundle has the following structure.
.
|____composer.json
|____src
| |____Migrations
| | |____MongoDB
| |____Resources
| | | |____Version20151119140145.php
| | |____config
| | | |____migrations.yml
| | |____definition
| | | |____DocumentDefinition.json
The file migrations.yml
configures the bundle level migration support.
# migrations.yml
---
name: acme-bundle migrations
collection_name: acme-bundle-migrations
migrations_namespace: AcmeBundle\Migrations\MongoDB
migrations_directory: vendor/grv/acme-bundle/src/Migrations/MongoDB
The namespaces of the migration classes is registered in composer.json
.
# composer.json
{
"autoload": {
"psr-4": {"AcmeBundle\\": "src/"}
}
}
With this the migration code knows where to find migration code as well as where to store metadata pertaining to the migrations.
Generating and Writing Migrations
To help you getting started with writing a migration you can use the console.
./vendor/graviton/graviton/app/console mongodb:migrations:generate \
--configuration=vendor/acme/acme-bundle/src/Resources/config/migrations.yml
This generates a new migration class which needs to be customized to suite your migration needs. You will need to implement both the up()
and
down()
method for a full migration.
If you need access to other parts of graviton during migrations you may implement the ContainerAwareInterface
in your migration to get a
container injected.
Annotated Example Annotation
<?php
/**
* example migration
*/
namespace Graviton\EvojaChecklistBundle\src\Migrations\MongoDB;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use AntiMattr\MongoDB\Migrations\AbstractMigration;
use Doctrine\MongoDB\Database;
/**
* @author List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
* @license http://opensource.org/licenses/MIT MIT License
* @link http://swisscom.ch
*/
class Version20151207122656 extends AbstractMigration implements ContainerAwareInterface
{
/**
* @var ContainerInterface container
*/
private $container;
/**
* @param ContainerInterface|null $container
* @return void
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* @return string
*/
public function getDescription()
{
return "Migrate acme bundle things";
}
/**
* @param Database $db mongodb database
* @return void
*/
public function up(Database $db)
{
// get dm (or other stuff) from container
$dm = $this->container->get('doctrine.odm.mongodb.document_manager');
// do migration (use hydrate(false) as needed)
// ...
// $qb = $dm->createQueryBuilder('GravitonDyn\AcmeBundle\Document\Document');
// ...
// flush dm at the end
$dm->flush();
}
/**
* @param Database $db mongodb database
* @return void
*/
public function down(Database $db)
{
// do something similar to up() but the other way around
}
}
Running Migrations
You can run the migrations for a single bundle using the mongodb:migrations:migrate
command as long as you pass the path to a configuration as
described above.
./vendor/graviton/graviton/app/console mongodb:migrations:migrate \
--configuration=vendor/acme/acme-bundle/src/Resources/config/migrations.yml
For your convenience you may also call graviton:mongodb:migrate
which will run the migrate command for all configurations stored in the Resources/config
directory of a bundle.
./vendor/graviton/graviton/app/console graviton:mongodb:migrate