2016-12-13 1 views
0

J'essaie de créer une association entre 2 entités. Le gauche est une représentation de table. Le droit est une représentation de vue.Doctrine 2 et MySQL: mappage d'association entre une table et une vue

Je viens de réussir à faire fonctionner cette relation, mais j'ai un problème lors de la création du schéma avec php vendor/bin/doctrine orm:schema-tool:create.

Ci-dessous est tout le code nécessaire pour l'essayer:

SQL

CREATE TABLE IF NOT EXISTS `demo` (
    `id` int(11) NOT NULL, 
    `name` varchar(30) COLLATE utf8_unicode_ci NOT NULL 
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

INSERT INTO `demo` (`id`, `name`) VALUES 
(1, 'demo 1'), 
(2, 'demo 2'), 
(3, 'demo 3'), 
(4, 'demo 4'); 

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `demo_metadata` AS select `se`.`id` AS `demo_id`,12 AS `demo_count` from `demo` `se`; 

Demo Table Entité

/** 
* @Entity 
* @Table(name="demo") 
*/ 
class Demo { 

    /** 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue 
    */ 
    private $id; 

    /** 
    * @Column(type="string", length=30) 
    */ 
    private $name; 

    /** 
    * @OneToOne(targetEntity="DemoMetadata") 
    * @JoinColumn(name="id", referencedColumnName="demo_id") 
    */ 
    private $metadata; 

    public function getMetadata() { 
     return $this->metadata; 
    } 
} 

Demo Voir Entité

/** 
* @Entity 
* @Table(name="demo_metadata") 
*/ 
class DemoMetadata { 

    /** 
    * @Id 
    * @Column(type="integer") 
    * @var int 
    */ 
    private $demo_id; 

    /** 
    * @Column(type="integer") 
    * @var int 
    */ 
    private $demo_count; 

    public function getDemoCount() { 
     return $this->demo_count; 
    } 
} 

Query et la récupération des donnéesComme nous pouvons le voir, la propriété de métadonnées de l'entité de démonstration est remplie avec les données de la vue. Tout fonctionne bien et comme prévu.

Mais avec une telle configuration, lors de l'exécution de la commande cli pour supprimer le schéma, puis le recréer, une erreur se produit car la table demo_metadata existe déjà. En fin de compte, je ne cherche pas un moyen de créer automatiquement la vue. J'ai des scripts SQL que je peux appeler pour créer la vue. Je me demande s'il existe un moyen de ne pas essayer de créer la table pour certaines entités?

[Doctrine\ORM\Tools\ToolsException]                                            
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8 _unicode_ci ENGINE = InnoDB':                                             
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'demo_metadata' already exists' while executing DDL: CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB 

Il est juste une question de commodité, parce que les points de vue existent déjà et ne sont pas supprimées avec la commande drop cli.

Est-ce que la seule façon de gérer est de:

  1. schéma goutte (la doctrine de cli)
  2. supprimer demo_metadata vue
  3. créer le schéma (doctrine cli)
  4. retirer demo_metadata Table
  5. créer demo_metadata afficher

Merci

Modifier

En fin de compte, j'ai utilisé ce code pour filtrer les entités que je avais besoin:

<?php 

class UpdateSchema extends \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand { 

    /** 
    * {@inheritdoc} 
    */ 
    protected function executeSchemaCommand(
     InputInterface $input, 
     OutputInterface $output, 
     SchemaTool $schemaTool, 
     array $metadatas) : int 
    { 
     $entities = array_filter($metadatas, function ($m) { 
      return !$m->isReadOnly; 
     }); 
     return parent::executeSchemaCommand($input, $output, $schemaTool, $entities); 
    } 
} 

Répondre

0

En plus de create et drop commandes, il y a aussi un update commander.C'est celui que vous devriez utiliser si la base de données existe déjà

Mauvaise réponse, voir les commentaires pour corriger

+0

J'ai essayé avec 'update' que vous proposez, mais même si une vue existe avec le nom' demo_metadata', le mécanisme de mise à jour essaye de créer une nouvelle table 'demo_metadata' et une erreur se produit. Je suis obligé de supprimer la vue, faire la mise à jour, supprimer la "mauvaise" table et recréer la vue ... – rekam

+0

Mon mauvais, n'a pas lu la question correctement pressé. Cette question est ce que vous demandez probablement: http://stackoverflow.com/questions/12563005/ignore-a-doctrine2-entity-when-running-schema-manager-update – Xymanek

+0

ok, merci! Je dois admettre que j'aurais préféré une solution via des annotations, comme @Table (nogenerate = true), mais le remplacement de la mise à jour de cli fonctionne parfaitement! Et cela m'aide finalement à poser ma question sous un meilleur angle. Merci – rekam