简体   繁体   中英

Django sqlite3 OperationalError near "WHERE": syntax error

I am trying to query an sqlite database with custom sql in django and when I run the query I get

OperationalError at /production/Libre-Badge-Demo-Template/
near "WHERE": syntax error

I have heard talk of django's sqlite engine being unable to insert multiple parameters but I'm not sure what to make of that.

here is the query after all of the variables have been inserted

('SELECT EmployeeID, FirstName, LastName, AccessLevel FROM cardholders WHERE '
 'EmployeeID LIKE %s WHERE FirstName LIKE %s WHERE LastName LIKE %s WHERE '
 'AccessLevel LIKE %s ')

and here are the parameters that get escaped by django and inserted where the %s are

['F1150101', 'Micah', 'Guttman', 'Red']

here is the traceback

Environment:


Request Method: POST
Request URL: http://localhost:8000/production/Libre-Badge-Demo-Template/

Django Version: 3.0.5
Python Version: 3.8.2
Installed Applications:
['LibreBadge',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 396, in execute
    return Database.Cursor.execute(self, query, params)

The above exception (near "WHERE": syntax error) was the direct cause of the following exception:
  File "/home/micah/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/micah/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/micah/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/micah/.local/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/micah/Documents/GitHub/LibreBadge/mysite/LibreBadge/views/views.py", line 25, in production
    rows = formQuery('cardholders', columns, 'cardholders', values)
  File "/home/micah/Documents/GitHub/LibreBadge/mysite/LibreBadge/views/databaseFunctions.py", line 37, in formQuery
    cursor.execute(qry,values)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/home/micah/.local/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 396, in execute
    return Database.Cursor.execute(self, query, params)

Exception Type: OperationalError at /production/Libre-Badge-Demo-Template/
Exception Value: near "WHERE": syntax error

The code for the view is

@login_required
def production(request, slug):
    try:
        BadgeTemplateInstance = BadgeTemplate.objects.get(slug=slug)
        BadgeTemplateConfigFile = json.loads(BadgeTemplateInstance.configFile.read())
    except:
       BadgeTemplateConfigFile = None
    if request.method == 'POST':
        columns = list()
        values = list()
        for BadgeTemplateFormConfig in BadgeTemplateConfigFile['FormFields']:
            postData = request.POST.get(BadgeTemplateFormConfig['id'])
            columns.append(BadgeTemplateFormConfig['DatabaseColumn'])
            values.append(postData)
        rows = formQuery('cardholders', columns, 'cardholders', values)
        return render(request, 'LibreBadge/production.html',
        context = {"BadgeTemplate":BadgeTemplate.objects.all,"AlertMessage":AlertMessage.objects.all,"slug":slug,"BadgeTemplateConfigFile":BadgeTemplateConfigFile,"rows":rows})
    else:
        return render(request, 'LibreBadge/production.html',
        context = {"BadgeTemplate":BadgeTemplate.objects.all,"AlertMessage":AlertMessage.objects.all,"slug":slug,"BadgeTemplateConfigFile":BadgeTemplateConfigFile})

And the code that runs the sql query

def namedtuplefetchall(cursor):
    "Return all rows from a cursor as a namedtuple"
    desc = cursor.description
    nt_result = namedtuple('Result', [col[0] for col in desc])
    return [nt_result(*row) for row in cursor.fetchall()]

def formQuery(db, columns, table, values):
    columnsComma = ', '.join(columns)
    #columns and values dict to comma seperated values
    #for loop for every key/value pair in values append AND + field + like %s%% and append values to value variable in cursor execute
    with connections[db].cursor() as cursor:
                qry = "SELECT "+ columnsComma + " FROM " + table + " "
                i=0
                for x in columns:
                    if i<1:
                        qry = qry + "WHERE " + x + " LIKE %s "
                        i + 1
                    else:
                        qry = qry + "AND " + x + " LIKE %s "
                cursor.execute(qry,values)
                return namedtuplefetchall(cursor)
                cursor.close()

The problem is that you did not increment i , you only wrote i + 1 , so it evaluates i + 1 , and then "throws away" the result. You can fix this by incrementing i with i += 1 :

i = 0
for x in columns:
    if i < 1:
        qry = qry + "WHERE " + x + " LIKE %s "
          # increment i
    else:
        qry = qry + "AND " + x + " LIKE %s "

or more Pythonic:

for i, x in columns:
    if not i:
        qry += "WHERE " + x + " LIKE %s "
    else:
        qry += "AND " + x + " LIKE %s "

But please do not write SQL queries yourself. The Django ORM is designed to make querying elegant, user-friendly, and often more secure, for example by trying to ensure sql injection [wiki] is not possible. See the documentation for an introduction on how to write Django queries effectively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM