#29899: Adapt the auto-detector to detect changes from model states instead of
model classes
-------------------------------------+-------------------------------------
     Reporter:  Simon Charette       |                    Owner:  David
         Type:                       |  Wobrock
  Cleanup/optimization               |                   Status:  assigned
    Component:  Migrations           |                  Version:  master
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

 Hello David,

 > Am I understanding correctly that, by using the ModelState objects,
 instead of the rendered model objects/classes, we avoid calling the
 ProjectState.apps and ProjectState.concrete_apps (in the
 Autodetector.init) which are rendering the models? Therefore, we avoid
 work and speed up the makemigrations and migrate commands?

 Exactly, accessing `.apps` and `concrete_apps` involves model rendering
 which is really slow.

 > But since the "from_state" is still generated from the migration graph,
 we will still apply all existing migrations iteratively to build it,
 right? So we cannot totally avoid exploring the migration graph?

 Right but `from_state` is generated by calling `states_forwards` on all
 operations of on-disk migrations and none of these operations should
 access `.apps` during `states_forwards` which should make them relatively
 fast.

 > The one thing about the logic which I'm unsure of, is the "relations"
 property which is introduced in the ProjectState. The goal is, I guess, to
 substitute the "related_objects" that a model class' option contains.

 That's it

 > However, I don't fully understand how the "proxies", "concrete" models
 and "swappable" ones work together.

 You'll have to do a bit more of investigation on your side to figure this
 out I'm afraid but the gist is that ''proxies'' models are `Meta.proxy =
 True` models which are always backed by a ''concrete'' table backed one.
 ''swappable'' refers to models that can be swapped by other ones.
 Currently only `auth.User` uses this feature internally.

 > I see that we are trying to fill the relations, for each model
 (identified by app_label+model_name), have the related models (identified
 by the same key) and the associated fields that have a relation. It's not
 easy to get your head around the 4 consecutive loops.

 Yeah this code is tricky for sure.

 > What are those relations exactly? All possible defined FK (also m2m,
 ...) on the model itself? Or also fields FK that point to this model?

 IIRC they are all forwards relationships which means related fields
 ''from'' the model.

 > And would it possible, even quickly, to explain how "swappable", "proxy"
 and "concrete" work together, I'd be grateful. I mean, I guess that we
 need to resolve the real/concrete model from a proxy model, but
 "swappable" is my main source of confusion here and I don't know how it
 should be handled :/ Like a proxy model because we resolve the concrete
 model when the User model is swappable?

 I tried to explain it above but I suggest you start by reading the
 (limited) swappable model documentation and then dive into how they are
 currently handled. A lot of this logic is tribal knowledge share by the
 limited amount of people who worked on the migration framework over the
 years and its hard to define beyond what's coded and currently passes the
 suite. The basic idea is that swappable models could have been swapped by
 another one (e.g. a custom user model via `settings.AUTH_USER_MODEL`) so
 it needs to be treated differently.

 As mentioned in the description there's a lot of overlap with this ticket
 and #29898 which [https://groups.google.com/d/msg/django-
 developers/_ohBzsuomqw/VOr2itOiAwAJ I tried to describe on the mailing
 list to a developer interested in working on the latter for GSoC]. Both
 tickets require access to a `ProjectState` forwards relationship cache
 (and maybe a reverse one as well in this case) and both would benefit from
 having `ProjectState` define methods that perform state alterations
 currently baked into `Operation.state_forwards` overrides. That would
 allow the auto-detector to simply call these operations if necessary when
 performing renames instead of maintaining tons of different maps of
 changes. It would also pave the way for `ProjectState`/`ModelState` to
 have their own `.difference(other, questionner=None)` methods to break the
 monolithic `autodetector` file into testable and extendable components
 which users have been asking for a while.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29899#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/067.1211cf68ece2e1b0ab5e04a02f6051d3%40djangoproject.com.

Reply via email to