简体   繁体   English

Django “WHERE”附近的 sqlite3 OperationalError:语法错误

[英]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我正在尝试使用 django 中的自定义 sql 查询 sqlite 数据库,当我运行查询时,我得到

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.我听说过 django 的 sqlite 引擎无法插入多个参数,但我不确定该怎么做。

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这是由 django 转义并插入 %s 的参数

['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以及运行 sql 查询的代码

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.问题是你没有增加i ,你只写了i + 1 ,所以它评估i + 1 ,然后“丢弃”结果。 You can fix this by incrementing i with i += 1 :您可以通过使用i += 1递增i来解决此问题:

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

or more Pythonic:或更多 Pythonic:

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

But please do not write SQL queries yourself.但请不要自己编写 SQL 查询。 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. Django ORM 旨在使查询变得优雅、用户友好并且通常更安全,例如通过尝试确保sql 注入[wiki]是不可能的。 See the documentation for an introduction on how to write Django queries effectively.有关如何有效编写 Django 查询的介绍,请参阅文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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