How to load fixtures in the south-jungo?

I use Django 1.5b1 and southern migrations, and life in general was great. I have some schema updates that create my database, with a User table among others. Then I load the fixture for ff.User (my user model):

 def forwards(self, orm): from django.core.management import call_command fixture_path = "/absolute/path/to/my/fixture/load_initial_users.json" call_command("loaddata", fixture_path) 

Everything works fine until I added another field to my ff.User model, much further along the migration line. My binding is now breaking:

 DatabaseError: Problem installing fixture 'C:\<redacted>create_users.json': Could not load ff.User(pk=1): (1054, "Unknown column 'timezone_id' in 'field list'") 

The time zone is the (ForeignKey) field that I added to my user model.

ff.User is different from what is in the database, so Django ORM refuses DB error. Unfortunately, I cannot specify my model in my device as orm['ff.User'] , which seems to be a southern way of doing things.

How should I correctly load the fixtures with the help of the south, so that they do not break after the models for which these fixtures have been changed have been changed?

+4
source share
6 answers

Reading the following two posts helped me come up with a solution:

http://andrewingram.net/2012/dec/common-pitfalls-django-south/#be-careful-with-fixtures

http://news.ycombinator.com/item?id=4872596

In particular, I rewrote data migration to use the output from 'dumpscript'

I needed to slightly modify the resulting script result to work with the south. Instead of doing

 from ff.models import User 

I do

 User = orm['ff.User'] 

It works exactly the way I wanted it. In addition, it does not have the advantage of hard coding identifiers as required.

-1
source

I found a Django snippet that does the job!

https://djangosnippets.org/snippets/2897/

Loads data according to the models frozen in the device, and not the actual definition of the model in the application code! Great for me.

+5
source

I have proposed a solution that may interest you:

fooobar.com/questions/954731 / ...

Basically, this is how I boot my device:

 from south.v2 import DataMigration import json class Migration(DataMigration): def forwards(self, orm): json_data=open("path/to/your/fixture.json") items = json.load(json_data) for item in items: # Be carefull, this lazy line won't resolve foreign keys obj = orm[item["model"]](**item["fields"]) obj.save() json_data.close() 
+1
source

It was a disappointing part of using fixtures for me. My solution was to make some helper tools. One that creates fixtures by selecting data from a database and includes a history of south migration in fixtures.

There is also a tool to add South migration history to existing fixtures.

The third tool checks the fixation when this fixture has been changed, loads the instrument, then checks the last fixation and performs southern migration and unloads the transferred db back to the instrument. This is done in a separate database, so your default dB does not fall.

The first two can be considered beta, and the third, please consider it as useful alpha, but they are already very useful for me.

I would like to get some feedback from others: git @ github.com: JivanAmara / django_fixture_tools.git Currently, it only supports projects using git as RCS.

0
source

The most elegant solution I found is here , where according to your application model get_model function is disabled to supply the model from the supplied orm instead. Then he returns after using the device.

 from django.db import models from django.core.management import call_command def load_fixture(file_name, orm): original_get_model = models.get_model def get_model_southern_style(*args): try: return orm['.'.join(args)] except: return original_get_model(*args) models.get_model = get_model_southern_style call_command('loaddata', file_name) models.get_model = original_get_model 

You call it with load_fixture('my_fixture.json', orm) from inside your forward.

0
source

Typically, South handles migrations using the forwards() and backwards() functions. In your case, you should either:

  • modify fixtures to contain relevant data, or
  • import the device before the transfer, which breaks it (or within the same migration, but before changing the scheme),

In the second case, before adding the transfer (or, as in your case, deleting) the column, you must perform a migration that will explicitly load devices similar to this ( docs ):

 def forwards(self, orm): from django.core.management import call_command call_command("loaddata", "create_users.json") 

I believe this is the easiest way to accomplish what you need. Also make sure that you are not making some simple mistakes, for example, trying to import data with a new structure before applying older migrations.

-1
source

Source: https://habr.com/ru/post/954727/


All Articles