python mysql 连接器出现位置错误

Getting a positional error with python mysql connector

在尝试填充数据库时,Python mysql 连接器出现数百个位置错误。我认为这是因为我无法转义部分或全部特殊字符。有没有办法转义导致此问题的所有特殊字符或; ...我是否应该继续将每个字符串中的特殊字符替换为其他中性字符并创建一个字典以在我从数据库中提取数据时将句子重组回原始内容?

for thing in every_thing:
    line_= thing.split("|", 3)
    book_name = line_[0]
    chap_number = line_[1]
    verse_num = line_[2]
    verse= line_[3]
#Test
    statement = "INSERT INTO " + new_dict[line_[0]]
    statement += " ( " 
    chapters = book_key_chapt[line_[0]]
    h = 1
    fields = ""
    while h <= chapters:
        fields += "Chapter_" + str(h)
        h += 1
        if h != chapters + 1:
            fields += ","
        else:
            fields += " )"
    statement += fields
# Value creation
    values = " VALUES ( "
    a = 1
    while a <= chapters:
        if a == int(chap_number):
            values += "'" + verse_num +  verse.replace('~'," ") + "'"
        else:
            values += "'NA'"
        a += 1
        if a != chapters + 1:
            values += "," 
    values += " )"
    statement += values
    try:
        cur.execute(*statement)
        print(cur)
    except Exception as er:
        print(er) 

这里:

cur.execute(*statement)

“*”表示"unpack before passing"。它通常应用于列表或元组,但适用于任何可迭代对象 - 字符串 are 可迭代对象。所以基本上,你在这里做的是:

cur.execute(statemement[0], statement[1], statement[2], # etc)

所以我们知道您的 statement 字符串长度为 844 个字符 ;-)

解决办法当然是去掉“*”。

话虽这么说,你的代码是totally unsafe, and even if no one uses this breach to attack you, it's still very brittle (properly escaping strings is not that simple). The proper way to use the db-api is to use placeholders in the SQL query and pass the values as arguments

请注意,这仅适用于 ,不适用于 table 和字段名称,因此您仍然必须以编程方式构建 SQL 查询,但是您可以通过使用字符串格式化操作以及使用 str.join(seq) 构建字段列表和占位符列表来让您的生活更轻松(并且您的代码更快),即:

statement = "INSERT INTO {table_name} ({fields}) VALUES ({placeholders})"

# NB: you may want to read about the stdlib's `csv` package...
book_name, chap_number, verse_num, verse = thing.split("|", 3)

table_name = new_dict[book_name]
nb_chapters = book_key_chapt[book_name]

fields = ["Chapter_{}".format(i) for i in range(1, nb_chapters + 1)]
placeholders = ["?"] * nb_chapters

values = [#XXX I let you rewrite your code here using a list comprehension as above]

sql = statement.format(
    table_name=table_name, 
    fields=", ".join(fields), 
    placeholders=", ".join(placeholders)
    )

cur.execute(sql, values)

最后(但很重要!)请注意:看起来每个书名都有一个不同的 table,每个书名的字段数与章节?如果是,那是一个完全错误的设计。如果重点是为一本书+章节建模,你想要一个单一的 table 用于书籍(每本书一条记录),以及一个相关的 "chapters" table 与 [=42 上的外键=] table(每章一条记录)。