#29801: Feature Suggestion for Migrations
-------------------------------------+-------------------------------------
Reporter: Calvin | Owner: nobody
DeBoer |
Type: New | Status: new
feature |
Component: | Version: master
Migrations | Keywords: environments
Severity: Normal | migrations
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
=== Background
Django's current recommendation for adding data to a application is
through the well documented "DataMigration" via `RunSQL` and `RunPython`
calls. This represents an improvement over the fixture loading for a
variety of reasons (it doesn't force developers to keep their fixtures up
to date, control over overwriting data ,etc). Fixtures would be great if
they didn't have to be kept up to date with the DB's current state (more
on that later). As the applications we've been building with Django have
grown in complexity we've seen an increase in the need to have control
over which data is created in different application environments. For
example, in production we want to add a large dataset `foo` (production
data), but in development we only want to load a smaller dataset `bar`
(for Developer Experience); furthermore, in tests we don't want to add ANY
data because we want the tests, `setUp` method to granularly control what
data is available in the DB with that set of tests. For the test piece, we
investigated setting the `MIGRATION_MODULES` setting to None for all the
apps in a `test_settings` file, but that seemed heavy handed, and also
only handled a single application environment.
=== Suggestion
1. add a method called `loaddata` that takes a fixture and `apps` <- (the
model context within a migration from which one can obtain a `FakeModel`
instance representing the Model at state of that migration.
{{{#!python
import os
from django.db import migrations
import environize
PATH = 'path/to/fixtures/'
def load_fixture(apps, schema_editor):
fixture_file = os.path.join(PATH, 'myfixture.json')
environize.loaddata(apps, fixture_file)
class Migration(migrations.Migration):
dependencies = [
('app', '0003_auto_20180916_1122'),
]
operations = [
migrations.RunPython(load_fixture, lambda x, y: None)
]
}}}
2. allow `RunPython` and `RunSQL` to take an additional keyword that will
tell django which envs to include or exclude in a `DataMigration`.
{{{#!python
class Migration(migrations.Migration):
dependencies = [
('app', '0002_auto_20180916_1122'),
]
operations = [
migrations.RunPython(add_prod_data, remove_hams,
only_in=['production']),
migrations.RunSQL(""INSERT blah;", "REMOVE blah;",
except_in=['test'])
]
}}}
=== Implementation
https://github.com/cgdeboer/environize
Here is a hastily put together library to allow environments inside
migrations and have state specific `loaddata` . The environment stuff is
implemented as decorators on the function at the moment, probably makes
more sense to just inherit `RunPython` and `RunSQL` and provide the
keywords shows above in example 2.
Probably makes the most sense to continue to develop this as a package
outside of Django, but before I do that, thought I'd see if there is any
appetite for it in core django.
--
Ticket URL: <https://code.djangoproject.com/ticket/29801>
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/051.3c816849c00649eba0b30baf8e8f469b%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.