66

Is it possible to generate a single entity from database using the Symfony2 console tool?

In the middle of coding I had to add a table and there are modifications made to the existing entity classes. So I don't want all my entities regenerated.

Any suggestions will be appreciated!

Phill Pafford
  • 83,471
  • 91
  • 263
  • 383
Sethunath K M
  • 4,702
  • 3
  • 28
  • 42
  • 1
    Many people still appear to have issues with a database that has tables without primary keys - '--filter' still reads those tables, and fails. Use the doctrine.yaml config: `doctrine.dbal.connections.CONNECTION_NAME.schema_filter: ~^(table_prefix_name_).*~` or use the regex to skip specific tables – Alister Bulman Aug 12 '19 at 16:01

12 Answers12

111

I had the same problem, you've to do this way:

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

Then

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

Where metadata_format is the file ending you want to generate (e.g. xml, yml, annotation)

And finally

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

Like this doctrine will load only the entity you need. Just be carefull on the filter you must use the CamelCase !

Hope this will help you

SirDerpington
  • 11,260
  • 4
  • 49
  • 55
Snroki
  • 2,424
  • 1
  • 20
  • 28
  • Great ! It helped . Glad to award you the well deserved bounty pal. Thanks! – Sethunath K M May 20 '12 at 06:11
  • 14
    my pleasure, i had some bad times on this issue. Just be carefull to the filter it's quite "sensible" like if you set `--filter="mytable"` doctrine will take all tables begining by "mytable" and not just the table named "mytable" (had this problem too). – Snroki May 21 '12 at 08:24
  • 2
    @Coussinsky This works except I have one small issue: --filter=MyTable doesn't work. If I remove the option I get all the tables in the database, if I add the option I get: "No Metadata Classes to process.", Thoughts? http://stackoverflow.com/questions/13629959/generate-entities-with-doctrine-into-separate-namespace – Phill Pafford Dec 05 '12 at 18:07
  • 2
    you forget the " you've to write it this way : --filter="MyTable" – Snroki Dec 06 '12 at 13:12
  • 7
    what is `whateveryouwant` ? – Jake Berger Sep 05 '13 at 04:16
  • 1
    the whateveyouwant is the format of the mapping file (can be xml, yml or annotation) see : http://docs.doctrine-project.org/en/latest/reference/basic-mapping.html – Snroki Sep 05 '13 at 11:47
  • 12
    This doesn't seem to work if the database contains tables without a primary key, even if your filter contains a table which does have a primary key. any ideas? – codecowboy Feb 13 '14 at 16:30
  • 1
    "Whateveryouwant" is not a good parameter name, as it does not convey the meaning of the parameter. This parameter should be called "MappingType", and I believe that valid values are: xml, yml, and php. – Don Briggs Jun 09 '14 at 18:45
  • I use this command but it does not work: **php app/console doctrine:mapping:convert yml ./src/Acme/BookB undle/Resources/config/doctrine --from-database --filter="book" --em=book_db**, My "book_db" contains many book related tables. I want to generate entity only for "book" table and update only this table in future (Just consider other tables as dynamic, may have different fields and different data inside them). But the above command does not work. Could anybody point out what I am doing wrong? – webblover Sep 01 '14 at 17:06
  • 1
    **Comment Continuation:** I get this error "No Metadata Classes to process.", though I have primary key in all tables and they are of simple column definitions in them. – webblover Sep 01 '14 at 17:10
  • 1
    @webblover I had the same issue. I ended up using `$config->setFilterSchemaAssetsExpression('^(table|table2|table3)$')` instead. In addition I edited `\Doctrine\ORM\Tools\Export\Driver\AbstractExporter::export()` to `continue;` when the file exists instead of throwing an exception. This way any existing entities I have are not modified and those added to the filter are included. Wish they would add a flag for `--skip` to not overwrite instead of `--force` to overwrite. – Will B. Jan 14 '15 at 19:56
31

For the third command, doctrine kept regenerating all of the Entity files. By adding the entity name after the bundle, it only generated the entity I was interested in.

php app/console doctrine:generate:entities AppMyBundle:Yourtablename --no-backup
jpb
  • 356
  • 4
  • 4
  • 2
    It should be included in the top answer, because of that Doctrine re-generated all my ~300 entities. – Bonswouar Feb 20 '14 at 10:24
  • 3
    Actually, If I use this command, I have `Namespace "VENDOR\MyBundle\Entity\TableName" does not contain any mapped entities.`, and if I use the full `doctrine:generate:entities` it re-generate all my entities except the new one... What am I doing wrong ?! – Bonswouar Feb 20 '14 at 11:00
  • 2
    this doesn't work for me either.it generates entities from all my bundles. – user2268997 Aug 04 '14 at 07:06
  • 1
    "Could not open input file: app/console" – Dennis Feb 19 '19 at 16:53
  • @Dennis Make sure you're in the root of the project. There should be an "app" directory when you do an ls/dir command. – jpb Mar 05 '19 at 00:33
14

Simple Working Solution for Symfony 2.7 option annotation and for [/xml/yml] see http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html

do 3 commands in 3 steps:

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

(NOTE: if your database name is my_meeting You will need to change it to MyMeeting in filter="MyMeeting" for doctrine to find your table name. This is because doctrine will always strip underscores and add Camel-case to your table name. If not, you will get this error: "Database does not have any mapping information".)

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

(NOTE: making sure you have namespace AppBundle\Entity; as below in your Meeting.php class file like this:

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

use Doctrine\ORM\Mapping as ORM;

If not add it in.)

where:

  • AppBundle is exactly your "AppBundle" in Symfony 2.7
  • Meeting is the target table (Camel-Case sensitive)

TO BE SURE, check this directory:

src\AppBundle/Resources/config/doctrine/Meeting.orm.xml

AND MAKING SURE you only have .xml files for the table you want to create entity class files and no others. Then run this below command to generate get and set methods for your entity class that you created previously

$ php app/console doctrine:generate:entities AppBundle:Meeting --no-backup

NOTE2: As the last step you must delete the xml doctrine orm db file in for example src\AppBundle/Resources/config/doctrine/VisitorData.orm.xml

It works very well for me.

For explanation please read: http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html

BlitZ
  • 12,038
  • 3
  • 49
  • 68
Dung
  • 19,199
  • 9
  • 59
  • 54
9

@fyrye's comment that is currently hidden deserves the credit, wanted to add this so it's not missed by others. This is the approach:

/** @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).*$/');

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

I was having issues when running the following command because of large number of badly defined legacy tables

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

It turns out that the --filter flag only filters AFTER it has read meta data from all of your tables which, if they don't have primary keys or have some other issue, will cause the command to fail

Carlton
  • 5,533
  • 4
  • 54
  • 73
  • where do you add the `setFilterSchemaAssetsExpression()` call? Are you modifying the core Symfony or Doctrine files? – mHouses May 22 '15 at 09:30
  • Good question I can't actually remember! I think there's a bootstrap file or something called cli-config.php that the ./vendor/bin/doctrine file use - see http://doctrine-orm.readthedocs.org/en/latest/reference/configuration.html#setting-up-the-commandline-tool does that help? – Carlton May 22 '15 at 10:27
  • 2
    @mHouses in Symfony2.3+ it would easier to edit your `app/config/config.yml` to include the `schema_filter` option which invokes `setFilterSchemaAssetsExpression` see: http://symfony.com/doc/current/reference/configuration/doctrine.html – Will B. Nov 19 '15 at 16:10
  • `doctrine: dbal: connections: user_db: schema_filter: /^(oauth_)/` – Alister Bulman Aug 12 '19 at 15:50
6

None of the answers were quite right for me using Symfony 3. I ended up doing:

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
Brett Thomas
  • 161
  • 3
  • 7
4

I would have left this as a comment to the accepted answer but I'm a newbie.

For those like me who had trouble with the --filter switch mapping multiple tables with coincident strings in names, one can use a pattern.

Example table names:

Vendor VendorContact

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

That command will convert both tables rather than just Vendor. If you want just Vendor and not VendorContact, use a pattern in --filter:

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

Hope that helps someone!

peej
  • 61
  • 4
3

Works great with Symfony 3 too.

If you are getting "No Metadata Classes to process." message try convert your tablename to Doctrine camel casing in the filter parameter.

"my_table_name" needs to be write as "MyTableName".

Ivo Necchi
  • 43
  • 3
  • Exactly! On first time when I was try I got errors, but when I wrote entity name in camel case style then everything goes right. – Jerzy Drożdż Nov 27 '17 at 22:41
3

--filter works with entity name, not table name ! php bin/console doctrine:mapping:import "App\Entity" annotation --path=config/doctrine --filter="YourEntity"

2

for Symfony 3

To generate the entities for a new "Group" table

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

enter image description here

as written in the symfony 3 documentation

max4ever
  • 11,909
  • 13
  • 77
  • 115
1

I had exactly the same issue with Symfony 2.4 and MySQL.

None of the workarounds posted above worked for me.

I ended up creating a new database with the tables I want to extract (this can be easy to do because MySQL provides the creation script).

Then changed the connection to that new database and executed the entity extraction command from there.

Seems to be a bit radical, but I will not create the entities by hand.

Hope that helps

Nicolas
  • 1,320
  • 2
  • 16
  • 28
1

Didn't work any of these for my symfony 3.3. So I just created a copy of directory and re-generated all of the entities in copy directory. Then I copied required entities in my original directory.

--filter does not work due to this issue https://github.com/symfony/symfony/issues/7717

hanish singla
  • 782
  • 8
  • 21
1

Since 2019 doctrine has deprecated the reserve-engineering functionality, and it is therefore not recommended to use it any more. Instead, Symfony recommends to use make:entity from the Symfony Maker Bundle instead.

Michel Rummens
  • 459
  • 3
  • 9
  • Yes, although the Symfony Maker bundle doesn't do reverse engineering on an existing table that I can see. Looks like there's no alternative, so I'm sticking with the old import, then using rector to translate to attributes instead of annotations – Jonathan Clark Feb 17 '23 at 15:56