运行 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
方法。
我 "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');
我有一个使用 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
方法。
我 "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');