使用Symfony2和Doctrine从现有数据库生成单个实体

66

是否可以使用Symfony2控制台工具从数据库生成单个实体?

在编码过程中,我不得不添加一个表格,并对现有实体类进行修改。因此,我不想重新生成所有实体。

欢迎提出任何建议!


1
许多人似乎仍然在处理没有主键的表格数据库时遇到问题 - “--filter”仍会读取这些表格,并失败。使用doctrine.yaml配置:doctrine.dbal.connections.CONNECTION_NAME.schema_filter: ~^(table_prefix_name_).*~或使用正则表达式跳过特定表格。 - Alister Bulman
12个回答

111

我遇到了同样的问题,你需要这样做:

php app/console doctrine:mapping:convert metadata_format \
    ./src/App/MyBundle/Resources/config/doctrine \
    --from-database \
    --filter="Yourtablename"

那么

php app/console doctrine:mapping:import AppMyBundle \
    metadata_format --filter="Yourtablename"

其中metadata_format是您要生成的文件格式结尾(例如xml、yml、annotation)

最后

php app/console doctrine:generate:entities AppMyBundle --no-backup

这样的教条只会加载你所需的实体。只要小心使用驼峰式过滤器即可!

希望这能对你有所帮助。


14
很高兴为您翻译。您需要注意一下过滤器,它非常“敏感”。例如,如果设置 --filter="mytable" ,Doctrine 将选择以“mytable”开头的所有表格,而不仅仅是名为“mytable”的表格(我也曾遇到这个问题)。虽然我在这个问题上遇到了一些困难,但我很乐意帮助您。 - Snroki
2
@Coussinsky 这个方法可以用,但是我有一个小问题:--filter=MyTable 不起作用。如果我移除这个选项,我会得到数据库中的所有表,如果我加上这个选项,我会得到:"No Metadata Classes to process.",你有什么想法吗?http://stackoverflow.com/questions/13629959/generate-entities-with-doctrine-into-separate-namespace - Phill Pafford
2
你忘记了引号,应该这样写:--filter="MyTable"。 - Snroki
7
whateveryouwant 是什么? - Jake Berger
12
如果数据库中包含没有主键的表,即使您的筛选器包含一个具有主键的表,这种方法似乎不起作用。有什么想法吗? - codecowboy
显示剩余6条评论

31

第三个命令中,Doctrine 一直在重新生成所有实体文件。通过在 bundle 后添加实体名称,它只会生成我感兴趣的实体。

php app/console doctrine:generate:entities AppMyBundle:Yourtablename --no-backup

2
它应该被包含在最佳答案中,因为Doctrine重新生成了我约300个实体。 - Bonswouar
3
实际上,如果我使用这个命令,就会出现“Namespace"VENDOR\MyBundle\Entity\TableName"不包含任何映射的实体”的错误提示。而如果我使用完整的“doctrine:generate:entities”命令,则会重新生成除新实体以外的所有实体......我做错了什么?! - Bonswouar
2
这对我也不起作用。它从我所有的包中生成实体。 - user2268997
1
无法打开输入文件:app/console - Dennis
@Dennis 确保你在项目的根目录下。当你执行ls/dir命令时,应该有一个名为“app”的目录。 - jpb

14

对于Symfony 2.7选项注释和[/xml/yml]的简单工作解决方案,请参见http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html

3个步骤中执行3个命令:

$ php app/console doctrine:mapping:import --force AppBundle xml --filter="Meeting"

注意: 如果您的数据库名称是 my_meeting,则需要在 filter="MyMeeting" 中将其更改为 MyMeeting ,以便Doctrine找到您的表名。这是因为Doctrine始终会删除下划线并将驼峰式添加到您的表名中。如果没有更改,则会出现以下错误:“数据库没有任何映射信息”。)

$ php app/console doctrine:mapping:convert annotation ./src/AppBundle/Entity --from-database --filter="Meeting"

