This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
django-sync/django_sync/management/commands/sync-with-remote.py

54 lines
2.0 KiB
Python

from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction, connections
from django.db.models.loading import get_model
class Command(BaseCommand):
args = '<app1.model1 app1.model2 app2.model3>'
help = 'Synchronize models between DBs'
option_list = BaseCommand.option_list + (
make_option('--from',
default='remote',
help='Database id to pull objects from',
),
make_option('--to',
default='default',
help='Database id to push objects to',
),
)
def handle(self, *args, **options):
models = []
for arg in args:
try:
app_label, model_name = arg.split('.', 1)
except ValueError:
raise CommandError('invalid model name %s' % model)
models.append(get_model(app_label, model_name))
db_from = options['from']
db_to = options['to']
try:
connections[db_from]
except KeyError:
raise CommandError('unknown db %s' % db_from)
try:
connections[db_to]
except KeyError:
raise CommandError('unknown db %s' % db_to)
with transaction.commit_on_success(db_to):
connections[db_to].cursor().execute('SET CONSTRAINTS ALL DEFERRED')
while models:
model, models = models[0], models[1:]
opts = model._meta
qs_from = model.objects.using(db_from).all()
for instance in qs_from:
instance.save(using=db_to)
for many_to_many_field in opts.many_to_many:
through_model = getattr(model, many_to_many_field.name).through
models.insert(0, through_model)
qs_to = model.objects.using(db_to).exclude(id__in=list(qs_from.values_list('id', flat=True)))
qs_to.delete()