在SilverStripe中重建数据库时迁移数据
如果我有两个共享公共数据和行为的现有在SilverStripe中重建数据库时迁移数据,silverstripe,Silverstripe,如果我有两个共享公共数据和行为的现有数据对象,例如,它们在$db变量中都有一个标题字段&我想将共享数据移动到两个数据对象的基类中,如果数据库中已经有与DataObject关联的数据,那么如何将这些数据与结构一起迁移,而不必陷入sql?还是没有别的办法 因此,假设我的两个dataobject通过继承BaseDataObject来获取它们的Title数据。例如,数据库中的这些数据移动到一个名为BaseDataObject的表中,只有现有的Title数据不会迁移,显然,我该如何迁移它 编辑: 我接受了
数据对象
,例如,它们在$db变量中都有一个标题
字段&我想将共享数据移动到两个数据对象的基类中
,如果数据库中已经有与DataObject
关联的数据,那么如何将这些数据与结构一起迁移,而不必陷入sql?还是没有别的办法
因此,假设我的两个dataobject
通过继承BaseDataObject
来获取它们的Title
数据。例如,数据库中的这些数据移动到一个名为BaseDataObject
的表中,只有现有的Title
数据不会迁移,显然,我该如何迁移它
编辑:
我接受了下面的答案,尽管它不是我问题的解决方案
我想说,公认的答案与迁移数据的问题更相关,但是,为了解决我的问题,需要在多个数据对象之间共享一个字段,但在一个地方声明,同时保持当前数据库结构不变,我通过DataExtension
类扩展这些类,并以这种方式应用它们。通常我会为这些任务创建一个。有时,您必须执行比单独使用SQL更复杂的迁移(尽管在您的特定情况下,单独使用SQL也可以),而且这比编写自定义PHP脚本更容易,因为您可以利用SilverStripe框架的强大功能。以下是基本结构:
class MigrateTask extends BuildTask
{
protected $title = 'Task title';
protected $description = 'Task description';
protected $enabled = true;
public function run($request) {
// perform your migrations here
}
}
当您输入http://yoursite.com/dev/tasks
在您的情况下,获取所有数据对象,对其进行迭代并对其执行强制写入(例如,$dataObect->write(false,false,true);
)。检查是否将标题从子类写到基类。。如果是这种情况,您可以安全地从子类表中删除Title
字段。否则,您将不得不执行一些稍微低级的过程。也许是这样的:
$rslt = DB::query('SELECT * FROM "DataObjectSubclass"');
foreach($rslt as $r){
DB::query('UPDATE "DataObjectBaseClass" SET "Title" = \''. $r['Title'] .'\' WHERE ID = '. $r['ID']);
}
// you could even drop the title field once you're done..
// But you'll have to be sure that the above code migrated your data
// correctly. Otherwise you're screwed ;)
DB::query('ALTER TABLE "DataObjectSubclass" DROP "Title"');
迁移完成后,可以将$enabled
变量设置为false
,使任务不再可用