django-commons / django-commons/django-debug-toolbar

"TypeError: not enough arguments for format string" on executemany() INSERT in sqlite3

Open
#1,069 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
Dominant language
Python
Stars
8.4k
Forks
1.1k
Avg merge
1d 5h
Merged PRs (30d)
13

Description

Hi Folks. Thanks very much for your work. I'm getting an error on django 1.11 and django-debug-toolbar 1.9.1. I get no errors with postgres on the back end, but sqlite3 gets:

Internal Server Error: /forecast/34/upload/286
Traceback (most recent call last):
  File "/Users/cornell/.local/share/virtualenvs/forecast-repository-aIKRoinE/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
  File "/Users/cornell/.local/share/virtualenvs/forecast-repository-aIKRoinE/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
  File "/Users/cornell/.local/share/virtualenvs/forecast-repository-aIKRoinE/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/cornell/IdeaProjects/forecast-repository/forecast_app/views.py", line 904, in upload_forecast
forecast_model.load_forecast(Path(tmp_data_file), time_zero, file_name)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/contextlib.py", line 53, in inner
return func(*args, **kwds)
  File "/Users/cornell/IdeaProjects/forecast-repository/forecast_app/models/forecast_model.py", line 85, in load_forecast
new_forecast.load_csv_data(csv_file_path)
  File "/Users/cornell/IdeaProjects/forecast-repository/forecast_app/models/data.py", line 48, in load_csv_data
cursor.executemany(sql, rows)
  File "/Users/cornell/.local/share/virtualenvs/forecast-repository-aIKRoinE/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py", line 167, in executemany
return self._record(self.cursor.executemany, sql, param_list)
  File "/Users/cornell/.local/share/virtualenvs/forecast-repository-aIKRoinE/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py", line 130, in _record
self.cursor, sql, self._quote_params(params)),
  File "/Users/cornell/.local/share/virtualenvs/forecast-repository-aIKRoinE/lib/python3.6/site-packages/django/db/backends/sqlite3/operations.py", line 142, in last_executed_query
return sql % params
TypeError: not enough arguments for format string

Here's is the minimal view function that recreates the problem:

def load_csv_data(self, cdc_csv_file):
    with connection.cursor() as cursor:
        rows = [('US National', 34, 'point', 'week', None, None, 50, 4421)]
        sql = """
            INSERT INTO forecast_app_forecastdata (location, target_id, row_type, unit, bin_start_incl, bin_end_notincl, value, forecast_id)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s);
        """
        cursor.executemany(sql, rows)

The error is in: https://github.com/jazzband/django-debug-toolbar/blob/ac52b23f9a05cafe0f7124a1f9d7b8236a3027d5/debug_toolbar/panels/sql/tracking.py#L132

The variables at that point are, via print(self.cursor, repr(sql), repr(params), repr(self._quote_params(params))):

<django.db.backends.utils.CursorDebugWrapper object at 0x107e6fa90>

 '\n                INSERT INTO forecast_app_forecastdata (location, target_id, row_type, unit, bin_start_incl, bin_end_notincl, value, forecast_id)\n                VALUES (%s, %s, %s, %s, %s, %s, %s, %s);\n            '

[('US National', 34, 'point', 'week', None, None, 50, 4421)]

["('US National', 34, 'point', 'week', None, None, 50, 4421)"]

Finally, the failing last_executed_query() line in django/db/backends/sqlite3/operations.py is:

return sql % params

The variables at that point are, via print(repr(sql), repr(params)):

'\n                INSERT INTO forecast_app_forecastdata (location, target_id, row_type, unit, bin_start_incl, bin_end_notincl, value, forecast_id)\n                VALUES (%s, %s, %s, %s, %s, %s, %s, %s);\n            '

("'(''US National'', 34, ''point'', ''week'', None, None, 50, 4421)'",)

Sure enough, that fails.

Is there anything else I can share about this? In the meantime I've updated my django settings to disable the toolbar for sqlite3. Thank you.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with debug_toolbar/panels/sql/tracking.py around _record() and executemany(), then inspect django/db/backends/sqlite3/operations.py at last_executed_query(). Reproduce the supplied INSERT with executemany() under SQLite and verify that the SQL panel records it without raising the formatting error.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python, sqlite
Domain
databases, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.