Django:将CharField转换为TextField,数据完整无缺

时间:2011-05-02 22:27:38

标签: python django

有没有办法将CharField更改为TextField并保持此列中的数据不变?

现在我有以下内容:

class TestLog(models.Model):
    failed_reqs = models.CharField(max_length=DB_MAX_CHAR_LENGTH, blank=True)
    passed_reqs = models.CharField(max_length=DB_MAX_CHAR_LENGTH, blank=True)

但是DB_MAX_CHAR_LENGTH是500,因为事实证明这个字段有时会超过它,所以我想去:

class TestLog(models.Model):
    failed_reqs = models.TextField(blank=True)
    passed_reqs = models.TextField(blank=True)

如何执行此操作并将数据保持在生产数据库中?

Djangobook详细说明了如何添加和删除字段,我也尝试使用South来执行此操作,但是South给了我一个错误,并查看错误之前的输出它显示为虽然南方正在放弃并重建数据库。这是南方data migrations的全部意义吗?

3 个答案:

答案 0 :(得分:12)

这是通过django迁移(1.7+)解决的。如果您将类型从CharField更改为TextField,则生成的迁移是AlterField,它可以做正确的事情。

答案 1 :(得分:5)

副手,我会继续研究南方的方法。这是我尝试的工作流程:

1)南模式迁移创建两个新的TextField字段,称为“failed_reqs_txt”和“passed_reqs_txt”。

2)创建数据迁移以将数据从旧字段迁移到新字段

3)创建模式迁移以删除原始的“failed_reqs”和“passed_reqs”字段。

----如果您需要字段与原始字段相同,我将继续:

4)创建模式迁移以添加“failed_reqs”和“passed_reqs”作为TextFields

5)创建数据迁移,从“failed_reqs_txt”和“passed_reqs_txt”迁移到“failed_reqs”和“passed_reqs”字段。

6)创建模式迁移以删除“failed_reqs_txt”和“passed_reqs_txt”字段。

虽然这是很多迁移,但它会将每次更改分解为原子迁移。我先试试这个。我不确定为什么南方会丢弃并重新创建数据库。在向项目添加南方时是否运行了convert_to_south选项?我认为这会假装迁移,让南方知道它正在与现有项目合作,而不是新项目。

作为替代方法,您可以对数据库执行一些直接ALTERS以更改列类型,然后将model.py从CharField更新为TextField。 Postgres,据说支持以这种方式隐式更改数据类型。 (参见第5.5.6节。)我不确定mysql,但我认为它的工作原理相同。 (CharField到TextFiled应该是兼容的转换)

无论如何,我会在进行任何此类更改之前备份我的数据。希望这可以帮助。

答案 2 :(得分:5)

假设你有权访问数据库,正如你提到Django谈论添加和删除列的方式,我已经列出了Postgresql和MySQL的方法,因为你没有提到你正在使用的内容。

Postgresql:
BEGIN;
    ALTER TABLE "TestLog"
        ALTER COLUMN "failed_reqs" TYPE TEXT,
        ALTER COLUMN "passed_reqs" TYPE TEXT;
COMMIT;

MySQL:
BEGIN;
    ALTER TABLE TestLog
        MODIFY failed_reqs TEXT NULL,
        MODIFY passed_reqs TEXT NULL;
COMMIT;

我强烈建议您在进行这些更改之前备份数据库。