Используйте EntityManager в файле миграции

У меня есть этот код, но не работает:

<?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");
    }
}

Я добавил информацию в мобильный телефон в новом поле.

Спасибо

2 ответа

Решение

Это может быть старый пост, но пока проблема решена и фактически является частью текущей документации.

См. http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html

// ...
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
    }
}

Я понимаю, что это старовато, но учусь на своей ошибке и:

даже не думайте об использовании Entity Manager в миграциях

особенно так, как вы хотите его использовать - чтобы получить репозиторий сущностей.

Вот почему.

Представьте себе ситуацию, когда у вас есть DogEntity с полем $name. Теперь вы создаете файл миграции (скажем, его Версия 1) на основе этой сущности. Все идет нормально.

Затем вы хотите использовать диспетчер сущностей, чтобы получить репозиторий этого DogEntity, обновите записи, сделайте все, что вам нужно, с этими объектами. И это работает, и все в порядке (допустим, этот файл миграции имеет имя Version2).

Теперь вы добавляете $color поле для вашего DogEntity, вы снова создаете миграцию (это файл с именем Version3). И это нормально...

... до тех пор, пока вы не попытаетесь запустить все миграции с самого начала. В этот момент во время миграции файла Version2 будет выдана ошибка. Почему? Поскольку менеджер сущностей ищетcolorполе в базе данных. Но это поле создается позже в файле версии 3.

TL; DR: Entity Manager ищет столбцы, которые В настоящее время есть в вашей сущности, и которые могут вызвать проблемы при выполнении миграции с самого начала.

Вы должны позвонить ваши изменения в postUp() метод - addSql()- Заявления будут выполнены после up() метод завершен, поэтому ваши новые строки (т. е. Tellphone) не доступны во время up() метод!

Другие вопросы по тегам