这是我建议的解决方案,昨天在我的评论中我无法正确解释它。
当您运行doctrine-schema-update(或doctrine-migrations-diff,请参阅https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html),学说做了三件事:
- 它从映射信息(例如实体注释)生成模式,然后触发 postGenerateSchema 事件
- 它从当前数据库生成模式(通过逆向工程)
- 它比较两个生成的模式并生成第二个模式需要与第一个模式相同的 SQL 代码。
因此,如果您操纵第一个模式,您可以避免 Doctrine 做您不喜欢的事情。
在此示例中,我有一些实体实际上是数据库中的视图,而不是表。所以我告诉原则不要生成他们的表以及相关表上的所有 FK 约束。您可以轻松地从此工作脚本开始并适应您的需求。
此致。
这是AppBundle/Utils/IgnoreTablesListener.php
<?php
namespace AppBundle\Utils;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
class IgnoreTablesListener {
private $ignoredEntities = null;
private $ignoredTables = null;
public function __construct($ignoredEntities) {
$this->ignoredEntities=$ignoredEntities;
$this->ignoredTables=array();
}
/**
* Remove ignored entities from Schema
* This listener is called when the schema as been generated, from entities data mapping (i.e. in doctrine-schema-update or in doctrine:migrations:diff)
*
* @param GenerateSchemaEventArgs $args
*/
public function postGenerateSchema(GenerateSchemaEventArgs $args)
{
$schema = $args->getSchema();
$em = $args->getEntityManager();
$ignoredTables = $this->ignoredTables;
foreach ($this->ignoredEntities as $entityName) {
$ignoredTables[] = strtolower($em->getClassMetadata($entityName)->getTableName());
}
foreach ($schema->getTableNames() as $longTableName) {
$table=$schema->getTable($longTableName);
$table_name=strtolower($table->getShortestName($table->getNamespaceName()));
$fks=$table->getForeignKeys();
foreach ($fks as $fk) {
$foreign_table_name=strtolower($fk->getForeignTableName());
if (in_array($foreign_table_name, $ignoredTables)) { //if the fk points to one of the entities i'm ignoring
$table->removeForeignKey($fk->getName()); //i remove fk constrains from generated schema (NOT FROM MY CURRENT DB!!!)
// dump('removed FK '.$fk->getName().' from '.$table_name.' pointing to '.$foreign_table_name.'.['.implode(', ', $fk->getForeignColumns()).']');
}
}
if (in_array($table_name, $ignoredTables)) { //if i have to ignore the $table_name table
$schema->dropTable($longTableName); //remove the table from generated schema -- NOT FROM DB!!
// dump('removed ignored table/entity '.$longTableName);
}
}
}
}
这是服务配置(app/config/services.yml
)
..
app.ignoretableslistener:
class: AppBundle\Utils\IgnoreTablesListener
arguments: ['AppBundle:MyEntityToBeIgnoredBecauseItIsAView1', 'AppBundle:MyEntityToBeIgnoredBecauseItIsAView2']
tags:
- {name: doctrine.event_listener, event: postGenerateSchema }
..