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

Añadir una nueva base de datos a un proyecto Symfony existente

16 de marzo de 2015

Saludos.

Tengo una aplicación symfony (2.1) operativa. La situación es la siguiente: necesito actualizar mi aplicación incorporando una base de datos (con información) que existe en otro servidor de la red.

Esta base de datos funciona en Microsoft SQL Server 2012 en servidor Windows 2008 R2.

Mis dudas:

  • Qué necesito para configurar la base de datos en la aplicación/servidor. (Yo no tengo acceso para modificar la configuración del servidor, por eso necesito saber que tengo que cambiar, para pedir se lo al administrador)
  • ¿Tengo que crear entidad para cada tabla de la base de datos que se utilice?

Esos son mis dudas, Gracias.


Respuestas

#1

Nunca he usado SQL Server en una aplicación Symfony, pero se supone que gracias a DBAL/Doctrine, debería funcionar todo igual que con cualquier otra base de datos tipo MySQL o PostgreSQL.

Los datos que debes pedir al administrador son las credenciales para acceder a la base de datos (usuario y contraseña) y los datos de conexión (host, puerto, etc.) Puedes añadir los nuevos datos como parámetros del archivo parameters.yml (o parameters.ini si todavía usas ese formato). Ejemplo:

parameters:
    # base de datos MySQL existente
    database_driver: pdo_mysql
    database_host: localhost
    database_port: null
    database_name: nombre_bbdd
    database_user: root
    database_password: loQueSea
 
    # nueva base de datos SQL Server
    database2_driver: pdo_sqlsrv
    database2_host: XXXX
    database2_port: XXX
    database2_name: nombre_nueva_bbdd
    database2_user: XXX
    database2_password: XXX

Después, en el archivo app/config/config.yml tienes que definir un nuevo entity manager. La idea es que en el código de la aplicación, cada vez que hagas una consulta o actualices la información, deberás elegir uno de los dos entity managers para que Symfony/Doctrine sepan dónde buscar o modificar información. Puedes echar un vistazo a esta otra pregunta del foro donde respondí una duda similar y puse un ejemplo de cómo usar los dos entity managers.

Por último, sí que tienes que crear una entidad para cada tabla que vayas a manipular en la nueva base de datos. Lo bueno es que Doctrine en Symfony incluye un comando llamado doctrine:mapping:import con el que puedes crear las entidades automáticamente a partir de una base de datos existente. Lee este artículo para ver en detalle cómo funciona.

@javiereguiluz

16 marzo 2015, 15:59
#2

Gracias por tu pronta respuseta.

Mi duda esta en estos puntos

# nueva base de datos SQL Server
    database2_driver: pdo_sqlsrv
    database2_host: XXX
    database2_port: XXX
    database2_name: nombre_nueva_bbdd
    database2_user: XXX
    database2_password: XXX

1) database2_user: mi duda el usuario se escribe de esta forma user o DOMINIO/user

2) database_host: el servidor donde esta mi aplicación también está la base de datos principal y defino el host localhost. Aquí le asigno la IP del servidor.

3) database2_port: Especifico el puerto que corre la base de datos.

4) Configurar algo en el administrador de la base de datos o en Windows para poder tener acceso a la base de datos de forma remota.

5) o donde esta la aplicación funcionando necesita de algun modificacion o instalar para que funcione la coneccion con sql server.

Gracias.

@dariongg

16 marzo 2015, 16:08
#3

Respondiendo a tus preguntas:

  • El database2_user en forma de user en vez de DOMINIO/user debería ser suficiente.
  • El database2_host normalmente sí que será una dirección IP.
  • El database2_port será 1433 a menos que el administrador haya cambiado el puerto por defecto.
  • No hay que configurar nada más, salvo lo obvio: desde tu máquina debes ser capaz de establecer conexiones con la IP y el puerto de la base de datos. Igualmente, la base de datos debe ser capaz de aceptar conexiones desde la IP de tu servidor.

@javiereguiluz

16 marzo 2015, 16:31
#4

Gracias.

Sabrías cuál es el soporte de Doctrine con SQL Server.

@dariongg

16 marzo 2015, 16:37
#5

Aquí tienes un listado de todos los problemas conocidos de Doctrine/DBAL con Microsoft SQL Server: Known Vendor Issues with Microsoft SQL Server.

Por otra parte, si tienes problemas para usar SQL Server en tu aplicación Symfony, echa un vistazo a este artículo que explica una forma alternativa de hacerlo funcionar.

@javiereguiluz

16 marzo 2015, 16:44
#6

Actualmente tengo esto:

orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        entity_managers:
          default:
            auto_mapping: true
            dql:
              datetime_functions:
                MONTH: DoctrineExtensions\Query\Mysql\Month
                YEAR: DoctrineExtensions\Query\Mysql\Year
                DAY: DoctrineExtensions\Query\Mysql\Day
                DATE_FORMAT: App\AppBundle\DQL\DateFormatFunction
              numeric_functions:
                UNIX_TIMESTAMP: App\AppBundle\DQL\UnixTimestamp

