告诉Doctrine SchemaTool不要删除未知的表


Tell Doctrine SchemaTool not to drop unknown tables

不好意思,我真的不知道该怎么称呼它,故事是这样的:

我已经将doctrine/orm作为一个库集成到Joomla3中,并且我已经创建了一个基于实体和存储库的组件。它真的很整洁!我实际上创造了一个J!名为JDoctrine的可安装库,它有一个获取EntityManager的入口点。比如:

require_once JPATH_ROOT."/libraries/jdoctrine/jdoctrine.php";
$JDO = new 'stdClass();
$JDO->configuration = new 'stdClass();
$JDO->configuration->type = "annotation";
$JDO->configuration->paths = [JPATH_ROOT."/administrator/components/com_something/Core/Entity"];
$JDO->configuration->isDevMode = false;
$JDO->connection = null;
$JDO->eventManager = null;
$em = 'JDoctrine::getEntityManager($JDO);

它拾取Joomla的db配置和表前缀,您可以使用实体。

我想发布这个库——也许其他人会发现它很有用——但是有一件事我不明白。

如果我这样做(这是我想在我的组件安装脚本):

$schemaTool = new SchemaTool($em);
$sqlArray = $schemaTool->getUpdateSchemaSql($classes, false);

我结束了一个数组的sql语句将创建/更新所有实体传递在$类和删除所有其他表。

现在,对于我的家用组件,我用一些非常丑陋的清理方法修复了这个问题,只保留了与我的实体相关联的表名的语句。

我想做的是"指示"学说忽略所有它不知道的表-也就是说-跳过所有没有实体关联的东西。什么好主意吗?

Jakabadambalazs我也使用Jdoctrine。我是新手。我只是通过joomla安装安装它。现在我可以在哪里放置上面的代码。如果您有任何示例,请指定路径

这真的很直接,答案是'显然'已经在那里了,因为Doctrine已经这样做了。这只是一个寻找和平的问题。

一般来说:您需要创建2个模式(Doctrine'DBAL'Schema'Schema),并将它们与比较器(Doctrine'DBAL'Schema'Comparator)进行比较,这将给您带来差异('Doctrine'DBAL'Schema'SchemaDiff)。然后在ShemaDiff上你可以调用:toSaveSql

Schema类有一个表列表。所以当你有$fromSchema和$toSchema并比较它们时:

    在$fromSchema中列出但在$toSchema中没有的表将被删除
  • $fromSchema中没有的表,但在$toSchema中列出的表将被创建
  • $fromSchema中列出的表和$toSchema中列出的表将被修改
  • 在$fromSchema和$toSchema中缺少的
  • 表将被…忽略;-)

那么,你可以这样做:

/** @var EntityManager $em */
$classes = $this->getArrayOfClassMetadataAboutYourEntities();
$em = $this->getAnEntityManagerFromSomewhere();
$sm = $em->getConnection()->getSchemaManager();
$st = new SchemaTool($em);
//FROM Schema
$tables = [];
foreach($classes as $class) {
  if(isset($class->table)&&isset($class->table["name"])) {
    $tables[] = $sm->listTableDetails($class->table["name"]);
  }
}
$sequences = ($sm->getDatabasePlatform()->supportsSequences()?$sm->listSequences():[]);
$fromSchema = new Schema($tables, $sequences, $sm->createSchemaConfig());
//TO SCHEMA - $classes is an array of ClassMetadata representing the entities
$toSchema = $st->getSchemaFromMetadata($classes);
//COMPARE
$comparator = new Comparator();
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
//DO SOMETHING
$sqlStatements = $schemaDiff->toSaveSql($sm->getDatabasePlatform());
foreach($sqlStatements as $sql) {
    $em->getConnection()->exec($sql);
}

PS:我在SO上写这段代码,小心拼写错误!