tutorial symfony2 query español datos crear consultas doctrine symfony

doctrine - query - Importación de tablas desde una base de datos externa en Symfony2 con doctrina



doctrine:mapping:import (7)

Creé una solución basada en todos los comentarios que simplifica el código

en el espacio de nombres de clase Doctrine / ORM / Mapping / Driver; DatabaseDriver.php

En la línea 277, cambie:

if (!$table->hasPrimaryKey()) { // comment this Throw exception // throw new MappingException( // “Table “ . $table->getName() . “ has no primary key. // Doctrine does not “. // “support reverse engineering from tables that don’t // have a primary key.” // ); } else { $pkColumns = $table->getPrimaryKey()->getColumns(); }

Y, en la línea 488, agregue:

if( $table->hasPrimaryKey() ) //add this if to avoid fatalError return $table->getPrimaryKey()->getColumns();

Para evitar problemas futuros, después de mapear su base de datos, devuelva la configuración para evitar problemas más adelante. ¡Buena suerte!

Tengo un proyecto Symfony2 con su propia base de datos, y ahora quiero conectarme a otra base de datos (otro proyecto) para poder modificar algunas tablas.

Creé la nueva conexión en config_dev.yml

doctrine: dbal: default_connection: default connections: default: driver: pdo_mysql host: localhost dbname: database1 user: root password: buv: driver: pdo_mysql host: localhost dbname: database2 user: root password:

Traté de importar el esquema con el siguiente comando:

$ php app / console doctrine: mapping: import --em = buv MyBundle yml

[Doctrine / DBAL / Schema / SchemaException] Index '''' no existe en la tabla ''old_table''

¡Pero algunas de las tablas en database2 no tienen PKs! Y la importación completa no funciona. Pero solo quiero importar dos tablas, así que lo intenté:

$ php app / console doctrine: mapping: import --em = buv --filter = "tablename" MyBundle yml

Pero estoy obteniendo el mismo error, parece que --filter no está funcionando.

La documentación en la doctrina del comando de la consola: mapeo: importar solo dice poner el nombre de la entidad en la opción de filtro. Pero aún no tengo una entidad.


Debe actualizar la función getTablePrimaryKeys para:

private function getTablePrimaryKeys(Table $table) { try { $primaryKeyColumns = ($this->tables[$table->getName()]->hasPrimaryKey())?$this->tables[$table->getName()]->getPrimaryKey()->getColumns():array(); } catch(SchemaException $e) { $primaryKeyColumns = array(); } return array(); }


Es un requisito para Doctrine tener un identificador / clave principal . Eche un vistazo a esta página: http://www.doctrine-project.org/docs/orm/2.0/en/reference/basic-mapping.html#identifiers-primary-keys

Pero hay una forma de generar mapeos y entidades a partir de tablas que no tienen una clave principal . Una tabla sin clave principal es un diseño de base de datos inusual y malo, pero existe tal escenario en el caso de las bases de datos heredadas.

Solución :
Nota : Todas las referencias a continuación se refieren a Doctrine 2.0
1. Encuentre el archivo DatabaseDriver.php (en Doctrine / ORM / Mapping / Driver / DatabaseDriver.php)
2. Encuentre el método reverseEngineerMappingFromDatabase . Modificar el código como se indica a continuación.
El código original es:

private function reverseEngineerMappingFromDatabase() { if ($this->tables !== null) { return; } $tables = array(); foreach ($this->_sm->listTableNames() as $tableName) { $tables[$tableName] = $this->_sm->listTableDetails($tableName); } $this->tables = $this->manyToManyTables = $this->classToTableNames = array(); foreach ($tables as $tableName => $table) { /* @var $table /Doctrine/DBAL/Schema/Table */ if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { $foreignKeys = $table->getForeignKeys(); } else { $foreignKeys = array(); } $allForeignKeyColumns = array(); foreach ($foreignKeys as $foreignKey) { $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns()); } if ( ! $table->hasPrimaryKey()) { throw new MappingException( "Table " . $table->getName() . " has no primary key. Doctrine does not ". "support reverse engineering from tables that don''t have a primary key." ); } $pkColumns = $table->getPrimaryKey()->getColumns(); sort($pkColumns); sort($allForeignKeyColumns); if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) { $this->manyToManyTables[$tableName] = $table; } else { // lower-casing is necessary because of Oracle Uppercase Tablenames, // assumption is lower-case + underscore separated. $className = $this->getClassNameForTable($tableName); $this->tables[$tableName] = $table; $this->classToTableNames[$className] = $tableName; } } }


El código modificado es:

private function reverseEngineerMappingFromDatabase() { if ($this->tables !== null) { return; } $tables = array(); foreach ($this->_sm->listTableNames() as $tableName) { $tables[$tableName] = $this->_sm->listTableDetails($tableName); } $this->tables = $this->manyToManyTables = $this->classToTableNames = array(); foreach ($tables as $tableName => $table) { /* @var $table /Doctrine/DBAL/Schema/Table */ if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) { $foreignKeys = $table->getForeignKeys(); } else { $foreignKeys = array(); } $allForeignKeyColumns = array(); foreach ($foreignKeys as $foreignKey) { $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns()); } $pkColumns=array(); if ($table->hasPrimaryKey()) { $pkColumns = $table->getPrimaryKey()->getColumns(); sort($pkColumns); } sort($allForeignKeyColumns); if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) { $this->manyToManyTables[$tableName] = $table; } else { // lower-casing is necessary because of Oracle Uppercase Tablenames, // assumption is lower-case + underscore separated. $className = $this->getClassNameForTable($tableName); $this->tables[$tableName] = $table; $this->classToTableNames[$className] = $tableName; } } }


3. Encuentre el método loadMetadataForClass en el mismo archivo. Modificar el código como se indica a continuación.
Encuentre el código indicado a continuación:

try { $primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns(); } catch(SchemaException $e) { $primaryKeyColumns = array(); }


Modifíquelo así:

try { $primaryKeyColumns = ($this->tables[$tableName]->hasPrimaryKey())?$this->tables[$tableName]->getPrimaryKey()->getColumns():array(); } catch(SchemaException $e) { $primaryKeyColumns = array(); }



La solución anterior crea asignaciones (xml / yml / annotation) incluso para tablas que no tienen una clave principal.


He importado con éxito algunas entidades de base de datos agregando un schema_filter en la configuración dbal de doctrine ( ~/app/config/config.yml )

# Doctrine Configuration doctrine: dbal: driver: %database_driver% host: %database_host% port: %database_port% dbname: %database_name% user: %database_user% password: %database_password% charset: UTF8 schema_filter: /^users_table/

app/console doctrine:mapping:import --force MyBundle yml

A continuación, invierta config.yml.


Si te entiendo correctamente, ¿quieres importar tu base de datos existente?

Lo que hago es:

php app/console doctrine:mapping:convert xml ./src/App/MyBundle/Resources/config/doctrine/metadata/orm --from-database --force

Luego haz una conversión selectiva a anotación:

php app/console doctrine:mapping:import AppMyBundle annotation --filter="users_table"

Si quería yml, cambie la anotación a yml.

advertencia: cuando importe a la anotación o yml, eliminará su archivo de entidad actual.


Tenga en cuenta que --filter en su comando debe completarse con el nombre de la clase de entidad y no el nombre de la tabla . Si la entidad aún no existe, el nombre de la clase de entidad debe complementar su nombre de tabla. Entonces, si su tabla es user_table , el valor del filtro sería UserTable .

Y luego, para evitar que su base de datos tenga algunas tablas que Doctrine no puede manejar, debe incluir en la lista blanca las tablas que desea permitir que administre Doctrine. Puede hacer esto en su archivo de configuración, por ejemplo:

doctrine: dbal: # ... schema_filter: /^(users_table|emails)$/

alternativamente puede especificar esto en su archivo cli-config.php.

/** @var Doctrine/ORM/Configuration $config */ $config->setFilterSchemaAssetsExpression(''/^(users_table|email)$/'');


php bin/console doctrine:mapping:convert xml ./src/NameBundle/Resources/doctrine/metadata/orm php bin/console doctrine:mapping:import NameBundle yml php bin/console doctrine:generate:entities NameBundle