Skip to content

Fix displaying RawQuerySet in sql_explain view #1104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 19, 2018

Conversation

todorvelichkov
Copy link
Contributor

@todorvelichkov todorvelichkov commented Sep 19, 2018

This problem may be a regression from #309, but I'm not 100% sure.

Trying to do sql_explain on raw query with dictionary for params causes a crash.

ERROR Internal Server Error: /__debug__/sql_explain/
Traceback (most recent call last):
  File "../site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "../site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "../site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "../site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "../site-packages/debug_toolbar/decorators.py", line 15, in inner
    return view(request, *args, **kwargs)
  File "../site-packages/debug_toolbar/panels/sql/views.py", line 61, in sql_explain
    cursor.execute("EXPLAIN %s" % (sql,), params)
  File "../site-packages/debug_toolbar/panels/sql/tracking.py", line 188, in execute
    return self._record(self.cursor.execute, sql, params)
  File "../site-packages/debug_toolbar/panels/sql/tracking.py", line 121, in _record
    return method(sql, params)
  File "../site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "../site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "../site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "../site-packages/MySQLdb/cursors.py", line 159, in execute
    query = query % db.literal(args)
TypeError: format requires a mapping

The reason is because params is not dictionary, but list.

The core of the issue is caused by panels/sql/traking.py

    _params = json.dumps([self._decode(p) for p in params])

This forces only dictionary keys to be send over sql_explain view.

My change is going to preserve the initial params structure.

    _params = json.dumps(self._decode(params))

Now, because dictionary params are not supported by the SQLite backend.
My test is going to be skipped for this vendor.

Trying to do sql_explain on raw query with dictionary causes a crash.

```
ERROR Internal Server Error: /__debug__/sql_explain/
Traceback (most recent call last):
  File "../site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "../site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "../site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "../site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "../site-packages/debug_toolbar/decorators.py", line 15, in inner
    return view(request, *args, **kwargs)
  File "../site-packages/debug_toolbar/panels/sql/views.py", line 61, in sql_explain
    cursor.execute("EXPLAIN %s" % (sql,), params)
  File "../site-packages/debug_toolbar/panels/sql/tracking.py", line 188, in execute
    return self._record(self.cursor.execute, sql, params)
  File "../site-packages/debug_toolbar/panels/sql/tracking.py", line 121, in _record
    return method(sql, params)
  File "../site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "../site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "../site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "../site-packages/MySQLdb/cursors.py", line 159, in execute
    query = query % db.literal(args)
TypeError: format requires a mapping
```

The reason is because `params` is not dictionary, but list.

The core of the issue is caused by `panels/sql/traking.py`
```
    _params = json.dumps([self._decode(p) for p in params])
```
This forces only dictionary keys to be send over sql_explain view.

My change is going to preserve the initial params structure.
```
    _params = json.dumps(self._decode(params))
```

Now, because dictionary params are not supported by the SQLite backend.
My test is going to be skipped for this vendor.
@matthiask matthiask merged commit a2ed32c into django-commons:master Sep 19, 2018
@matthiask
Copy link
Member

Thank you!

@todorvelichkov todorvelichkov deleted the fix-rawqueryset branch September 20, 2018 04:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants