从某个时间点更改数据库,当更改不适合现有数据时



我有一个看起来像这样的模型:

class Report(models.Model):
    updater = models.CharField(max_length=15)
    pub_date = models.DateTimeField(auto_add_now=True)
    identifier = models.CharField(max_length=100)
    ... and so on...

还有一些字段,但它们与问题无关。现在该网站具有非常简单的功能 - 用户可以查看较旧的报告及其数据,并可以编辑它们或添加新报告。

但是,标识符字段实际上是一个整数,用于符号化正在报告的日志文件。大多数情况下,每个报告都有一个日志。但有时它不止一个。我将其作为 CharField 进行,因为我构建了该网站以替换较旧的 sharepoint 2003 网站,在该网站上,该字段被视为简单文本。所以我希望在我的下一个版本中,它应该是这样的,即像这样:

class Report(models.Model):
    updater = models.CharField(max_length=15)
    pub_date = models.DateTimeField(auto_add_now=True)
    ... and so on...
class Log(models.Model):
    report = models.ForeignKey(Report)
    identifier = models.IntegerField()

问题是,因为在旧站点中,该字段是CharField,人们随心所欲地使用它。意思是,即使他们在同一报告中更新了各种日志,他们也只是像这样<logid1>, <logid2>这样做。有时他们会添加一些文本<logid1> which is related to <logid2>.

所以我想改变这一点,但我不想丢失所有旧数据,我无法修复所有这些边缘情况(数据库包含大约 22,000 个报告)。我想过将此添加到报告中:

def disp_id(self):
    if self.pub_date < ... #the day I'll do the update
        return self.identifier
    else:
        return ', '.join([log.identifier for log in self.log_set.all()])

但是,我现在并没有真正摆脱旧领域,是吗?我只是添加一个新值并保留某个日期的原始空值。

据我所知,我想做的事情是不可能的。我只是问,因为我知道也许我不是第一个处理这种事情的人,也许有一个我不知道的解决方案。

希望我的解释足够清楚,提前谢谢!

class Report(models.Model):
    updater  = models.CharField(max_length=15)
    pub_date = models.DateTimeField(auto_add_now=True)
    identifier = models.CharField(null=True)
    ... and so on...
    logs     = models.ManyToManyField(Log,null=True)
class Log(models.Model):
    identifier = models.IntegerField()
制作

上面的模型,然后制作如下脚本:

ident_list = []
for reports in Report.objects.all():
    identifiers = reports.identifiers.split(',')
    for idents in identifiers:
        if not idents in ident_list:
            log = Log.create(**{'identifier' : int(idents)})
            ident_list.append(int(idents))
        else:
            log = Log.objects.get(identifier = int(idents))
        report.log.add(log)

在从报表表中删除列标识符之前检查数据。它现在解决了你的目的吗?

最新更新