#28073: RemoveField.state_forwards() crashes with AttributeError: 'NoneType' 
object
has no attribute 'is_relation'
---------------------------------+------------------------------------
     Reporter:  Logan Gunthorpe  |                    Owner:  nobody
         Type:  Bug              |                   Status:  new
    Component:  Migrations       |                  Version:  1.11
     Severity:  Normal           |               Resolution:
     Keywords:                   |             Triage Stage:  Accepted
    Has patch:  0                |      Needs documentation:  0
  Needs tests:  0                |  Patch needs improvement:  0
Easy pickings:  0                |                    UI/UX:  0
---------------------------------+------------------------------------

Comment (by Carel):

 I'm not sure if this is a bug for me too or simply my lack of
 understanding when it comes to rolling ones own migrations, but I'm
 triggering the same response. I'm converting a legacy SQLite database
 (Approx. 20-30 Tables still working through it) to Django. There is a
 `models.IntField` (Milliseconds since Unix/Linux Epoch) which I want to
 alter to a `models.DateTimeField`. Djangos' automigrate was complaining
 when I switched the table from unmanaged to managed so I'm manually
 performing the following actions within a custom migration :

  1. Create a new `models.DateTimeField` called "Temp"
  2. Using `migrations.runPython` Iterate overall the records and convert
 all the data in the original field, "Modified", to `datetime.datetime` and
 assign it to new field "Temp"
  3. Remove the original field "Modified" using `migrations.RemoveField`
  4. Rename the temporary field "temp" to "Modified" using
 `migrations.RenameField`

 The process fails at Step 3 where the field being removed triggers the
 error, `AttributeError: 'NoneType' object has no attribute 'is_relation'`.
 Originally I was using Django 1.11.3/4 but have bumped to 1.11.7 and have
 the same problem.

 Based on the code posted by **PythonForce** it would seem that the loop is
 not assigning an instance to `old_field`, so where it tries to assign a
 value for `delay` it is breaking as there is no attribute `is_relation`
 for `None`/`NoneType`. Now it seems `delay` should be a boolean value so I
 would like to suggest one replace the line `delay = not
 old_field.is_relation` with `delay = old_field is None and not
 old_field.is_relation` then if `old_field` is `None` delay is `False` and
 the relation short circuits before testing the attribute. If `old_field`
 turns out to be an instance then `delay` depends upon
 `old_field.is_related`, as it presently does.

 {{{
 def state_forwards(self, app_label, state):
     new_fields = []
     old_field = None
     print app_label + " " + self.model_name_lower + " " + self.name
     for name, instance in state.models[app_label,
 self.model_name_lower].fields:
         if name != self.name:
             new_fields.append((name, instance))
         else:
             old_field = instance
     state.models[app_label, self.model_name_lower].fields = new_fields
     # Delay rendering of relationships if it's not a relational field
     delay = not old_field.is_relation
     state.reload_model(app_label, self.model_name_lower, delay=delay)
 }}}

 My suggestions is based upon only this snippet of code and I am not aware
 of any other context that may be relevant. I will try to pull down the
 sources and apply this. If successful I shall report back.

 P.s. If the manner in which I have posted does not meet some guideline,
 let me know I'll try to neaten it up or whatever as necessary.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28073#comment:15>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.0176c5de7e445a9c27af0f91b7da1afd%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to