运行 Symfony 迁移时添加数据

Add data when running Symfony migrations

我有一个使用 DoctrineMigrations 包的 Symfony 项目,我有一个非常简单的问题:当我 运行 迁移时(例如,当我将更新推送到生产环境时),如何才能我向数据库中插入数据?

例如:我有一个 Entity,它是一个 add 的类型。实体是:

private $addType; // String
private $type1;   // Boolean
private $type2;   // Boolean
private $type3;   // Boolean

我添加了另一个字段 ($type4),我想向数据库中添加一条新记录,其值为:

$addType = 'Type number 4';
$type1 = false;
$type2 = false;
$type3 = false;
$type4 = true;

如何使用 DoctrineMigrations 完成此操作?可能吗?

我刚问了一个相关的related question

可以使用迁移包将数据添加到数据库中。如果您添加一个新的 属性 并使用学说映射,那么

php app/console doctrine:migrations:diff

命令将生成一个新的迁移文件。您可以使用以下语法将插入语句放入此文件中:

$this->addSql('INSERT INTO your_table (name) VALUES ("foo")');

确保在自动生成的架构更改之后放置它。如果您想将模式更改和数据更改分开,那么您可以使用

php app/console doctrine:migrations:generate

创建一个空的迁移文件来放入您的插入语句。

正如我在相关问题中所说,这是一种方法,但如果您想更改数据库中的数据,则需要手动创建这些。

编辑:

由于这个答案似乎有一些观点,我认为值得补充的是,为了更清楚地将数据更改与模式更改区分开来,有一个 postUp 方法可以被覆盖并在之后调用up 方法。

https://www.doctrine-project.org/projects/doctrine-migrations/en/3.0/reference/migration-classes.html#postup

我 "found" 解决问题的正确方法(在 运行 迁移后插入数据,使用我的实体 类)。

这里是:

想法是将迁移声明为ContainerAware,然后从postUp 函数调用DI 来获取EntityManager。这真的很简单,您可以使用所有实体和存储库。

// ...
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class Version20130326212938 extends AbstractMigration implements ContainerAwareInterface
{

    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function up(Schema $schema)
    {
        // ... migration content
    }

    public function postUp(Schema $schema)
    {
        $em = $this->container->get('doctrine.orm.entity_manager');
        // ... update the entities
    }
}

按照另一个答案中的建议使用实体管理器不是一个好主意,因为它会在以后导致麻烦。

在第一次迁移中,我创建了一个 table 和 用户 并通过 $em->persist($user); 填充了一些用户,这在开始时看起来不错。

但是一个月后,我在我的用户模型中添加了一个 phone 列。并且 Doctrine 在第一次迁移中使用此列生成 INSERT 语句,由于列 phone 不存在而失败。当然它在第一次迁移中还不存在。所以最好使用纯 SQL INSERT。

当您创建新字段时,您需要输入此注释“options={"default":1}”,它应该可以工作。

/**
 * @var boolean
 * @ORM\Column(name="type4", type="boolean", options={"default":1})
 */
private $type4 = true;

我花了一些时间才弄明白:)

确实如此,如果您知道如何格式化数组;

$this->connection->insert('user', ['id' => 1, 'gender' => 'Male']);

在迁移中填写日期听起来不是个好主意,不是它的责任,symfony 有办法做到这一点。 https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html

这对我来说是个不错的解决方案。只需使用 bin/console make:migration 并在生成迁移时编辑 if 并添加“DEFAULT TRUE”: $this->addSql('ALTER TABLE event ADD active TINYINT(1) NOT NULL DEFAULT TRUE');