release 1.0
This commit is contained in:
commit
f4cb942fa4
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) Entr'ouvert
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of Django nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,24 @@
|
|||
Install
|
||||
-------
|
||||
|
||||
Add application to your INSTALLED_APPS::
|
||||
|
||||
INSTALLED_APPS += ('django_sync',)
|
||||
|
||||
Add a remote DB to your DATABASES setting::
|
||||
|
||||
DATABASES['remote'] = {
|
||||
'remote': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'remote',
|
||||
},
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
./manage.py sync-with-remote [--from=remote] [--to=default] <app.model...>
|
||||
|
||||
Synchronize models in order from the remote db to the default db, or other db
|
||||
if specified. You must order your models so that no model at the start refer to
|
||||
model at the end of the list, through a foreign key field or a many to many
|
||||
field.
|
|
@ -0,0 +1,53 @@
|
|||
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()
|
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
This file demonstrates writing tests using the unittest module. These will pass
|
||||
when you run "manage.py test".
|
||||
|
||||
Replace this with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.assertEqual(1 + 1, 2)
|
|
@ -0,0 +1 @@
|
|||
# Create your views here.
|
|
@ -0,0 +1,17 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name="django-sync",
|
||||
version='1.0',
|
||||
license="BSD",
|
||||
description="Synchronize django models between DBs",
|
||||
author="Entr'ouvert",
|
||||
author_email="info@entrouvert.org",
|
||||
maintainer="Benjamin Dauvergne",
|
||||
maintainer_email="info@entrouvert.com",
|
||||
include_package_data=True,
|
||||
packages=find_packages(),
|
||||
install_requires=[],
|
||||
dependency_links=[],
|
||||
)
|
Reference in New Issue