Re: Suggestion: how to access custom methods from a historical model during a migration

16 views
Skip to first unread message

Shai Berger

unread,
May 16, 2016, 5:41:31 AM5/16/16
to south...@googlegroups.com
Hi Ryan,

A) Your message clearly refers to Django migrations, the Django built-in
component which replaced South as of Django 1.7. So this is the wrong place
for it (in fact, this is a rather abandoned place in general). The right place
for this kind of suggestion/question (where you are not sure some practice is
generally good) is django-users.

B) I think the code you pasted, as is, shouldn't work -- you aren't actually
importing the model, you just take it from the `apps` object. If you did
import the model, it would have the problem that when the model changed, your
migration code would suddenly break -- the migration would try to use the most
updated version of the model against a database that fits some historical
version.

Django Migrations do have a sort-of solution for the problem -- you can
specify base classes for your models and put such methods in these bases. You
have to be careful about "freezing" the method (as in: not changing it),
though, in order to avoid breaking your migrations.

HTH,
Shai.

On Monday 16 May 2016 02:19:04 Ryan Lahfa wrote:
> Hi, a friend recently struggled with accessing custom instance methods from
> a historical method during a migration.
>
> The documentation of South specified that it was not possible due to the
> freezing process.
>
> I suggest an easy hack rather than copying / pasting some code, you could
> import the model and call the instance method from the class method.
>
> Like the following:
>
> from django.db import models, migrations
>
> def recompute_fingerprints(apps, schema_editor):
> """
> Recomputes the fingerprints of all papers, merging
> those who end up having the same fingerprint
> """
> merged = 0
> Paper = apps.get_model('papers','Paper')
> pc = Paper.objects.all().count()
> for idx, p in enumerate(Paper.objects.all()):
> if idx % 100:
> print idx
> match = Paper.recompute_fingerprint_and_merge_if_needed(p) # <--
> here I call the class method and I pass the instance as self. if match is
> not None:
> merged += 1
> print "%d papers merged" % merged
>
>
> I think that it's pretty handy when you have complex methods. I wonder if
> there is any drawbacks or caveat with this method.
>
> Here is my suggestion: maybe, you could update the docs to mention this
> dirty hack as a solution?
>
>
> Kind regards,
>
> Ryan Lahfa.
Reply all
Reply to author
Forward
0 new messages