从数据库生成 Symfony2 装置?
是否可以从 Symfony2/Doctrine 中的现有数据库生成装置?我怎么能这么做呢?
示例:
我定义了 15 个实体,并且我的 symfony2 应用程序正在运行。现在,有些人可以浏览该应用程序,并且通过使用它,到目前为止,它已经插入了大约 5000 行。现在我想要将这些东西作为固定装置插入,但我不想手动执行此操作。我如何从数据库生成它们?
Is it possible to generate fixtures from an existing DB in Symfony2/Doctrine? How could I do that?
Example:
I have defined 15 entities and my symfony2 application is working. Now some people are able to browse to the application and by using it it had inserted about 5000 rows until now. Now I want the stuff inserted as fixtures, but I don’t want to do this by hand. How can I generate them from the DB?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Doctrine 或 Symfony2 中没有直接的方式,但为其编写代码生成器(无论是在 sf2 内部还是外部)将是微不足道的。只需提取每个属性并生成一行代码来设置每个属性,然后将其放入您的装置加载方法中。例子:
There's no direct manner within Doctrine or Symfony2, but writing a code generator for it (either within or outside of sf2) would be trivial. Just pull each property and generate a line of code to set each property, then put it in your fixture loading method. Example:
据我了解你的问题,你有两个数据库:第一个已经投入生产并填充了 5000 行,第二个是你想要用于新测试和开发的新数据库。是这样吗?
如果是,我建议您在测试环境中创建两个实体管理器:第一个是“默认”实体管理器,它将在您的项目(您的控制器等)中使用。第二个将用于连接到您的生产数据库。您将在这里找到如何处理多个实体管理器: http://symfony.com /doc/current/cookbook/doctrine/multiple_entity_managers.html
然后,您应该创建一个可以访问您的容器的 Fixture 类。这里有一个“如何”: http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#using-the-container-in-the-fixtures。
使用容器,您将可以访问两个实体管理器。这就是“魔法”:您必须从生产数据库中检索对象,并将它们保存在第二个实体管理器中,该管理器会将它们插入到您的测试数据库中。
我指出两点:
我没有任何代码可以向您建议,但我希望这个想法对您有所帮助。
As I understand your question, you have two databases: the first is already in production and filled with 5000 rows, the second one is a new database you want to use for new test and development. Is that right ?
If it is, I suggest you to create in you test environment two entity manager: the first will be the 'default' one, which will be used in your project (your controllers, etc.). The second one will be used to connect to your production database. You will find here how to deal with multiple entity manager : http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
Then, you should create a Fixture class which will have access to your container. There is an "how to" here : http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#using-the-container-in-the-fixtures.
Using the container, you will have access to both entity manager. And this is the 'magic': you will have to retrieve the object from your production database, and persist them in the second entity manager, which will insert them in your test database.
I point your attention to two points:
I do not have any code to suggest to you, but I hope this idea will help you.
我假设您想要使用固定装置(而不仅仅是将生产数据库或临时数据库转储到开发数据库中),因为a)您的架构发生更改,并且如果您更新代码,转储将不起作用,或者b)您不想转储孔数据库,但只想扩展一些自定义夹具。我能想到的一个例子是:您的临时数据库中有 206 个国家/地区,用户将城市添加到这些国家/地区;为了保持灯具较小,您的开发数据库中只有 5 个国家/地区,但是您希望将用户添加到临时数据库中的这 5 个国家/地区的城市添加到开发数据库中
我能想到的唯一解决方案是使用提到的DoctrineFixturesBundle 和多个实体管理器。
首先,您应该在
config.yml
中配置两个数据库连接和两个实体管理器,正如您所看到的,两个实体管理器都映射了 AcmeDemoBundle(在此包中,我将放置用于加载固定装置的代码)。如果第二个数据库不在您的开发计算机上,您可以将 SQL 从另一台计算机转储到开发计算机。这应该是可能的,因为我们讨论的是 500 行而不是数百万行。
接下来您可以做的是实现一个夹具加载器,它使用服务容器检索第二个实体管理器,并使用 Doctrine 从第二个数据库查询数据并将其保存到您的开发数据库(
默认
实体管理器):我在
loadCountry
方法中所做的是从staging
实体管理器加载对象,添加对固定国家/地区的引用(已经存在的国家/地区)在你当前的装置中)并使用默认
实体管理器(您的开发数据库)。来源:
I assume that you want to use fixtures (and not just dump the production or staging database in the development database) because a) your schema changes and the dumps would not work if you update your code or b) you don't want to dump the hole database but only want to extend some custom fixtures. An example I can think of is: you have 206 countries in your staging database and users add cities to those countries; to keep the fixtures small you only have 5 countries in your development database, however you want to add the cities that the user added to those 5 countries in the staging database to the development database
The only solution I can think of is to use the mentioned DoctrineFixturesBundle and multiple entity managers.
First of all you should configure two database connections and two entity managers in your
config.yml
As you can see both entity managers map the AcmeDemoBundle (in this bundle I will put the code to load the fixtures). If the second database is not on your development machine, you could just dump the SQL from the other machine to the development machine. That should be possible since we are talking about 500 rows and not about millions of rows.
What you can do next is to implement a fixture loader that uses the service container to retrieve the second entity manager and use Doctrine to query the data from the second database and save it to your development database (the
default
entity manager):What I did in the
loadCountry
method was that I load the objects from thestaging
entity manager, add a reference to the fixture country (the one that already exists in your current fixtures) and persist it using thedefault
entity manager (your development database).Sources:
你可以使用 https://github.com/Webonaute/DoctrineFixturesGeneratorBundle
它增加了使用类似命令为单个实体生成固定装置的能力
或者您可以创建完整快照
you could use https://github.com/Webonaute/DoctrineFixturesGeneratorBundle
It add ability to generate fixtures for single entity using commands like
Or you can create full snapshot
Doctrine Fixtures 非常有用,因为它们允许您创建对象并将它们插入数据库。当您需要创建关联或使用密码编码器之一对密码进行编码时,这尤其有用。如果数据库中已经有数据,那么您实际上不需要将它们从该格式中取出并将其转换为 PHP 代码,只需让该 PHP 代码将相同的数据插入回数据库即可。您可能可以只执行 SQL 转储,然后以这种方式将它们重新插入到数据库中。
如果您正在启动项目但想要使用用户输入来创建项目,那么使用固定装置会更有意义。如果您的配置文件中有默认用户,您可以读取它并插入对象。
The Doctrine Fixtures are useful because they allow you to create objects and insert them into the database. This is especially useful when you need to create associations or say, encode a password using one of the password encoders. If you already have the data in a database, you shouldn't really need to bring them out of that format and turn it into PHP code, only to have that PHP code insert the same data back into the database. You could probably just do an SQL dump and then re-insert them into your database again that way.
Using a fixture would make more sense if you were initiating your project but wanted to use user input to create it. If you had in your config file the default user, you could read that and insert the object.
AliceBundle 可以帮助您做到这一点。事实上,它允许使用 YAML(或 PHP 数组)文件加载固定装置。
例如,您可以使用以下方式定义灯具:
或者在 PHP 数组中使用相同的结构。这比生成可工作的 PHP 代码要容易得多。
它还支持参考:
The AliceBundle can help you doing this. Indeed it allows to load fixtures with YAML (or PHP array) files.
For instance you can define your fixtures with:
Or with the same structure in a PHP array. It's WAY easier than generating working PHP code.
It also supports references:
在doctrine_fixture 说明书中,您可以在最后一个示例中看到如何在实体中获取服务容器。
使用此服务容器,您可以检索学说服务,然后检索实体管理器。使用实体管理器,您将能够从数据库中获取所需的所有数据。
希望这会对您有所帮助!
In the doctrine_fixture cookbook, you can see in the last example how to get the service container in your entity.
With this service container, you can retrieve the doctrine service, then the entity manager. With the entity manager, you will be able to get all the data from your database you need.
Hope this will help you!