(注意:请确保在您的Meeting.php类文件中像下面这样添加namespace AppBundle\Entity;

<?php
/**
* Created by PhpStorm.
* User:
* Date: 03-Sep-2015
* Time: 3:23 PM
*/
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
如果不存在,请添加它。
其中:
- AppBundle 正好是你在 Symfony 2.7 中的 "AppBundle"。 - Meeting 是目标表(大小写敏感)。
请确保检查此目录:
src\AppBundle\Resources\config\doctrine\Meeting.orm.xml
并确保您只有要创建实体类文件的表的 .xml 文件,而没有其他文件。然后运行以下命令为您先前创建的实体类生成 get 和 set 方法:
$ php app/console doctrine:generate:entities AppBundle:Meeting --no-backup 注意2: 作为最后一步,您必须删除xml doctrine orm db文件,例如 `src\AppBundle\Resources\config\doctrine\VisitorData.orm.xml`。
这对我非常有效。
有关说明,请阅读:http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html

9

目前隐藏的@fyrye的评论值得一提,我想加上这个让其他人不会错过。这是做法:

/** @var \Doctrine\DBAL\Connection $connection */
$config = $connection->getConfiguration();

// for excluding an specific table
$config->setFilterSchemaAssetsExpression('/^(table_to_reverse_engineer_1|table_to_reverse_engineer_2).*$/');

来源: https://coderwall.com/p/jofhdw/doctrine-tell-which-tables-to-work-with

我在运行以下命令时遇到了问题,因为存在大量定义不良的旧表。

php ./vendor/bin/doctrine orm:convert-mapping --force --from-database annotation ./src/UI/Entity/

原来,--filter标志只在读取所有表的元数据后进行过滤,如果这些表没有主键或存在其他问题,将导致命令失败。


你在哪里添加 setFilterSchemaAssetsExpression() 调用?你是修改 Symfony 或 Doctrine 的核心文件吗? - mHouses
好问题,我实际上记不清了!我认为有一个引导文件或称为cli-config.php的东西,./vendor/bin/doctrine文件使用 - 请参见http://doctrine-orm.readthedocs.org/en/latest/reference/configuration.html#setting-up-the-commandline-tool,这有帮助吗? - Carlton
2
在Symfony2.3+中,如果要编辑@mHouses,则更容易编辑您的app/config/config.yml以包括schema_filter选项,该选项调用setFilterSchemaAssetsExpression。请参见:http://symfony.com/doc/current/reference/configuration/doctrine.html - Will B.
doctrine: dbal: connections: user_db: schema_filter: /^(oauth_)/ - Alister Bulman

6

在使用Symfony 3时,没有一个答案完全适合我。最终我做了以下操作:

php bin/console doctrine:mapping:import --force MyBundle xml --filter="MyTable"

php bin/console doctrine:mapping:convert annotation ./src --filter="MyTable"

php bin/console doctrine:generate:entities MyBundle:MyTable --path ./src

4

我本想把这个作为对已接受答案的评论,但我是新手。

对于像我一样在使用 --filter 开关时,由于表名中存在相同字符串而映射多个表格的人,可以使用模式。

例如,表名如下:

Vendor(供应商) VendorContact(供应商联系人)

php app/console doctrine:mapping:convert metadata_format \
    ./src/App/MyBundle/Resources/config/doctrine \
    --from-database \
    --filter="Vendor"

该命令将转换两个表而不仅仅是Vendor。如果您只想要Vendor而不是VendorContact,请在--filter中使用一个模式:

php app/console doctrine:mapping:convert metadata_format \
    ./src/App/MyBundle/Resources/config/doctrine \
    --from-database \
    --filter="\bVendor\b"

希望这能对某些人有所帮助!

这就是我一直在寻找的答案。我漏掉了反斜杠b! - Chinmay

3
--filter 使用的是实体名称,而不是表名称! php bin/console doctrine:mapping:import "App\Entity" annotation --path=config/doctrine --filter="你的实体名"

3

这个工具也能很好地运作于Symfony 3。

如果您遇到“没有需要处理的元数据类”提示,请尝试将您的表名转换为Doctrine驼峰命名法并在filter参数中使用。

例如,“my_table_name”应该写成“MyTableName”。


没错!第一次尝试时我遇到了错误,但是当我以驼峰命名方式编写实体名称时,一切都变得正确了。 - Jerzy Drożdż

2

针对Symfony 3

生成一个新的"Group"表的实体

最初的回答:

php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/AppBundle/Entity --filter Group

"最初的回答",根据Symfony 3文档所述,需要进行Doctrine反向工程。请参考Symfony 3文档

enter image description here


1
我在Symfony 2.4和MySQL上遇到了完全相同的问题。以上提到的所有解决方法都没有对我起作用。最终,我创建了一个新的数据库,并使用MySQL提供的创建脚本创建了所需的表格。然后,将连接更改为该新数据库,并从那里执行实体提取命令。这似乎有些激进,但我不想手动创建实体。希望这可以帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接