【问题标题】:Python - sqlite3 sqlite3.OperationalError: near “%”: syntax error?Python - sqlite3 sqlite3.OperationalError:“%”附近:语法错误?
【发布时间】:2017-05-17 21:15:53
【问题描述】:

首先,在一切之前,我意识到这个问题已经被事先问过了。我已经寻找了几个小时试图解决我的问题,但我无法正确实施解决方案,我仍然遇到错误。

我正在尝试使用变量字符串将表名插入到表中(希望表名是动态的,但我相信这也是不允许的?)。从我所做的研究来看,这似乎是不允许的/良好的做法,因为它使代码对 SQL 注入开放。

我尝试将 %s 替换为 ?但它仍然返回与“?”相同的错误而不是“%?”

这是我正在使用的代码。其中大部分归功于 James Mills,我只是想将他从 CSV 中所做的语句用于 sqlite3 INSERT 语句,如果这有意义的话。

"""csv2sql

Tool to convert CSV data files into SQL statements that
can be used to populate SQL tables. Each line of text in
the file is read, parsed and converted to SQL and output
to stdout (which can be piped).

A table to populate is given by the -t/--table option or
by the basename of the input file (if not standard input).

Fields are either given by the -f/--fields option (comma
separated) or determinted from the first row of data.
"""

__version__ = "0.4"
__author__ = "James Mills"
__date__ = "3rd February 2011"

import os
import csv
import sys
import optparse
import sqlite3

USAGE = "%prog [options] <file>"
VERSION = "%prog v" + __version__

def parse_options():
    parser = optparse.OptionParser(usage=USAGE, version=VERSION)

    parser.add_option("-t", "--table",
            action="store", type="string",
            default=None, dest="table",
            help="Specify table name (defaults to filename)")

    parser.add_option("-f", "--fields",
            action="store", type="string",
            default=None, dest="fields",
            help="Specify a list of fields (comma-separated)")

    parser.add_option("-s", "--skip",
            action="append", type="int",
            default=[], dest="skip",
            help="Specify records to skip (multiple allowed)")

    opts, args = parser.parse_args()

    if len(args) < 1:
        parser.print_help()
        raise SystemExit, 1

    return opts, args

def generate_rows(f):
    sniffer = csv.Sniffer()
    dialect = sniffer.sniff(f.readline())
    f.seek(0)

    reader = csv.reader(f, dialect)
    for line in reader:
        yield line

def main():
    opts, args = parse_options()

    filename = args[0]

    if filename == "-":
        if opts.table is None:
            print "ERROR: No table specified and stdin used."
            raise SystemExit, 1
        fd = sys.stdin
        table = opts.table
    else:
        fd = open(filename, "rU")
        if opts.table is None:
            table = os.path.splitext(filename)[0]
        else:
            table = opts.table

    rows = generate_rows(fd)

    if opts.fields:
        fields = ", ".join([x.strip() for x in opts.fields.split(",")])
    else:
        fields = ", ".join(rows.next())

    for i, row in enumerate(rows):
        if i in opts.skip:
            continue

        values = ", ".join(["\"%s\"" % x for x in row])
        print "INSERT INTO %s (%s) VALUES (%s);" % (table, fields, values)

        con = sqlite3.connect("school")
        cur = con.cursor()

        cur.executemany("INSERT INTO %s (%s) VALUES (%s);", (table, fields, values))
        con.commit()
        con.close()

if __name__ == "__main__":
    main()

这是一个输出示例:

> INSERT INTO data (School Name, Summer 15, Summer 16, Summer 17) VALUES ("School One", "126", "235", "453");
Traceback (most recent call last):
  File "sniffer.py", line 103, in <module>
    main()
  File "sniffer.py", line 98, in main
    cur.executemany("INSERT INTO %s (%s) VALUES (%s);", (table, fields, values))
sqlite3.OperationalError: near "%": syntax error

嗅探器的东西是获取列的名称及其值,我尝试将它们放入 SQL 语句中。

我尝试了很多方法,但始终无法找到解决方案!

请不要打我!我是新手,只需要一点帮助!

感谢任何帮助!

【问题讨论】:

标签: python sqlite


【解决方案1】:

记住SQL-Injection Attack 的可能性并确保清理您的输入,您可以像这样准备查询:

if opts.fields:
    fields = ", ".join([x.strip() for x in opts.fields.split(",")])
else:
    fields = ", ".join(rows.next())

qry = "INSERT INTO %s (%s) VALUES (%s);" % (table,
                                            fields,
                                            ",".join("?"*len(rows)),)

请注意,对于 SQLite 中的参数替换,您需要使用 ?s。

cur.executemany(qry, (rows,))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    相关资源
    最近更新 更多