How to generate Entities from an Existing Database in Symfony 2.1

I was trying to generate Symfony 2.1 entities from an existing MySQL database according to the instructions in the current documentation. I was supposed to be done with three simple commands, but it turned out to be somewhat more difficult than that.

Fix your config

First of all: this converter doesn’t support some basic MySQL data types by default, so you have to edit your config.yml file as follows:

#Doctrine Configuration
doctrine:
    dbal:
        mapping_types:
            enum: string
            bit: integer

You might need to add some others, too, as Doctrine doesn’t support any of these: BIT, BINARY, VARBINARY, TINYBLOB, MEDIUMBLOB, BLOB, LONGBLOB, ENUM, SET, GEOMETRY, POINT, MULTIPOINT, LINESTRING, MULTILINESTRING, POLYGON and MULTIPOLYGON.

Fix your database

Next, make sure all your database tables have primary keys; OK, that might sound obvious, but I had some odd old tables (which I wasn’t going to use in this project) lying around in the database. Apparently there is no way to specify that to the converter that you want to use only some tables.

Run the commands

doctrine:mapping:convert

First of all, the documentation tells you to run the following command:

php app/console doctrine:mapping:convert yml ./src/Miro/KPBundle/Resources/config/doctrine/metadata/orm --from-database --force

They forget to update the documentation when the directory structure has changed at some stage (2.0?), so the target folder should be ./src/Miro/KPBundle/Resources/config/doctrine. Secondly, you really need to tell the command what namespace these entities will be using, otherwise you will have to edit the yaml files yourself to add it. Therefore, the correct command in my case is:

php app/console doctrine:mapping:convert yml ./src/Miro/KPBundle/Resources/config/doctrine --from-database --force --namespace="Miro\KPBundle\Entity\\"

I figured out the correct command after some trial and error. Note the double “\\” at the end, that’s in Windows. If you’re using Linux, you probably need to add some more backslashes.

The command create yaml files which are otherwise perfect, except that they are named like this:

Miro.KPBundle.Entity.BkAccount.orm.yml

doctrine:mapping:import

The second command to run was:

php app/console doctrine:mapping:import MiroKPBundle annotation

It’s supposed to create entity classes for your database tables, and I suppose it does do that;  it just doesn’t care about the .yml files created by the previous command. So now I have entities for all tables in my database. No problem, I just delete the ones I don’t want.

Since I didn’t create foreign keys in the tables (as MySQL doesn’t use them anyway), I had to edit the .yml files to tell Symfony/Doctrine how the tables/entities should be related to eachother. Not a problem, except that I didn’t seem to find any documentation for the file format, only some examples of what they should look like.

doctrine:generate:entities

Once I’d figured out the correct syntax, it was time to run the final command:

php app/console doctrine:generate:entities MiroKPBundle

This gives the not so informative error message:

Generating entity "Miro\KPBundle\Entity\BkAccount"

[Doctrine\Common\Persistence\Mapping\MappingException]

Invalid mapping file 'Miro.KPBundle.Entity.Miro.KPBundle.Entity.BkAccount.orm.yml' for class 'Miro\KPBundle\Entity\BkAccount'.

doctrine:generate:entities [--path="..."] [--no-backup] name

So there is a problem in the file somewhere. And not just in one file, they all gave the same error. Was I supposed to rename the files like Miro.KPBundle.Entity.Miro.KPBundle.Entity.BkAccount.orm.yml’? That didn’t seem right, especially since it wasn’t exactly a ‘file not found’ error. Anyway, by trial-and-error I figured out the correct file name was simply ‘BkAccount.orm.yml’.

The command is incorrectly named IMO, since you already created the entities with the previous command (if you told it to create annotations like I did). All this command does is add getters and setters for the table columns.