Todos los bundles excepto este ExternoBundle pertenecen a default. Por tanto debe quedar de esta forma:

orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                mappings:
                    AppBundle:  ~
                    AcmeStoreBundle: ~
                dql:
                    datetime_functions:
                        MONTH: DoctrineExtensions\Query\Mysql\Month
                        YEAR: DoctrineExtensions\Query\Mysql\Year
                        DAY: DoctrineExtensions\Query\Mysql\Day
                        DATE_FORMAT: Intranet\PersonalBundle\DQL\DateFormatFunction
                    numeric_functions:
                        UNIX_TIMESTAMP: Intranet\TurnoBundle\DQL\UnixTimestamp
            externa:
                connection: externa
                mappings:
                    ExternoBundle: ~

Por otra parte el siguiente comando exporta la estructura de las dos base de datos:

$ php app/console doctrine:mapping:convert xml 
  ./src/Acme/BlogBundle/Resources/config/doctrine/metadata/orm
  --from-database --force

El problema que tengo es que la base de datos por defecto tengo tablas que no están representadas por la aplicación y no quiero que la importe, solo de la base de datos externa.

Gracias.

@dariongg

16 marzo 2015, 21:01
#7

El problema de no importar las dos bases de datos con el comando doctrine:mapping:convert es fácil de solucionar: todos los comandos de Doctrine definen la opción --em con la que puedes indicar el entity manager que debe utilizarse al ejecutar el comando.

Así que sólo tienes que ejecutar el comando de la siguiente manera:

$ php app/console doctrine:mapping:convert xml 
  ./src/Acme/BlogBundle/Resources/config/doctrine/metadata/orm
  --from-database --force
  --em=externa

@javiereguiluz

16 marzo 2015, 22:52
#8

Al exportar la base de datos, me arrojó el siguiente mensaje:

[Doctrine\DBAL\DBALException]                                                
  Unknown database type timestamp requested,
  Doctrine\DBAL\Platforms\SQLServer2008Platform may not support it.

@dariongg

17 marzo 2015, 15:00
#9

Según este artículo de la documentación oficial de Symfony tienes que utilizar la opción mapping_types para redefinir el tipo de dato de cualquier tipo desconocido de la base de datos que utilices:

# app/config/config.yml
doctrine:
    dbal:
       mapping_types:
          timestamp: integer

En este ejemplo he puesto integer porque Doctrine no tiene un tipo de datos para almacenar timestamps. Además, un valor entero permite almacenar timestamps de fechas hasta el año 2106. Si necesitas más, usa el tipo bigint o string.

@javiereguiluz

17 marzo 2015, 15:17
#10

Disculpa por hacer tantas preguntas, pero me arrojó otro error:

[Doctrine\ORM\Mapping\MappingException]                                      
  Table tbcaspen has no primary key. Doctrine does not support reverse
  engineering from tables that don't have a primary key.

Que puedo hacer con las tablas que no tienen Primary Key. ¿Se pueden saltar en la comprobación?

@dariongg

17 marzo 2015, 15:41
#11

Tienes dos posibles soluciones:

1) Si necesitas esa entidad que Doctrine no puede generar porque no hay clave primaria definida, entonces tienes que crearla a mano. No hay posibilidad de saltarse esa comprobación.

2) Si no necesitas esa entidad en tu aplicación, puedes usar la opción --filter del comando. Esta opción indica las entidades que sí se deben importar y puedes añadir más de una opción --filter:

$ php app/console doctrine:mapping:convert xml 
  ./src/Acme/BlogBundle/Resources/config/doctrine/metadata/orm
  --from-database --force
  --em=externa
  --filter:Entidad1 --filter=Entidad2 --filter=Entidad3

@javiereguiluz

17 marzo 2015, 15:58
#12

El comando para exportar las estructuras de las tablas, pero sigue arrojando la misma excepción.

[Doctrine\ORM\Mapping\MappingException]                                      
  Table tbcaspen has no primary key. Doctrine does not support reverse
  engineering from tables that don't have a primary key.

Este es el comando que utilice.

$ php app/console doctrine:mapping:convert xml   
   ./src/App/ExternoBundle/Resources/config/doctrine/metadata/orm 
   --from-database 
   --force 
   --em="externa" 
   --filter="tabla1" 
   --filter="tabla12"

ACTUALIZACIÓN

Agregre esto en config.php

doctrine:
    dbal:
        externo:
            schema_filter:  ~^(table1|table2|table3|table4)$~

Importo los esquemas de las tablas señaladas anteriormente.

@dariongg

17 marzo 2015, 19:24
#13

Hola,

Yo estoy intentando obtener las clases en base a la DB y mi entidad tiene 4 campos primary key. El mensaje que me aparece ejecutar el comando:

php bin/console doctrine:mapping:import Bundle annotation --em=store

es el siguiente

[Doctrine\ORM\Mapping\MappingException]
 Table tbl_xx has no primary key. Doctrine does not support reverse engineering from tables that don't have a primary key.

@cesarluisl

7 octubre 2016, 17:55