Opened 7 years ago
Last modified 7 years ago
#29852 closed Bug
Infinite migrations when using SimpleLazyObject in field arguments — at Version 1
| Reported by: | Javier Buzzi | Owned by: | nobody |
|---|---|---|---|
| Component: | Migrations | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
from django.db import models
from django.utils.functional import SimpleLazyObject
from django.core.validators import MinValueValidator
import datetime
# Create your models here.
class Thing(models.Model):
day = models.DateTimeField(validators=[MinValueValidator(SimpleLazyObject(datetime.datetime.now))])
This works great right up until you try running migrations:
- First time it creates a
- Create model Thing - Then you run the same command again and again, and will always generate a new migration
- Alter field day on thing
class Migration(migrations.Migration):
dependencies = [
('app', '0005_auto_20181015_2203'),
]
operations = [
migrations.AlterField(
model_name='thing',
name='day',
field=models.DateTimeField(validators=[django.core.validators.MinValueValidator(datetime.datetime(2018, 10, 15, 22, 3, 41, 390769))]),
),
]
The issue being that the now() is being evaluated and thus is always different.
I got it 50% working with this diff:
diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py
index 911cf0f..ef2ad43 100644
--- a/django/db/migrations/serializer.py
+++ b/django/db/migrations/serializer.py
@@ -12,7 +12,7 @@ import uuid
from django.db import models
from django.db.migrations.operations.base import Operation
from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
-from django.utils.functional import LazyObject, Promise
+from django.utils.functional import LazyObject, Promise, SimpleLazyObject
from django.utils.timezone import utc
from django.utils.version import get_docs_version
@@ -273,6 +273,8 @@ def serializer_factory(value):
from django.db.migrations.writer import SettingsReference
if isinstance(value, Promise):
value = str(value)
+ elif isinstance(value, SimpleLazyObject):
+ value = value._setupfunc
elif isinstance(value, LazyObject):
# The unwrapped value is returned as the first item of the arguments
# tuple.
Turns the migrations into:
class Migration(migrations.Migration):
dependencies = [
('app', '0004_auto_20181015_2203'),
]
operations = [
migrations.AlterField(
model_name='thing',
name='day',
field=models.DateTimeField(validators=[django.core.validators.MinValueValidator(datetime.datetime.now)]),
),
]
While it's a great improvement, it still generates a new one every time. I'm a little over my head with this one, this code is very dense. I could keep looking at it tomorrow, but i need someone to point me in the right direction + where in the world do i put the tests for this thing?? Thanks.
Change History (1)
comment:1 by , 7 years ago
| Component: | Uncategorized → Migrations |
|---|---|
| Description: | modified (diff) |
| Summary: | SimpleLazyObject Causing Migrations to be created over and over → Infinite migrations when using SimpleLazyObject in field arguments |
| Triage Stage: | Unreviewed → Accepted |
| Type: | Uncategorized → Bug |
I think the problem is this:
The two must be considered equal to prevent infinite migrations. See 91f701f4fc324cd2feb7dbf151338a358ca0ea18 for a similar issue.