#Bug Report: DataError on Migration with Reduced CharField Max Length

7 messages · Page 1 of 1 (latest)

split kayak
#

I encountered a bug while working with Django migrations that I wanted to bring to your attention. The issue arises when reducing the max_length of a CharField after creating instances of the model. Here's a detailed description:

Steps to Reproduce:

  1. Create a model with a CharField:

    word = models.CharField(max_length=10, blank=True)
    
  2. Create an instance of this model with a word value containing 8 characters.

  3. Modify the model to reduce the max_length:

    word = models.CharField(max_length=5, blank=True)
    
  4. Run makemigrations. The command completes successfully and generates a migration file.

  5. Run migrate. This command fails with the following error:

    django.db.utils.DataError: value too long for type character varying(5)
    

Observations:

  • The error occurs because there is an existing instance with a word value longer than 5 characters.
  • The makemigrations command does not raise any issues, but the migrate command fails due to the existing data.
  • If no instances exist when reducing max_length, the migration proceeds without errors.

Impact:

This issue could lead to significant problems if migrations are generated on a local machine without data but fail in production environments with existing data.

Potential Solution:

I don't know 🙂

fringe totem
#

how is that a bug?

#

it's pretty much what I'd expect

dim blade
#

This doesn't sound like a bug with Django migrations itself.

If you were planning to do this change I would expect first to have a data migration which ensured that the data in the CharField was appropriately truncated <-- this will be entirely dependent on your project.

Then it would be safe to make the change you suggest.

steep bane
#

Well, how do you want to solve that? As a database manager, you can also adjust the column size at any time... As a rule, you first make a query "WHERE LENGTH > new maximum length" to see in advance whether there is already data that is longer. But even if you integrate this into Django, you will still have problems in the production environment if there are data records there that are longer. Then this field cannot be made smaller or you have to adjust the data. Depending on how many records there are and whether shortening is even possible.

split kayak
#

My thought is that when running makemigrations, if the change involves reducing the max_length of a field, an operation should be added to check existing records that exceed the new, lower max_length, and truncate them accordingly.

dim blade
#

That would be beyond the scope of the migrations framework. To blindly truncate data would certainly not be desirable in many (if any) circumstances. There might be a slim chance that it would be appropriate for Django to highlight the potential for data loss during makemigrations along the similar lines of adding non nullable fields. but otherwise the expectation would be that this is something an individual project would need to handle.