6

I often change/add some field in Entity and using bin/console make:migration to generate migrations, that's convenience just like in Rails or Django. But I do not need Foreign Key Constraint when I am using Doctrine Relationships(ManyToOne, OneToMany...).

I have to delete lines contained Foreign Key Constraint in generated migrations. But When I doing some changes with Entity, and run bin/console make:migration, It will add Foreign Key Constraint again, it is annoying.

I do not care about data consistency.

In Django model ForeignKey you can set db_constraint=False, so migration would not generate Foreign Key constraint.

Is there some similar setting in Doctrine?

yivi
  • 42,438
  • 18
  • 116
  • 138
Moon soon
  • 2,616
  • 2
  • 30
  • 51
  • I'm sorry but there is really no built-in method in Doctrine to do this, as I say in my answer. If you really want no FKs and want to use doctrine to generate the schema automatically; you'll have to delete the statements manually. – yivi Aug 12 '19 at 10:37
  • 1
    but it will auto generate `Foreign Key Constraint` again and again when I create/change some entities migrations – Moon soon Aug 12 '19 at 13:11
  • Yes, it will. If you use Doctrine to generate modify the schema, these FK constraints will be generated. Again, Doctrine does not support association mapping without using FKs on relational backends, as I said in my answer. – yivi Aug 12 '19 at 13:12
  • you can do that with some code in a listener attached to `postGenerateSchema` event. See my answer. – ste Aug 14 '19 at 07:59

3 Answers3

7

Why don't you just do the following?

$this->addSql('SET foreign_key_checks = 0');
// all SQL statements
$this->addSql('SET foreign_key_checks = 1');

This works.

D4V1D
  • 5,805
  • 3
  • 30
  • 65
5

Doctrine doesn't support this natively, but you can do that with an event listener on postGenerateSchema event.

// src/Doctrine/IgnoreFksListener.php

namespace App\Doctrine;

use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;

/**
 * see http://kamiladryjanek.com/en/ignore-entity-or-table-when-running-doctrine2-schema-update-command/
 */
class IgnoreFksListener
{

    /**
     * Remove fks from Schema
     * This listener is called when the schema has been generated (from mapping data of entities)
     *
     * @param GenerateSchemaEventArgs $args
     */
    public function postGenerateSchema(GenerateSchemaEventArgs $args)
    {
        $schema = $args->getSchema();
        $em = $args->getEntityManager();

        foreach ($schema->getTables() as $table) {
            $fks = $table->getForeignKeys();
            foreach ($fks as $fk) {
                $table->removeForeignKey($fk->getName());
//              dump('removed FK '.$fk->getName().' from '.$tabel->getName().' pointing to '.$fk->getForeignTableName().'.['.implode(', ', $fk->getForeignColumns()).']');
            }
        }
    }
}

And you have to register the listener in services.yaml

    App\Doctrine\IgnoreFksListener:
        tags:
            - {name: doctrine.event_listener, event: postGenerateSchema }

here you can find another example http://kamiladryjanek.com/en/ignore-entity-or-table-when-running-doctrine2-schema-update-command/

ste
  • 1,479
  • 10
  • 19
0

Doctrine does not support this.

If you are using a relational back-end and declare association mappings between your entities, the generated code will include the appropriate foreign keys.

You are not required to use that code. If the FKs does not exist Doctrine will continue working fine, as you've discovered.

I do not care about data consistency

Oh, to be young and care-fee. Good luck with that.

yivi
  • 42,438
  • 18
  • 116
  • 138
  • There are cases that FK cause performance issue due to unnecessary locking by the current design. https://stackoverflow.com/questions/49852942/mysql-insert-blocked-by-an-update-of-the-foreign-key-referenced-row I am also looking for a systematic way to disable this. Thanks for the answers that everyone contributes. – HelloSam Nov 15 '19 at 06:10