I've set up a simple project using with two databases, foo and bar in 
settings.py:

DATABASES = {
    'foo': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'foo.sqlite'),
    },
    'bar': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'bar.sqlite'),
    }
}
DATABASES['default'] = DATABASES['foo']


I have a simple model:

class Thing(models.Model):
    name = models.CharField(max_length=20, unique=True)

I have a simple management command:

class Command(BaseCommand):
    help = 'Add all the things.'


    def add_arguments(self, parser):
        parser.add_argument('--database', nargs='?', metavar='DATABASE',
                            default='default',
                            help='Database alias to use')
        parser.add_argument('things', nargs='+', metavar='THING',
                            help='Things to add')


    def handle(self, *args, **options):
        alias = options['database']
        self.stdout.write('using alias %s' % alias)
        with transaction.atomic(using=alias):
            for name in options['things']:
                try:
                    Thing.objects.create(name=name)
                    self.stdout.write('Added %s.\n' % name)
                except IntegrityError as e:
                    self.stderr.write('Failed to add thing %r: %s' % (name, 
e))
                    break

After running migrations to set up the two databases, using python 
manage.py migrate --data foo and python manage.py migrate --data bar, I 
then run python manage.py add_things fizz buzz which results in two records 
being added to foo.sqlite, as expected. 

If I then run python manage.py add_things fizz buzz --data bar, it seems 
reasonable to expect it to add the records to bar.sqlite. However, this is 
not what happens: it tries to add them to foo.sqlite, even though I've 
specified using=alias with the alias set to bar. So I get a constraint 
violation:

using alias bar
Failed to add thing 'fizz': UNIQUE constraint failed: hello_thing.name

What have I overlooked? In a real case the atomic block might be 
manipulating lots of models in nested code, and I can't see that it's 
practical to call using() for every model. Somewhere, it looks like Django 
code is caching a connection based on what settings.DATABASES['default'] 
was when settings was imported, even though it is being overridden in the 
command line. If not actually a bug, this behaviour doesn't seem 
particularly intuitive, so any advice would be gratefully received.

Regards,

Vinay Sajip

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/c61ddb5b-a5cb-460d-a109-b30ccd7d2a78%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to