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.