我使用 doctrine migrations bundle 来跟踪数据库结构的变化。我想确保在为我的应用程序部署/添加新服务器时:
- (A) 数据库模式是最新的 (doctrine:migrations:migrate)
- (B) 数据库总是包含一组预定义的数据
对于 (B) 一个很好的例子是角色。我希望始终存在一组特定的角色。我意识到数据库迁移是可能的,但我不喜欢将模式更改与数据更改混合在一起的想法。此外,如果我使用 MySql 迁移,我将不得不为我的测试数据库创建一个等效的 Sqlite 迁移。
我知道的另一种选择是数据固定装置。但是,通过阅读文档,我觉得 fixtures 更多的是用于加载测试数据。此外,如果我更改了角色名称,我不知道如何使用固定装置更新它(因为它们要么在加载之前删除数据库中的所有数据,要么附加到它)。如果我使用 append 那么唯一键也会有问题。
我正在考虑创建某种命令,它采用一组配置文件并确保某些表始终处于与配置文件匹配的一致状态 - 但如果存在其他选项,我当然想使用它。
处理将所需数据加载和管理到数据库中的最佳方法是什么?
最佳答案
如果你正在使用 Doctrine Migrations,你可以使用整个数据库模式生成初始迁移,然后你应该生成迁移(doctrine:migrations:generate
或 doctrine:migrations:diff
) 用于在数据库结构中所做的所有更改,并在其中添加将迁移现有数据的查询。
fixtures 被设计为预填充数据(使用 doctrine:fixtures:load
),在我看来,它们应该保持最新 latest数据库模式并在 doctrine:migrations:migrate
/doctrine:schema:create
之后执行。
最后:
- 使用初始数据库模式创建基础迁移(而不是执行
doctrine:schema:create
只是生成迁移文件并迁移它) - 为每个数据库架构更改和迁移现有数据(例如角色名称更改)创建新的迁移
- 使用最新的架构使设备保持最新(您可以使用
--append
选项,只更新设备而不是先删除所有数据库数据)
然后,在部署新实例时,您可以运行 doctrine:schema:create
,然后运行 doctrine:migrations:version --add --all --no-interaction
(将所有迁移标记为已迁移,因为您已经创建了最新的模式)和 doctrine:fixtures:load
会将数据填充到数据库(也是最新版本,因此不需要从 Doctrine 迁移文件进行数据迁移) .
注意:现有实例不应使用doctrine:schema:update
,而只能使用doctrine:migrations:migrate
。在我们的应用程序中,我们甚至在 app/console
中阻止使用此命令:
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Helper\FormatterHelper;
// Deny using doctrine:schema:update command
if(in_array(trim($input->getFirstArgument()), ['doctrine:schema:update'])) {
$formatter = new FormatterHelper();
$output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, true);
$formattedBlock = $formatter->formatBlock(['[[ WARNING! ]]', 'You should not use this command! Use doctrine:migrations:migrate instead!'], 'error', true);
$output->writeln($formattedBlock);
die();
}
这是我根据自己的经验得出的结论。希望你会发现它有用:-)
关于database - 如何存储数据库(特别是 Symfony)所需的 'base' 或 'initial' 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31884879/