#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.