【问题标题】:Symfony2 - cannot update doctrine schema. Base table or view already existsSymfony2 - 无法更新学说模式。基表或视图已存在
【发布时间】:2019-01-03 04:53:09
【问题描述】:

我有两个独立的 Symfony 项目使用一个数据库。 第一个项目在 Symfony 3.2 上,第二个项目在 Symfony 2.8 上。 数据库是 MySQL。 一切都在生产阶段,一切正常。

现在我在第一个项目中有一些实体类,而在第二个项目中没有。我们以前不需要第二个项目中的实体,但现在我需要在第二个项目中使用它们。

我将实体从第一个项目复制到第二个项目。我们使用注释。

在此之后,我检查了我的数据库并在第二个项目上执行了命令: 应用程序/控制台原则:架构:更新 --force 并得到错误:基表或视图已经存在:1050 表'crm_user'已经存在。 如果我使用 --dump-sql 选项(app/console dictionary:schema:update --dump-sql)执行命令,我会看到创建的表已经存在!

CREATE TABLE crm_user (id INT AUTO_INCREMENT NOT NULL, ...

所以学说模式更新没有看到数据库表已经创建。如何解决? 我试图清除所有缓存(缓存:清除),学说元数据缓存(学说:缓存:清除元数据),查询缓存(学说:缓存:清除查询)并没有成功。在此之后我得到了同样的错误。 如果我尝试验证学说架构,则不会有新表。 当然,我不能删除表数据,因为一切都处于生产阶段。

可能有人遇到过这样的问题。我很感激任何建议。

【问题讨论】:

    标签: php mysql symfony doctrine-orm doctrine


    【解决方案1】:

    我强烈建议不要像这样处理两个不同的项目和一个数据库。如果您需要,那么只需让一个成为您进行修改的 Doctrine “大师”,并且只有在那里运行 schema:update。 比这更好,更优雅的方式是创建一个可以使用 composer 导入的供应商,它是您的 Doctrine 实体供应商。 然后,这将管理所有数据库/存储库,您可以将其重新用于许多仅在一个地方具有代码的不同项目。

    在我看来,这将解决这个问题并解决你没有做对的事情: 有重复的实体指向同一个数据库结构,维护起来总是很痛苦,而且它不能很好地处理 KISS 原则和代码重复。

    【讨论】:

    • 感谢您的建议。好点子。在工作项目中实施并不容易,但可能我们会尝试。实际上我的问题出在之前完成的项目配置中。这是表的过滤器所在的原则:dbal:schema_filter 选项。
    【解决方案2】:

    如果您无法像 Jason 建议的那样通过 composer 使用共享项目包含 orm 定义,您可以创建一个正则表达式来过滤每个应用程序应该关注哪些表。

    zend 表达式示例:

    /**
     * @var \Doctrine\ORM\EntityManager $em
     */
    $em = $container->get('doctrine.entity_manager.orm_default'); // substitute with how you get your entity manager 
    $filter = 'crm_user|other_table|another_table';
    $em->getConnection()
       ->getConfiguration()
       ->setFilterSchemaAssetsExpression('/'.$filter.'/');
    

    动态...

    /**
     * @var \Doctrine\ORM\EntityManager $em
     */
    $em = $container->get('doctrine.entity_manager.orm_default');
    $metadata = $em->getMetadataFactory()->getAllMetadata();
    if(!empty($metadata)){
        $filter = '';
        /**
         * @var \Doctrine\ORM\Mapping\ClassMetadata $metadatum
         */
        foreach($metadata as $metadatum){
            $filter .= ($metadatum->getTableName().'|');
            $assocMappings = $metadatum->getAssociationMappings();
            if(!empty($assocMappings)){
                // need to scoop up manyToMany association table names too
                foreach($assocMappings as $fieldName => $associationData){
                    if(isset($associationData['joinTable'])){
                        $joinTableData = $associationData['joinTable'];
                        if(isset($joinTableData['name']) && strpos($filter, $joinTableData['name']) === false){
                            $filter .= ($joinTableData['name'].'|');
                        }
                    }
                }
            }
        }
        $filter = rtrim($filter, '|');
        $em->getConnection()->getConfiguration()
            ->setFilterSchemaAssetsExpression('/'.$filter.'/');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 1970-01-01
      相关资源
      最近更新 更多