[Fixed]-Django: Convert CharField to TextField with data intact

5đź‘Ť

âś…

Assuming that you have access to the database, as you mentioned the way Django talks about adding and removing columns, I’ve listed methods for both Postgresql and MySQL since you didn’t mention what you were using.

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;

I would highly recommend backing up your database before doing these changes.

24đź‘Ť

This is solved with django migrations (1.7+). If you change the type from CharField to TextField, the migration produced is AlterField, which does the right thing.

5đź‘Ť

Off hand, I would continue to look into a South approach. This is the workflow that I would try:

1) South schema migration to create two new TextField fields called something like “failed_reqs_txt” and “passed_reqs_txt”.

2) Create a data migration to migrate the data from the old fields to the new fields

3) Create a schema migration to delete the original “failed_reqs” and “passed_reqs” fields.

—- if you need the fields to be the same name as the original, I would then proceed to:

4) Create a schema migration to add “failed_reqs”, and “passed_reqs” as TextFields

5) Create a data migration to migrate from the “failed_reqs_txt” and “passed_reqs_txt” to the “failed_reqs”, and “passed_reqs” fields.

6) Create a schema migration to drop the “failed_reqs_txt” and “passed_reqs_txt” fields.

Though this is a lot of migrations, it breaks up each change into atomic migrations. I’d try this first. I’m not sure why South would be dropping and recreating the db. Did you run the convert_to_south option when adding south to your project? I think this fakes a migration and lets south know that it’s working with an existing project and not a new one.

As an alternative, you could do some direct ALTERS to the database to alter the column type and then update the model.py from CharField to TextField. Postgres, supposedly supports implicitly changing data types this way. (See Section 5.5.6.) I’m not sure about mysql, but I think it works the same. (CharField to TextFiled should be a compatible conversion)

Regardless, I’d backup my data before making any such changes. Hope this helps.

👤Joe J

Leave a comment