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 django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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