2011-05-02 38 views
8

有没有办法将CharField更改为TextField并保持来自此列的数据不变?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给了我一个错误,并且在错误出现之前查看输出,好像South正在下降并且重新创建数据库。这是南方的data migrations是关于什么?

+0

这是关于数据库限制的问题,但是在查看如何显示模型字段为textarea而不是input [type = text]时,我发现此问题。如果您只希望表单使用不同的HTML控件,请参阅:https://docs.djangoproject.com/en/dev/ref/forms/widgets/#specifying-widgets。如果问题更深入(如问题中) - 去南方奇迹。 – 2013-03-08 16:31:00

回答

6

假设你有对数据库的访问,你提到的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; 

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

+1

很好,谢谢。 – Nathan 2011-05-04 19:23:47

5

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

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

2)创建一个数据迁移从旧的字段中的数据迁移到新的领域

3)创建一个模式迁移,删除原有的“failed_reqs”和“passed_reqs”领域。

----如果你需要的字段是相同的名称与原始,我会再继续:

4)创建模式迁移添加“failed_reqs”和“passed_reqs”为的TextField

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

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

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

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

无论如何,我会在做任何这样的改变之前备份我的数据。希望这可以帮助。

+0

谢谢,事实证明这很容易直接通过Toad和/或SQL语句直接切换数据库,但我们将来需要使用South,所以我很欣赏这种写法。 – Nathan 2011-05-04 19:23:37

+1

这是正确的方式,适用于不同的底层数据库。即使看起来这么长,它也是非常合乎逻辑的。可能只有3个缩影:1)模式+数据:创建字段,使用旧值初始化它们,2)转储旧字段,3)将新字段重命名为旧名称。我不确定,但你甚至可以在2次迁徙中做到这一点,甚至可以在压力不大的情况下写下逆向迁徙。 – 2013-03-08 16:27:59

5

这是用django迁移(1.7+)解决的。如果您将类型从CharField更改为TextField,则生成的迁移是AlterField,这是正确的。