Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autogenerated migration keeps dropping and re-adding unrelated foreign keys #1483

Open
Menelion opened this issue Jan 9, 2025 · 0 comments

Comments

@Menelion
Copy link

Menelion commented Jan 9, 2025

Bug Report

Q A
BC Break no
Version 3.8.2

Summary

I'm using Symfony 7.2 and its Maker bundle. Under the hood the make:migration command calls doctrine:migrations:diff. For some reason, it keeps dropping and re-adding foreign keys on totally unrelated entities.
I'm using MariaDB 11.2.2 on this machine.

Current behavior

doctrine:migrations:diff drops and re-adds unrelated foreign keys (see steps to reproduce).

How to reproduce

  1. Either use make:entity in Symfony or add this entity manually:
<?php

namespace App\Entity;

use App\Repository\LanguageRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

#[ORM\Entity(repositoryClass: LanguageRepository::class)]
#[ORM\Table(name: 'languages')]
#[UniqueEntity(fields: ['code'], message: 'There is already a language with this code')]
class Language
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(type: Types::SMALLINT, options: ['unsigned' => true])]
    private ?int $position = null;

    #[ORM\Column(length: 20)]
    private ?string $code = null;

    #[ORM\Column(length: 100)]
    private ?string $englishName = null;

    #[ORM\Column(length: 100)]
    private ?string $nativeName = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getPosition(): ?int
    {
        return $this->position;
    }

    public function setPosition(int $position): self
    {
        $this->position = $position;

        return $this;
    }

    public function getCode(): ?string
    {
        return $this->code;
    }

    public function setCode(string $code): self
    {
        $this->code = $code;

        return $this;
    }

    public function getEnglishName(): ?string
    {
        return $this->englishName;
    }

    public function setEnglishName(string $englishName): static
    {
        $this->englishName = $englishName;

        return $this;
    }

    public function getNativeName(): ?string
    {
        return $this->nativeName;
    }

    public function setNativeName(string $nativeName): static
    {
        $this->nativeName = $nativeName;

        return $this;
    }
}
  1. Run doctrine:migrations:diff --formatted. I'm getting this:
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20250109223941 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Created languages table';
    }

    public function up(Schema $schema): void
    {
        $this->addSql('CREATE TABLE languages (
          id INT AUTO_INCREMENT NOT NULL,
          position SMALLINT UNSIGNED NOT NULL,
          code VARCHAR(20) NOT NULL,
          english_name VARCHAR(100) NOT NULL,
          native_name VARCHAR(100) NOT NULL,
          PRIMARY KEY(id)
        ) DEFAULT CHARACTER
        SET
          utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
        $this->addSql('ALTER TABLE reset_password_request DROP FOREIGN KEY FK_7CE748AA76ED395');
        $this->addSql('ALTER TABLE
           reset_password_request
        ADD
          CONSTRAINT FK_7CE748AA76ED395 FOREIGN KEY (user_id) REFERENCES users (id)');
    }

    public function down(Schema $schema): void
    {
        // this down() migration is auto-generated, please modify it to your needs
        $this->addSql('DROP TABLE languages');
        $this->addSql('ALTER TABLE reset_password_request DROP FOREIGN KEY FK_7CE748AA76ED395');
        $this->addSql('ALTER TABLE
          reset_password_request
        ADD
          CONSTRAINT FK_7CE748AA76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE');
    }
}

the reset_password_request migration for reference:

<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20250101232946 extends AbstractMigration
{
    public function getDescription(): string
    {
        return 'Added the reset password request table and isVerified column to the Users table';
    }

    public function up(Schema $schema): void
    {
        $this->addSql(
            'CREATE TABLE reset_password_request (
              id INT AUTO_INCREMENT NOT NULL,
              user_id INT NOT NULL,
              selector VARCHAR(20) NOT NULL,
              hashed_token VARCHAR(100) NOT NULL,
              requested_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\',
              expires_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\',
              INDEX IDX_7CE748AA76ED395 (user_id),
              PRIMARY KEY(id)
            )
            DEFAULT CHARACTER SET utf8mb4
            COLLATE `utf8mb4_unicode_ci`
            ENGINE = InnoDB
        ');

        $this->addSql(
            'ALTER TABLE
            reset_password_request
            ADD
            CONSTRAINT FK_7CE748AA76ED395 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
        ');

        $this->addSql('ALTER TABLE users ADD is_verified TINYINT(1) NOT NULL');
    }

    public function down(Schema $schema): void
    {
        $this->addSql('ALTER TABLE reset_password_request DROP FOREIGN KEY FK_7CE748AA76ED395');
        $this->addSql('DROP TABLE reset_password_request');
        $this->addSql('ALTER TABLE users DROP is_verified');
    }
}

Expected behavior

The reset_password_request table has nothing to do with this one at all, so it shouldn't be altered. There is no relations to users table either, it's just a standalone languages table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant