Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syncing data between devel/live databases in Django

With Django's new multi-db functionality in the development version, I've been trying to work on creating a management command that let's me synchronize the data from the live site down to a developer machine for extended testing. (Having actual data, particularly user-entered data, allows me to test a broader range of inputs.)

Right now I've got a "mostly" working command. It can sync "simple" model data but the problem I'm having is that it ignores ManyToMany fields which I don't see any reason for it do so. Anyone have any ideas of either how to fix that or a better want to handle this? Should I be exporting that first query to a fixture first and then re-importing it?

from django.core.management.base import LabelCommand
from django.db.utils import IntegrityError
from django.db import models
from django.conf import settings

LIVE_DATABASE_KEY = 'live'

class Command(LabelCommand):
    help = ("Synchronizes the data between the local machine and the live server")
    args = "APP_NAME"
    label = 'application name'

    requires_model_validation = False
    can_import_settings = True

    def handle_label(self, label, **options):

        # Make sure we're running the command on a developer machine and that we've got the right settings
        db_settings = getattr(settings, 'DATABASES', {})
        if not LIVE_DATABASE_KEY in db_settings:
            print 'Could not find "%s" in database settings.' % LIVE_DATABASE_KEY
            return

        if db_settings.get('default') == db_settings.get(LIVE_DATABASE_KEY):
            print 'Data cannot synchronize with self.  This command must be run on a non-production server.'
            return

        # Fetch all models for the given app
        try:
            app = models.get_app(label)
            app_models = models.get_models(app)
        except:
            print "The app '%s' could not be found or models could not be loaded for it." % label

        for model in app_models:
            print 'Syncing %s.%s ...' % (model._meta.app_label, model._meta.object_name)

            # Query each model from the live site
            qs = model.objects.all().using(LIVE_DATABASE_KEY)

            # ...and save it to the local database
            for record in qs:
                try:
                    record.save(using='default')
                except IntegrityError:
                    # Skip as the record probably already exists
                    pass
like image 220
T. Stone Avatar asked Nov 06 '22 15:11

T. Stone


1 Answers

Django command extension's Dumpscript should help a lot.

like image 145
Pierre-Jean Coudert Avatar answered Nov 11 '22 04:11

Pierre-Jean Coudert