Opened 7 years ago
Last modified 6 years ago
#28980 new Cleanup/optimization
Make the autodetector validate the type of one-off default values
Reported by: | Nikos Katsos | Owned by: | |
---|---|---|---|
Component: | Migrations | Version: | 2.0 |
Severity: | Normal | Keywords: | |
Cc: | Jeff | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
As the title says Django doesn't check the type of one-off value. Recently I had a field like this
start_time = models.DateTimeField(editable=False)
1) I gave to the field an one-off value
>>> 0
2) then the migration file had those operations
operations = [ migrations.AddField( model_name='x', name='outcome', field=models.CharField(default='TO', max_length=16), preserve_default=False, ), migrations.AddField( model_name='x', name='start_time', field=models.DateTimeField(default=0 editable=False), preserve_default=False, ), ]
when I found my error i couldn't really do anything
I changed
field=models.DateTimeField(default=0, editable=False),
to
field=models.DateTimeField(default=timezone.now, editable=False),
so after updating my migration file, I got an error "django.db.utils.OperationalError: (1060, "Duplicate column name "outcome")".
I could neither re-migrate because the operations isn't a bunch of queries in transaction, nor create a new migration.
Only reverting to zero and apply all migrations again worked.
This has to have a workaround.
Change History (5)
comment:1 by , 7 years ago
Summary: | Django doesn't check the type of one-off value → Make the autodetector validate the type of one-off default values |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → Cleanup/optimization |
comment:2 by , 6 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:3 by , 6 years ago
comment:4 by , 6 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:5 by , 6 years ago
The value comes from return_value='1'
. That test could be updated to use a valid value, however, it seems that DateTimeField.to_python()
(and all to_python()
methods) would need to be able to handle arbitrary Python types (and raise ValidationError
) -- which may be difficult -- unless there's some broader exception catching in the migrations questioner.
If anyone is willing to give me a hand, I am close to a viable patch, see commit, however I am currently wrangling with an existing test
tests/migrations/test_commands.py
-MakeMigrationsTests.test_makemigrations_auto_now_add_interactive
. The test is failing like so:I have confirmed that at this point the value being passed to
to_python
is the integer 1, which should indeed be an invalid default/one-off value to pass for a DateTime field.At the moment what seems to be blocking me, I believe, is figuring out how
unittest.mock.patch()
works, and how that value is being set for the interactive test:If anyone could provide some guidance on how to properly work with this test, I'd appreciate it.