Pregunta

When I do a filter on a ForeignKey field with __isnull=True, this exception is raised:

DatabaseError: This query is not supported by the database.

However, __isnull=False on ForeignKey works as long as there are no other inequality filters (which I would expect). And __isnull=True works for other field types.

So why does __isnull=True not work on ForeignKey? It seems that DBIndexer tries to make it work as shown here: https://github.com/django-nonrel/django-dbindexer/blob/dbindexer-1.4/dbindexer/backends.py

But then there is an exception in djangotoolbox:

  File "/Users//Documents/workspace/-gae-dev/src/django/db/models/query.py", line 107, in _result_iter
    self._fill_cache()
  File "/Users//Documents/workspace/-gae-dev/src/django/db/models/query.py", line 774, in _fill_cache
    self._result_cache.append(self._iter.next())
  File "/Users//Documents/workspace/-gae-dev/src/django/db/models/query.py", line 275, in iterator
    for row in compiler.results_iter():
  File "/Users//Documents/workspace/-gae-dev/src/djangotoolbox/db/basecompiler.py", line 337, in results_iter
    results = self.build_query(fields).fetch(
  File "/Users//Documents/workspace/-gae-dev/src/djangotoolbox/db/basecompiler.py", line 428, in build_query
    self.check_query()
  File "/Users//Documents/workspace/-gae-dev/src/djangotoolbox/db/basecompiler.py", line 409, in check_query
    raise DatabaseError("This query is not supported by the database.")

I did come across the following commented-out test case in djangoappengine, and am wondering if is referring to the same issue?

    def test_is_null(self):
        self.assertEquals(FieldsWithOptionsModel.objects.filter(
            floating_point__isnull=True).count(), 0)

        FieldsWithOptionsModel(
            integer=5.4, email='shinra.tensai@sixpaths.com',
            time=datetime.datetime.now().time()).save()

        self.assertEquals(FieldsWithOptionsModel.objects.filter(
            floating_point__isnull=True).count(), 1)

        # XXX: These filters will not work because of a Django bug.
#        self.assertEquals(FieldsWithOptionsModel.objects.filter(
#            foreign_key=None).count(), 1)

        # (it uses left outer joins if checked against isnull)
#        self.assertEquals(FieldsWithOptionsModel.objects.filter(
#            foreign_key__isnull=True).count(), 1)
¿Fue útil?

Solución

Alex Burgel on the NonRel project set me straight:

The NonRel/dbindexer project fixes this query (which otherwise doesn't work due to this Django bug: https://code.djangoproject.com/ticket/10790). To set up dbindexer:

  • of course, add it to INSTALLED_APPS
  • also in settings.py, set DATABASES['default]['ENGINE']= 'dbindexer'
  • also in settings.py, set DBINDEXER_BACKENDS to use FKNullFix. For example:

DBINDEXER_BACKENDS = ( 'dbindexer.backends.BaseResolver', 'dbindexer.backends.FKNullFix', 'dbindexer.backends.InMemoryJOINResolver', 'dbindexer.backends.ConstantFieldJOINResolver', )

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top