Encapsulating Complex Business Logic in a Migraiton

17 views
Skip to first unread message

Matt S

unread,
Aug 29, 2017, 4:47:52 PM8/29/17
to Django users
Standard practice is that you do not refer to "current" models (i.e. from app.models import MyModel) in a migration as the migration will break when that models changes. This means copying any model-specific code into the migration. This becomes impractical when the code needed for the migration spans multiple files and models.

How can I encapsulate a complex chain of business logic involving multiple models in a migration? For example, if I have instance methods on ModelA which calls methods on ModelB, ModelB queries for ModelC and calls methods on it. If I use those methods as they exist on the models, the migration will eventually break when any of the involved Models' schema changes.

Mike Dewhirst

unread,
Aug 29, 2017, 6:58:35 PM8/29/17
to Django users
In the forwards_func() method after it has been run and done its work,
and if appropriate, I add an extra line after the docstring ... return None

This effectively switches it off and it never does anything ever again.

Obviously you need to be doing stuff you do not wish to roll-back - ever.


> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users...@googlegroups.com
> <mailto:django-users...@googlegroups.com>.
> To post to this group, send email to django...@googlegroups.com
> <mailto:django...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/a60b8ed4-a5a6-40c8-b959-17e2a3ec3363%40googlegroups.com
> <https://groups.google.com/d/msgid/django-users/a60b8ed4-a5a6-40c8-b959-17e2a3ec3363%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

James Schneider

unread,
Aug 29, 2017, 7:39:16 PM8/29/17
to django...@googlegroups.com
On Tue, Aug 29, 2017 at 1:43 PM, Matt S <dope...@gmail.com> wrote:
Standard practice is that you do not refer to "current" models (i.e. from app.models import MyModel) in a migration as the migration will break when that models changes. This means copying any model-specific code into the migration. This becomes impractical when the code needed for the migration spans multiple files and models.

How can I encapsulate a complex chain of business logic involving multiple models in a migration? For example, if I have instance methods on ModelA which calls methods on ModelB, ModelB queries for ModelC and calls methods on it. If I use those methods as they exist on the models, the migration will eventually break when any of the involved Models' schema changes.

I would copy any instance method logic in to separate functions that live within the individual migration file. Yes, you'll be copy/pasting code that could live in models, but you need to capture the exact logic used for that migration step, which should never change moving forward. This isn't code that you'll be actively maintaining or referring to and shouldn't change once the migration has been applied. 

You do have access to a skeleton version of the models via a RunPython callback in each migration state by calling apps.get_model(), however, it only includes the model fields to be used for querying, not any of the instance methods. 


-James

Antonis Christofides

unread,
Aug 30, 2017, 4:22:15 AM8/30/17
to django...@googlegroups.com

Hello,

Another option that might or might not work would be to violate the rule and do refer to "current" models during the migration to version X, but thereafter reset your migrations and only support migration to X+1 from X, not from earlier versions. This would need detailed release notes about the migration procedure, so whether it's a decent solution depends on your release management practices.

Regards,

Antonis

Antonis Christofides
http://djangodeployment.com
On 2017-08-29 23:43, Matt S wrote:
Standard practice is that you do not refer to "current" models (i.e. from app.models import MyModel) in a migration as the migration will break when that models changes. This means copying any model-specific code into the migration. This becomes impractical when the code needed for the migration spans multiple files and models.

How can I encapsulate a complex chain of business logic involving multiple models in a migration? For example, if I have instance methods on ModelA which calls methods on ModelB, ModelB queries for ModelC and calls methods on it. If I use those methods as they exist on the models, the migration will eventually break when any of the involved Models' schema changes.
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages