54 lines
2.0 KiB
Python
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()
|