#25947: Query's str() method fails when 'default' database is empty
-------------------------------------+-------------------------------------
     Reporter:  liboz                |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  1.9
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by timgraham):

 * needs_better_patch:   => 0
 * component:  Uncategorized => Database layer (models, ORM)
 * needs_tests:   => 0
 * needs_docs:   => 0
 * type:  Uncategorized => Bug
 * stage:  Unreviewed => Accepted


Old description:

> According to the [https://docs.djangoproject.com/en/1.9/topics/db/multi-
> db/ docs], we can have
> {{{
> default database...[with]...parameters dictionary...blank if it will not
> be used.
> }}}
>
> However, when trying to print a query with something like:
> {{{
> print Question.objects.all().query
> }}}
>

> you get the error that
> {{{
> settings.DATABASES is improperly configured. Please supply the ENGINE
> value.
> }}}
>
> even though the query itself can return results.
>
> You can replicate this by creating a new project, creating a router that
> routes everything to a test database like so:
>

> {{{
> class Router(object):
>     def db_for_read(self, model, **hints):
>         """
>         Reads go to a randomly-chosen replica.
>         """
>         return 'test'
>
>     def db_for_write(self, model, **hints):
>         """
>         Writes always go to primary.
>         """
>         return 'test'
>
>     def allow_relation(self, obj1, obj2, **hints):
>         """
>         Relations between objects are allowed if both objects are
>         in the primary/replica pool.
>         """
>         return True
>
>     def allow_migrate(self, db, app_label, model=None, **hints):
>         """
>         All non-auth models end up in this pool.
>         """
>         return True
>

> # Database
> # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
> DATABASE_ROUTERS = ['test123.settings.Router']
> DATABASES = {
>     'default': {},
>     'test': {
>         'ENGINE': 'django.db.backends.sqlite3',
>         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
>     }
> }
> }}}
>
> Create a simple model like this one:
>

> {{{
> from django.db import models
>
> # Create your models here.
> class Question(models.Model):
>     question_text = models.CharField(max_length=200)
>     pub_date = models.DateTimeField('date published')
> }}}
>
> and run the appropriate migrations on the test database.
>
> Then attempting to print the query will fail, but the query itself will
> work. I believe the error is because the sql_with_params method in
> django.db.models.sql.query forces the uses of the DEFAULT_DB_ALIAS:
>

> {{{
> def sql_with_params(self):
>         """
>         Returns the query as an SQL string and the parameters that will
> be
>         substituted into the query.
>         """
>         return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
> }}}

New description:

 According to the [https://docs.djangoproject.com/en/1.9/topics/db/multi-
 db/ docs], we can have
 {{{
 default database...[with]...parameters dictionary...blank if it will not
 be used.
 }}}

 However, when trying to print a query with something like:
 {{{
 print Question.objects.all().query
 }}}


 you get the error that
 {{{
 settings.DATABASES is improperly configured. Please supply the ENGINE
 value.
 }}}

 even though the query itself can return results.

 You can replicate this by creating a new project, creating a router that
 routes everything to a test database like so:


 {{{
 class Router(object):
     def db_for_read(self, model, **hints):
         """
         Reads go to a randomly-chosen replica.
         """
         return 'test'

     def db_for_write(self, model, **hints):
         """
         Writes always go to primary.
         """
         return 'test'

     def allow_relation(self, obj1, obj2, **hints):
         """
         Relations between objects are allowed if both objects are
         in the primary/replica pool.
         """
         return True

     def allow_migrate(self, db, app_label, model=None, **hints):
         """
         All non-auth models end up in this pool.
         """
         return True


 # Database
 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
 DATABASE_ROUTERS = ['test123.settings.Router']
 DATABASES = {
     'default': {},
     'test': {
         'ENGINE': 'django.db.backends.sqlite3',
         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
     }
 }
 }}}

 Create a simple model like this one:


 {{{
 from django.db import models

 # Create your models here.
 class Question(models.Model):
     question_text = models.CharField(max_length=200)
     pub_date = models.DateTimeField('date published')
 }}}

 and run the appropriate migrations on the test database.

 Then attempting to print the query will fail, but the query itself will
 work. I believe the error is because the sql_with_params method in
 django.db.models.sql.query forces the uses of the DEFAULT_DB_ALIAS:


 {{{
 def sql_with_params(self):
     """
     Returns the query as an SQL string and the parameters that will be
     substituted into the query.
     """
     return self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
 }}}

--

Comment:

 I guess this might be tricky to fix for reasons similar to this comment in
 the file: "We need to use DEFAULT_DB_ALIAS here, as QuerySet does not have
 (nor should it have) knowledge of which connection is going to be used."

--
Ticket URL: <https://code.djangoproject.com/ticket/25947#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" 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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/063.45c661c5b9dad7a4149078c65fe64bcb%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to