在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
,使任务不再可用