Doctrinebundle: Doctrine mapping import ignores filter when checking tables for primary keys

Created on 24 Jun 2015  路  20Comments  路  Source: doctrine/DoctrineBundle

I ran into an issue when importing a mapping from a single table. The database has some tables without primary keys which are not important for my import. So I use the filter parameter to get only the single table. But doctrine does a complete database check and throws a MappingException when scanning the table without the primary key.

console doctrine:mapping:import --em=customer --filter="tbl_users" AcmeHelloBundle xml

[Doctrine\ORM\Mapping\MappingException]
Table tbl_abc has no primary key. Doctrine does not support reverse engineering from tables that don't have a primary key.

I think it would be better if the mapping import only does the check on the mentioned table in the filter parameter und do the import.

Most helpful comment

if ( ! $table->hasPrimaryKey()) {
         continue;
}

:)

All 20 comments

I confirm the issue

+1

:+1:

As workaround I created a new database with just the table I wanted to import.

agree

+1

agree verymuch!!

If I remember well the table filter works if you use it on the connection directly.
Like this

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
            customer:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
                schema_filter: tbl_users

And I use the customer connection to create the customer entity manager

orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                mappings:
                            .....
            customer:
                connection: customer #Here comes the already filtered connection

Now you can just pass your custom entity manager (customer) with your filtered connection (customer) to the import command.

+1

+1 on this.

@mikeSimonson answer works, but you have to wrap the value with some delimiters like $, otherwhise you'll get Warning: preg_match(): Delimiter must not be alphanumeric or backslash

For Symfony 4, it works if you change your config/packages/doctrine.yaml file adding:

doctrine:
    dbal:
        schema_filter: $table_name_to_filter$

Then on console: ./bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity just as documentation says. Note that schema_filter must be the table_name not the EntityName.

Don't forget to comment or remove the param declaration after importing.

Hello,

why is this closed ? Yes, there are workarouds but isn't still a bug ? I tryed today, I have the same problem, I can't import good tables if bad tables exists in the DB.

+1
Please, fix this?

doctrine:mapping:import command is deprecated, hence we won't spend effort fixing bugs there

Any alternative for this command?

no

Ok, thank you for clarifying that.

Source ?

Anyway, working solution is to use the
schema_filter: ~^(?!bad_table_a|bad_table_b|bad_table_c|and_so_on)~

To ignore primary keys go to \vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\Driver\DatabaseDriver.php
Search for reverseEngineerMappingFromDatabase method and uncomment the the following part as follows

//if ( ! $table->hasPrimaryKey()) {
//  throw new MappingException(
//    "Table " . $table->getName() . " has no primary key. Doctrine does not ".
//    "support reverse engineering from tables that don't have a primary key."
    //);
//}
//$pkColumns = $table->getPrimaryKey()->getColumns();
//sort($pkColumns);

Add the following line $pkColumns = array(); after sort($pkColumns);

Then search for method getTablePrimaryKeys and comment everything inside it and return empty array.

if ( ! $table->hasPrimaryKey()) {
         continue;
}

:)

Was this page helpful?
0 / 5 - 0 ratings