Say I have a Doctrine entity like so:
#[ORM\Entity]
#[ORM\Table(name: 'product')]
class Product
{
#[ORM\Id]
#[ORM\Column(type: DBALTYPES::INTEGER)]
#[ORM\GeneratedValue]
private int $id;
#[ORM\Column(type: DBALTYPES::STRING, length: 50)]
private string $sku;
...
}
I update the DB to match, and it goes into production. Now imagine I want to add a new OneToOne column, like so:
#[ORM\Entity]
#[ORM\Table(name: 'product')]
class Product
{
#[ORM\Id]
#[ORM\Column(type: DBALTYPES::INTEGER)]
#[ORM\GeneratedValue]
private int $id;
#[ORM\Column(type: DBALTYPES::STRING, length: 50)]
private string $sku;
#[ORM\OneToOne(targetEntity: Attribute::class)]
private Attribute $name;
public function __construct()
{
$this->name = new Attribute();
}
...
}
All existing Product
s were created before the $name
property was added, so updating the DB adds the name_id
column but leaves it defaulted to null
. This is a problem because $name
is a non-nullable property but it will be undefined except for newly-created products.
Is there a way to have Doctrine generate the required sub-models automatically when updating the DB with orm:schema-tool:update
? Or do I have to do this manually somehow?
I would suggest you create a migration console make:mig
final class Version20230613081942 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('UPDATE product SET name = (SELECT id FROM attribute LIMIT 1) WHERE name IS NULL;');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('UPDATE product SET name = NULL');
}
}
Adding an index to that column will also make the update faster
#[ORM\Table(indexes: new Index(name: 'index_name', columns: ['attribute_id']))]