Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Conexiones múltiples a bases de solo lectura y poder usar entitymanager

13 de marzo de 2015

Hola. Soy nuevo en Symfony y se me presenta la siguiente situación.

Estoy desarrollando un sistema con acceso a dos bases de datos: una MySQL para el sistema propiamente dicho, con la política de usuarios y demás y otra DB2 que es de solo lectura, hace consultas y eventualmente se agrega algún que otro registro.

Esta es una base (o schema) que existe de hace chiquicientos años, sumamente importante. He podido conectarme a las dos. Al MySQL de manera mas común y a la DB2 he hecho un servicio. El problema que se me presenta es que tengo que hacer consultas a la base de DB2 por medio de formularios y/o filtros me da excepciones por no tener entidades declaradas, (necesarias para la clase del formulario o filter ya que he de necesitar en entity manager). Si las declaro al regenerar el modelo no puedo pisar los datos existentes, por lo ya aclarado.

He buscado la manera de poder crear entidades y ver si existe alguna anotaciín que le diga Symfony que no mapee esa clase, pero no he encontrado. No se si es que estoy buscando una solución muy compleja y a lo mejor es tan simple que no lo veo.

Gracias de antemano.


Respuestas

#1

Respecto a no hacer cambios en las entidades relacionadas con DB2, es muy fácil gracias a la anotación @Entity de Doctrine. Sólo tienes que usar la propiedad readOnly, que no impide hacer persist() y flush() pero sí que hace que se ignore cualquier cambio sobre la entidad:

/**
 * @Entity(repositoryClass="AppBundle\Repository\UserRepository", readOnly=true)
 */
class User
{
    //...
}

Y respecto a usar dos bases de datos y hacer un servicio para una de ellas, sí que te estás complicando mucho la vida. Lo que quieres hacer ya lo soporta Symfony por defecto, así que no te costará nada hacerlo. En este artículo lo explican muy bien, pero básicamente tienes que definir dos entity manager y después decir qué bundles o qué entidades están manejadas por cada uno de ellos. Ejemplo:

# app/config/config.yml
doctrine:
    dbal:
        default_connection: default
        connections:
            # aquí configuras la base de datos MySQL
            default:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
            # aquí configuras la base de datos DB2
            legacy:
                driver:   "..."
                host:     "..."
                port:     "..."
                dbname:   "..."
                user:     "..."
                password: "..."
                charset:  UTF8
 
    # aquí defines a qué base de datos pertenece cada bundle o cada entidad
    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                mappings:
                    AppBundle:  ~
                    AcmeStoreBundle: ~
            legacy:
                connection: customer
                mappings:
                    AcmeCustomerBundle: ~

Y luego en tu código tienes que usar lo siguiente para indicar qué entity manager quieres usar para hacer las consultas:

// obtener el entity manager de la base de datos MySQL: las dos formas son equivalentes
$em = $this->get('doctrine')->getManager();
$em = $this->get('doctrine')->getManager('default');
 
// obtener el entity manager de la base de datos DB2
$legacyEm = $this->get('doctrine')->getManager('legacy');

@javiereguiluz

13 marzo 2015, 8:29