【问题标题】:Django sqlite3 custom sql operational error when passing more than one parameterdjango sqlite3自定义sql操作传递多个参数时报错
【发布时间】:2020-08-15 13:53:09
【问题描述】:

我试图在 django 中对 sqlite3 数据库运行自定义 sql 查询,当我尝试将多个参数传递到我的 sql 语句时出现操作错误。我不知道为什么,我尝试使用 cursor.fetchall() 而不是 namedtuplefetchall 但这没有用。我的数据库被命名为 cardholders.sqlite3,我有一个表也命名了我试图从中提取数据的持卡人。

下面是相关代码

from django.db import connections
from collections import namedtuple
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()]

然后是介于两者之间的一些视图

@login_required
def databaseTest(request):
    if request.method == 'POST':
        postid = request.POST.get("id")
        with connections['cardholders'].cursor() as cursor:
            cursor.execute("SELECT * FROM %s WHERE ID = %s",['cardholders',postid])
            row = namedtuplefetchall(cursor)
            cursor.close()
        return render(request, 'LibreBadge/databaseTest.html',
        context = {"AlertMessage":AlertMessage.objects.all, "row":row})
        row = "none"
    else:
        return render(request, 'LibreBadge/databaseTest.html',
        context = {"AlertMessage":AlertMessage.objects.all})

和追溯

Environment:


Request Method: POST
Request URL: http://localhost:8000/databaseTest/

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 "?": 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 27, in databaseTest
    cursor.execute("SELECT * FROM %s WHERE ID = %s",['cardholders',postid])
  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 /databaseTest/
Exception Value: near "?": syntax error

【问题讨论】:

    标签: python django sqlite


    【解决方案1】:

    感谢mechanical_meat帮助我这是我根据你的回答写的代码

    from django.db import connections
    from collections import namedtuple
    
    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 select(db, table, field, value):
        with connections['cardholders'].cursor() as cursor:
                    qry = "SELECT * FROM " + table + " WHERE " + field + " = " + value
                    cursor.execute(qry,[])
                    return namedtuplefetchall(cursor)
                    cursor.close()
    

    【讨论】:

      【解决方案2】:

      改为:

                  qry = "SELECT * FROM {} WHERE ID = ?".format('cardholders')
                  cursor.execute(qry,(postid,))
      

      查询参数化不适用于表名,因此需要对查询字符串进行两个单独的操作。

      with 语句也将关闭 cursor 本身,因此您不需要此行:

                  cursor.close()
      

      【讨论】:

      • 做 qry = "SELECT * FROM" + table + " WHERE" + field + " =" +value 会是个坏主意吗?将所有表字段和值作为变量
      • 非常感谢,这让我发疯了
      • 这里有没有好办法通过转义变量来防止sql注入?
      • 我建议创建一个表名白名单,并检查该列表中的成员资格。
      • 哦,对于它们应该用数据库模块的工具替换的值;在这种情况下,? 就像我的回答中所示。
      猜你喜欢
      • 2021-09-04
      • 1970-01-01
      • 2020-02-13
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多