#32689: Infinite AlterField Migrations due to default callable object missmatch
-------------------------------------+-------------------------------------
     Reporter:  Samuel Bishop        |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Migrations           |                  Version:  3.2
     Severity:  Normal               |               Resolution:
     Keywords:  infinite,            |             Triage Stage:
  makemigrations, migrations,        |  Unreviewed
  callable, default, field           |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Samuel Bishop:

Old description:

> `makemigration` will generate infinite migrations if the callable path is
> miss-matched such that you end up with two discreet callable objects (I'm
> still trying to identify where exactly the migration framework is
> generating this missmatch, I can see the difference stepping through
> `MigrationAutodetector.generate_altered_fields` in the debugger but I'm
> not sure if the root cause is inside `generate_altered_fields`, another
> method on `MigrationAutodetector` or somewhere else entirely...) then the
> same migration is generated every time you run the command which results
> in no actual change to the database.
>
> In my case it's from a custom field library being used as a primary key.
>
> I was importing `from ulid.api import new as new_ulid` and setting
> `default=new_ulid`, but unless I swap to `import ulid.api.api` and set
> `default=ulid.api.api.Api.new` I just get a new identical migration
> altering the field's default value to `ulid.api.api.Api.new` every time i
> run `makemigrations`
>
> I would have expected either a clear warning detailing why my choice of
> callable object for the `default=` will cause issues, or I would have
> expected `makemigrations` to not mutate my callable like this.

New description:

 `makemigration` will generate infinite migrations if the callable path is
 miss-matched such that you end up with two discreet callable objects (I'm
 still trying to identify where exactly the migration framework is
 generating this missmatch, I can see the difference stepping through
 `MigrationAutodetector.generate_altered_fields` in the debugger but I'm
 not sure if the root cause is inside `generate_altered_fields`, another
 method on `MigrationAutodetector` or somewhere else entirely...) then the
 same migration is generated every time you run the command which results
 in no actual change to the database.

 In my case it's from a custom field library being used as a primary key.

 I was importing `from ulid.api import new as new_ulid` and setting
 `default=new_ulid`, but unless I swap to `import ulid.api.api` and set
 `default=ulid.api.api.Api.new` I just get a new identical migration
 altering the field's default value to `ulid.api.api.Api.new` every time i
 run `makemigrations`

 I would have expected either a clear warning detailing why my choice of
 callable object for the `default=` will cause issues, or I would have
 expected `makemigrations` to not mutate my callable like this.

 Root cause: Turns out this is a serialisation fault. The migration
 serialiser doesn't throw any kind of error or warning and just mutates the
 callable instead of preventing me from using an invalid default callable
 that the migration framework wont be able to serialise. A simple wrapper
 function added to the custom field library solves the matter entirely,
 however the underlying issue of the migration framework behaviour is worth
 looking at improving.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32689#comment:2>
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/068.2a708c9090c12490f0464635b5eaab4d%40djangoproject.com.

Reply via email to