-
-
Save danni/1b2a0078e998ac080111 to your computer and use it in GitHub Desktop.
Django function for loading fixtures which use the current migration state of the model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import logging | |
from django.core import serializers | |
LOGGER = logging.getLogger(__name__) | |
def load_fixture(app, fixture, ignorenonexistent=True): | |
""" | |
A factory to load a named fixture via a data migration. | |
""" | |
def inner(apps, schema_editor): | |
""" | |
Loads migrations that work at current state of a model, in constrast to | |
`loaddata` which requires a fixture to have data matching the fields | |
defined in `models.py`. | |
Based on https://gist.github.com/leifdenby/4586e350586c014c1c9a | |
""" | |
# relative path to fixtures | |
fixtures_dir = os.path.join(app, 'fixtures') | |
# monkey patch serializers `apps` so that it uses the models in the | |
# current migration state | |
original_apps = serializers.python.apps | |
try: | |
serializers.python.apps = apps | |
objects = None | |
for extension in ('json', 'yaml', 'xml'): | |
fixture_path = os.path.join( | |
fixtures_dir, | |
'%s.%s' % (fixture, extension)) | |
LOGGER.debug("Trying %s", fixtures_dir) | |
if os.path.exists(fixture_path): | |
print("Loading fixtures from %s... " % fixture_path) | |
with open(fixture_path, 'rb') as file_: | |
objects = serializers.deserialize( | |
extension, file_, | |
ignorenonexistent=ignorenonexistent) | |
count = 0 | |
for obj in objects: | |
obj.save() | |
count += 1 | |
print("Loaded %d objects." % count) | |
if objects is None: | |
raise Exception( | |
"Couldn't find the '%s' fixture for the '%s' app." % ( | |
fixture, app)) | |
finally: | |
serializers.python.apps = original_apps | |
return inner |
Solved!
def forwards_func(apps, schema_editor):
command = load_fixture("users", "initial_data")
command(apps, schema_editor)
Designed as a factory so: `forwards_func = load_fixture(...)`
…On 12 Sep 2020, 21:29 +1000, Ian Yardley ***@***.***>, wrote:
@yardley commented on this gist.
Solved!
def forwards_func(apps, schema_editor):
command = load_fixture("users", "initial_data")
command(apps, schema_editor)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
I understand now, thank you.
operations = [
migrations.RunPython(load_fixture("users", "initial_data"), reverse_func),
]
Using django-cookiecutter, since apps are inside project folder I needed to
operations = [
migrations.RunPython(load_fixture("project_folder/name_app", "initial_data"), reverse_func),
]
This doesn't appear to handle auto increment sequences. Django's loaddata
command does the following:
if self.loaded_object_count > 0:
sequence_sql = connection.ops.sequence_reset_sql(no_style(), self.models)
if sequence_sql:
with connection.cursor() as cursor:
for line in sequence_sql:
cursor.execute(line)
Without something like this anyone who uses this is going to run into primary key conflicts.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for modifying the original script. How should this be run from a migration file?
The objects are inserted but I get an error
CommandError: Unknown command: None
This was my migration, perhaps you can advise how you run it?