如何存储数据库(特别是Symfony)所需的“基本”或“初始”数据? [英] How can I store required 'base' or 'initial' data for a database (in particular Symfony)?

查看:100
本文介绍了如何存储数据库(特别是Symfony)所需的“基本”或“初始”数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用doctrine迁移软件包跟踪我的数据库结构中的更改。我想确保当我为我的应用程序部署/添加一个新的服务器:




  • (A)数据库模式(doctrine:migrations:migrate)

  • (B)数据库始终包含预定义的数据集



对于(B)一个好的例子是角色。我想要一组特定的角色总是存在。我意识到这是可能与数据库迁移,但我不喜欢混合模式更改与数据更改的想法。如果我使用MySql迁移,我将不得不为我的测试数据库创建一个等效的Sqlite迁移。



我知道的另一个选项是数据夹具。然而从阅读文档我得到的感觉,夹具更多的加载测试数据。此外,如果我更改了一个角色名称,我不知道如何更新使用fixtures(因为它们删除数据库中的所有数据加载或附加之前)。如果我使用append然后唯一的键也将是一个问题。



我正在考虑创建某种命令,该命令需要一组配置文件,并确保某些表始终处于与配置文件匹配的一致状态 - 但如果另一个选项存在我想要使用它当然。



处理加载和管理数据库中所需数据的最好方法是什么?

解决方案

如果您使用Doctrine Migrations,您可以使用整个数据库模式生成初始迁移,那么您应该生成迁移( doctrine:migrations:generate code> doctrine:migrations:diff )用于数据库结构中的所有更改,并添加将迁移现有数据的查询。



灯具设计用于预填充数据(使用 doctrine:fixtures:load ),在我看来,它们应该保持最新的最新数据库模式并在 doctrine:migrations:migrate / / doctrine:schema:create / p>

最后:




  • 使用初始数据库模式创建基本迁移 doctrine:schema:create 只是生成迁移文件并将其迁移)

  • 为每个数据库模式更改创建新迁移并迁移现有数据(例如更改角色名称)

  • 使用最新模式保持装置最新状态(您可以使用 - 附加选项,只需更新fixture,而不是先删除所有数据库数据)



然后,在部署新实例时,您可以运行 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; 
使用Symfony\Component\Console\Helper\FormatterHelper;

//拒绝使用doctrine:schema:update命令
if(in_array(trim($ input-> getFirstArgument()),['doctrine:schema:update'
$ formatter = new FormatterHelper();
$ output = new ConsoleOutput(ConsoleOutput :: VERBOSITY_NORMAL,true);

$ formattedBlock = $ formatter-> formatBlock(['[[WARNING!]]','你不应该使用这个命令!use doctrine:migrations:migrate instead!'],'error' ,true);

$ output-> writeln($ formattedBlock);
die();
}

这是我从我的经验中得出的。希望你会发现它有用: - )


I use the doctrine migrations bundle to track changes in my database structure. I would like to ensure that when I'm deploying / adding a new server for my application that:

  • (A) the database schema is up to date (doctrine:migrations:migrate)
  • (B) the database always contains a pre-defined set of data

For (B) a good example is roles. I want a certain set of roles to always be present. I realize it is possible with database migrations, but I don't like the idea of mixing schema changes with data changes. Also if I use MySql migrations I would have to create a equivalent Sqlite migration for my test database.

Another option I'm aware of is data fixtures. However from reading the documentation I get the feeling that fixtures are more for loading test data. Also if I changed a role name I don't know how that would be updated using fixtures (since they either delete all data in the database before loading or append to it). If I use append then unique keys would also be a problem.

I'm considering creating some sort of command that takes a set of configuration files and ensures that certain tables are always in a consistent state matching the config files - but if another option exists I'd like to use it of course.

What is the best way to handle loading and managing required data into a database?

解决方案

If you're using Doctrine Migrations, you can generate initial migration with whole database schema, then you should generate migrations (doctrine:migrations:generate or doctrine:migrations:diff) for all changes that are made in database structure AND also add there queries that will migrate existing data.

Fixtures are designed to pre-populate data (with doctrine:fixtures:load) and, in my opinion, they should be kept up-to-date with latest database schema and executed after doctrine:migrations:migrate / doctrine:schema:create.

So finally:

  • Create base migration with initial database schema (instead of executing doctrine:schema:create just generate migration file and migrate it)
  • Create new migrations for each database schema change AND for migrating existing data (such as role name changing)
  • Keep fixtures up-to-date with latest schema (you can use --append option and only update fixtures instead of deleting all database data first)

Then, when deploying new instance you can run doctrine:schema:create, then doctrine:migrations:version --add --all --no-interaction (mark all migrations as migrated, because you have already created latest schema) and doctrine:fixtures:load which will populate data to the database (also latest version, so data migrations from Doctrine migrations files are not required).

Note: Existing instances should NOT use doctrine:schema:update, but only doctrine:migrations:migrate. In our app we even block usage of this command, in 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();
}

This is what I figured out from my experience. Hope you will find it useful :-)

这篇关于如何存储数据库(特别是Symfony)所需的“基本”或“初始”数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