Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use EntityManager in Migrations file

I have this code but does not work:

<?php

namespace Application\Migrations;

use Doctrine\DBAL\Migrations\AbstractMigration,
    Doctrine\DBAL\Schema\Schema;

/**
 * Auto-generated Migration: Please modify to your need!
 */
class Version20131021150555 extends AbstractMigration
{

    public function up(Schema $schema)
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'.");

        $this->addSql("ALTER TABLE person ADD tellphone LONGTEXT DEFAULT NULL");

        $em = $em = $this->getDoctrine()->getEntityManager();
        $persons = $em->getRepository('AutogestionBundle:Person')->fetchAll();

        foreach($persons as $person){
            $person->setTellPhone($person->getCellPhone());
            $em->persist($person);                                                                            
        }
        $em->flush(); 
    }

    public function down(Schema $schema)
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'.");

        $this->addSql("ALTER TABLE person DROP tellphone");
    }
}

I have add info in cellphone in a new field tellphone.

Thanks

like image 701
Zarpele Avatar asked Oct 21 '13 19:10

Zarpele


3 Answers

This may be an older post, but meanwhile the problem is solved and actually part of the current documentation.

See http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html#container-aware-migrations

// ...
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

class Version20130326212938 extends AbstractMigration implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    public function up(Schema $schema)
    {
        // ... migration content
    }

    public function postUp(Schema $schema)
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        // ... update the entities
    }
}
like image 117
AKCD Avatar answered Oct 19 '22 19:10

AKCD


I do realize this is kind of old but learn on my mistake and:

don't even think about using entity manager in migrations

especially in a way you want to use it - to get the entity repository.

Here's why.

Imagine a situation where You have a DogEntity with field $name. You now generate a migration file (lets say its Version1) based on that entity. So far so good.

Next, you want to use entity manager to get the repository of that DogEntity, update the records, do whatever you need to do with that entities. And that works and it's okay (and let's say this migration file has name Version2).

Now, you add a $color field to your DogEntity, again you generate migration (it's a file named Version3). And its okay...

... up until you try to run all migrations from the beggining. In that moment, the error will throw during migration of Version2 file. Why? Because the entity manager looks for the color field in the database. But that field is created later, in Version3 file.

TLDR: Entity Manager looks for columns that you CURRENTLY have in your entity and that can cause problems while running migrations from the start.

like image 24
Maad Avatar answered Oct 19 '22 17:10

Maad


You must call your modifications in the postUp() method - the addSql()- Statements will be executed after up() method is completed, so your new rows (i.e. tellphone) are not available during the up() method!

like image 8
Alex Avatar answered Oct 19 '22 18:10

Alex