Access Entity Manager inside Symfony 5 migration class?

He añadido una relación de noticias dentro de mi mesa, y dentro del método postUp() quiero actualizar todos mis hilos.

¿Cómo puedo acceder al EntityManager dentro de mi clase de migración para conseguir todo mi hilo, actualizarlos y persistir/fluir mis modificaciones, por favor?

Pregunta hecha hace 3 años, 4 meses, 28 días - Por codecraftsman


3 Respuestas:

  • La herramienta de migración de Doctrine está dirigida a ejecutar las consultas SQL para usted con el fin de modificar su esquema de base de datos. No tiene nada que ver con sus objetos persistentes, ya que opera en un nivel de base de datos, en lugar de un nivel de ORM. Puede escribir consultas SQL para actualizar los registros de bases de datos relacionados. Además, puede utilizar una conexión de base de datos dentro de un script de migración para obtener datos que necesita de una base de datos. Aquí hay un simple ejemplo para darle un punto de partida.

    foreach ($this->connection->fetchAll('SELECT id FROM table') as $id) {
        $ids = $this->connection->fetchAll(
            'SELECT some_id FROM another_table WHERE whatever_id = :whateverId GROUP BY some_id',
            [
                'whateverId' => $id['id']
            ]
        );
    
        $this->addSql(
            'UPDATE table_to_update SET some_field = :someField WHERE id = :some_id',
            [
                'someField' => implode(
                    ',',
                    array_map(
                        static function (array $data) {
                            return $data['some_id'];
                        },
                        $ids
                    )
                ),
                'some_id' => $id['id']
            ]
        );
    }
    

    Como alternativa para el caso si usted absolutamente no puede resolver su problema sin acceder a sus objetos persistentes (por ejemplo, si necesita aplicar alguna lógica de negocio dentro de una migración o una lógica de migración está más allá de un simple cambio de esquema), es mejor escribir un Comando de consola de Symfony e inyecte EntityManager, repositorios y lo que necesite. Este comando de consola se ejecutaría una vez para aplicar una migración compleja y luego se descompone en un próximo lanzamiento.

    Respondida el Dec 18, 2020 a las 13:16 - por nasean

    Votos positivos: 0 | Votos negativos: 0

  • Dentro de una clase de migración en Symfony 5, puedes acceder al EntityManager utilizando la clase ContainerAwareInterface y la propiedad container de la clase de migración. Aquí tienes un ejemplo de cómo puedes hacerlo:

    php
    use Doctrine\DBAL\Schema\Schema;
    use Doctrine\Migrations\AbstractMigration;
    use Symfony\Component\DependencyInjection\ContainerAwareInterface;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    class Version20210902134557 extends AbstractMigration implements ContainerAwareInterface
    {
        private $container;
    
        public function setContainer(ContainerInterface $container = null)
        {
            $this->container = $container;
        }
    
        public function up(Schema $schema) : void
        {
            $em = $this->container->get('doctrine')->getManager();
            $noticias = $em->getRepository('App\Entity\Noticias')->findAll();
    
            foreach ($noticias as $noticia) {
                // Actualizar la noticia según tus necesidades
            }
    
            $em->flush();
        }
    
        public function down(Schema $schema) : void
        {
            // Puedes definir la lógica de rollback aquí si es necesario
        }
    }
    

    Asegúrate de reemplazar App\Entity\Noticias con la clase de entidad real que estás utilizando en tu proyecto.

    Recuerda que es importante tener en cuenta que acceder al EntityManager dentro de una migración se considera una mala práctica, ya que las migraciones deberían ser atómicas y no deberían depender de la lógica de la aplicación en sí. Lo ideal es realizar las actualizaciones necesarias directamente en la migración y no depender de la lógica de la aplicación.

    Respondida el Dec 19, 2020 a las 13:16 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para acceder al EntityManager dentro de una clase de migración de Symfony 5, puedes utilizar el método getContainer() para recuperar el contenedor de servicios y, a continuación, utilizar el contenedor para recuperar el servicio EntityManager:

    php
    use Doctrine\ORM\EntityManagerInterface;
    
    public function postUp(Schema $schema): void
    {
        $container = $this->getContainer();
        $entityManager = $container->get('doctrine.orm.entity_manager');
    
        // Obtener todos los hilos
        $threads = $entityManager->getRepository(Thread::class)->findAll();
    
        // Actualizar los hilos
        foreach ($threads as $thread) {
            // Actualizar la propiedad de la noticia
            $thread->setNews($news);
    
            // Persistir los cambios
            $entityManager->persist($thread);
        }
    
        // Fluir los cambios
        $entityManager->flush();
    }
    

    Asegúrate de importar la interfaz EntityManagerInterface y la clase Thread en la parte superior de tu clase de migración.

    Respondida el Dec 19, 2020 a las 13:26 - por Gemini

    Votos positivos: 0 | Votos negativos: 0