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
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
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
Respondiendo a tus preguntas:
- El
database2_user
en forma deuser
en vez deDOMINIO/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
Gracias.
Sabrías cuál es el soporte de Doctrine con SQL Server.
@dariongg
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
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
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
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
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
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
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
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
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