Prepopulate database with fixtures or with script?

2019-07-11 02:47发布

问题:

I'm not an expert but I think is a good idea using a Class to define choices and to prepopulate the database with these choices. I think that make easier to change choices, etc

So in my models.py I have:

class City(models.Model):
    name = models.CharField(max_length=32)
    distance = models.SmallIntegerField(blank=True, null=True)
    #etc

class OtherClass(models.Model):
    name = models.CharField(max_length=32)
    #etc

class UserProfile(models.Model):
    name = models.CharField(max_length=32)
    city = models.ForeignKey(City)
    otherfield = models.ForeignKey(OtherClass)
    #etc

UserProfile is what the users compile, City, OtherClass is where the programmer puts the options.

After the migration I have to create some City and OtherClass objects: they will be the options (and yes they have to be fixed).

I Just find out about the fixtures. Until now I was using a script:

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sitopossedimenti.settings')

import django
django.setup()

from core.models import *

def populate():
    namecity1 = add_source('city1', None)
    namecity2 = add_source('city2', None)
    @etc

    nameotherclass1 = add_otherclass('name1', #etc)

    #etc some thousands more

def add_source(name, distance):
    s = model.Source.objects.get_or_create(name=name, distance=distance)[0]
    s.save()
    return s

def add_otherclass:
    #etc

if __name__ == '__main__':
    print ("Starting myapp population script...")
    populate()

For now the script works (about) and I'm afraid to change... but what do you think? Are the fixtures better? Why? There're differences?

回答1:

As the saying goes, if it works don't fix it. Fixtures is the more usual method but no harm in using your own. If you were writing a new test case, you might want to use fixtures, but If I were you I would just let this be.

If you want a fully automated way of achieving the result, consider migration.RunPython. The linked document contains a full example which shows data being loaded. Obviously this will happen with ./manage.py migrate without the need of an additional step.

The advantage of using migrations.RunPython is that if you were to share your app with a colleague or install on a different server, the required data will automatically be loaded into the production server and the tests will also have full access to it in the test database.