-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQIcBAEBCAAGBQJWsMqdAAoJEC0ft5FqUuEhNasQAKWmBUnN+uWZbOPAnlfqbgUp
7hvYyxuSQ6QV/9RejSRulgGQvQmbR2cEsZsnpQAyM95HjMqMDrvbZldxMbv173kg
dxG1lc0WzQSZkH9aDoN2gFioUhNHEchOKfSnhCUkNxgyL5a2l5LaW53qV61qIlTR
lDK0NUNnPjMOKqT0TITdPAEwqvmbRoz8mKKSs+B8VV58qLQuzUi2NIWCXSMVFfQ/
OJmUR2Wmzog3N2QOg+TAWX/BDdh9Y1cXMg4d6IMHR+awCY1Br8AH/z4713yaHyGT
TaUfdOeJqxII17u4XewjFMqDHnROD2ab7O0AkKokNeBlkcrrFc/3SOonG1bcj7x8
OxvINZEiBUaY9vFIZDf6Kwc3yOPqTL3xAr/fOxIAvGyuuHrsGlo/eW60YKIxB5mC
5YE3LvP7fj85MNI4J73C6oeRhlWOrCdtm+MIyi0Wz2AaxV9qSxESfYNF3lI6y3Mj
MZvVQIHs9yTXukzvWgRvhepQZBrD5+TlQ2YqknxxwJl0uZ/MgJwhPqm05C4qASPv
lXuHVplg/4zDgnmQS4RN9mghiZIsKxduSFYZm1nbhKqjGQnqdmE3B1RnoZjyrn/1
u1OTe2snHafsTAoy25KsSZ91lhGtig05D4R4uqn55y+pdSJDpHPM40GPPUAdVisP
rTK4+y+fVFKP8sb3g4Ia
=AWP/
-----END PGP SIGNATURE-----
Hi Vinay,
On 02/02/2016 08:11 AM, 'Vinay Sajip' via Django users wrote:
> 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:
>
> |
> classThing(models.Model):
> name =models.CharField(max_length=20,unique=True)
> |
>
> I have a simple management command:
>
> |
> classCommand(BaseCommand):
> help ='Add all the things.'
>
>
> defadd_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')
>
>
> defhandle(self,*args,**options):
> alias=options['database']
> self.stdout.write('using alias %s'%alias)
> withtransaction.atomic(using=alias):
> forname inoptions['things']:
> try:
> Thing.objects.create(name=name)
> self.stdout.write('Added %s.\n'%name)
> exceptIntegrityErrorase:
> 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:
>
> |
> usingaliasbar
> Failedto 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.
Nothing in your code ever "overrides" settings.DATABASES['default'].
Defining an atomic block on a certain database has no effect on the
default database within that block, it just opens a transaction on the
requested database. "Which database is default" and "which database(s)
has/have transactions open on them" are completely orthogonal questions,
there is no implicit link between them. Nothing prevents you from having
simultaneous transactions open on multiple databases, and interspersing
queries to different databases while those transactions are open.
If calling .using() explicitly to use a non-default database is
burdensome (and the situation can't be handled automatically with a
custom database router class), you could look at a third-party solution
like django-dynamic-db-router [1], which provides an `in_database`
context manager that does what you were expecting `transactions.atomic`
to do for you.
Carl
[1]
https://github.com/ambitioninc/django-dynamic-db-router/blob/master/docs/quickstart.rst
--
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+unsubscribe@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/56B0CA99.2090308%40oddbird.net.
For more options, visit https://groups.google.com/d/optout.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment