Skip to content

compiler.py allows for Multiquery with keys_only #100

Description

@manubotija

Deleting one object from the Admin Panel from which two or more objects depend on, results on an error at compiler.py because it is trying to do a multiquery with keys_only which is forbidden by GAE

#!python

Environment:


Request Method: POST
Request URL: http://localhost:8000/admin/frontend/project/5471719615627264/delete/

Django Version: 1.5.8
Python Version: 2.7.5
Installed Applications:
('django.contrib.auth',
 'registration',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'djangotoolbox',
 'autoload',
 'dbindexer',
 'frontend',
 'djangoappengine')
Installed Middleware:
('google.appengine.ext.appstats.recording.AppStatsDjangoMiddleware',
 'autoload.middleware.AutoloadMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/Users/manubotija/Dev/repos/js3.0/django/core/handlers/base.py" in get_response
  113.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/contrib/admin/options.py" in wrapper
  372.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/views/decorators/cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/contrib/admin/sites.py" in inner
  202.             return view(request, *args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/utils/decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/utils/decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "/Users/manubotija/Dev/repos/js3.0/django/db/transaction.py" in inner
  223.                 return func(*args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/contrib/admin/options.py" in delete_view
  1333.             self.delete_model(request, obj)
File "/Users/manubotija/Dev/repos/js3.0/django/contrib/admin/options.py" in delete_model
  746.         obj.delete()
File "/Users/manubotija/Dev/repos/js3.0/django/db/models/base.py" in delete
  698.         collector.delete()
File "/Users/manubotija/Dev/repos/js3.0/django/db/models/deletion.py" in decorated
  62.             func(self, *args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/django/db/models/deletion.py" in delete
  293.             qs._raw_delete(using=self.using)
File "/Users/manubotija/Dev/repos/js3.0/django/db/models/query.py" in _raw_delete
  562.         sql.DeleteQuery(self.model).delete_qs(self, using)
File "/Users/manubotija/Dev/repos/js3.0/django/db/models/sql/subqueries.py" in delete_qs
  84.         self.get_compiler(using).execute_sql(None)
File "/Users/manubotija/Dev/repos/js3.0/djangotoolbox/db/basecompiler.py" in execute_sql
  641.             self.build_query([self.query.get_meta().pk]).delete()
File "/Users/manubotija/Dev/repos/js3.0/djangoappengine/db/compiler.py" in _func
  72.             return func(*args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/djangoappengine/db/compiler.py" in delete
  169.             keys = [key_dict[self.query.get_meta().pk.column] for key_dict in self.fetch()]
File "/Users/manubotija/Dev/repos/js3.0/djangoappengine/db/compiler.py" in fetch
  108.         query = self._build_query()
File "/Users/manubotija/Dev/repos/js3.0/djangoappengine/db/compiler.py" in _func
  72.             return func(*args, **kwargs)
File "/Users/manubotija/Dev/repos/js3.0/djangoappengine/db/compiler.py" in _build_query
  325.             return MultiQuery(self.gae_query, self.ordering)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/datastore.py" in __init__
  2024.             'MultiQuery does not support keys_only.')

Exception Type: DatabaseError at /admin/frontend/project/5471719615627264/delete/
Exception Value: MultiQuery does not support keys_only.

This workaround solves the issue but it is a bad solution since it makes all queries not keys_only by default and therefore increases quota usage:


diff --git a/djangoappengine/db/compiler.py b/djangoappengine/db/compiler.py
index c2a5301..f2af272 100644
--- a/djangoappengine/db/compiler.py
+++ b/djangoappengine/db/compiler.py
@@ -96,7 +96,7 @@ class GAEQuery(NonrelQuery):
         start_cursor = getattr(self.query, '_gae_start_cursor', None)
         end_cursor = getattr(self.query, '_gae_end_cursor', None)
         self.config = getattr(self.query, '_gae_config', {})
-        self.gae_query = [Query(self.db_table, keys_only=self.pks_only,
+        self.gae_query = [Query(self.db_table, keys_only=False,
                                 cursor=start_cursor, end_cursor=end_cursor)]

     # This is needed for debugging.
@@ -301,7 +301,7 @@ class GAEQuery(NonrelQuery):
         for query in gae_query:
             for op, value in op_values:
                 self.gae_query = [Query(self.db_table,
-                                        keys_only=self.pks_only)]
+                                        keys_only=False)]
                 self.gae_query[0].update(query)
                 self._add_filter(field, op, value)
                 combined.append(self.gae_query[0])

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions