0

我正在运行以下代码:

#converts strings that are ints to int.
for i,x in enumerate(values):
    try:
        values[i] = int(x)
    except:
        pass

# Fills values with NULLs if needed
if len(values) < no_of_columns:
    values = values + ["NULL"]*(no_of_columns-len(values))
print(values)

# Creates dict with params and values
params = {}
for i, x in enumerate(values):
    params[i] = x

query = "INSERT INTO {} VALUES ({});".format(table_name,",".join(['%s']*no_of_columns))

self.cur.execute(query, params)
self.print_answer()

会发生什么是我收到以下错误:

Traceback (most recent call last):
  File "interface.py", line 228, in <module>
    db.run()
  File "interface.py", line 219, in run
    actions[self.print_menu()-1]()
  File "interface.py", line 194, in insert
    self.cur.execute(query, params)
  File "build/bdist.macosx-10.6-intel/egg/pgdb.py", line 323, in execute
  File "build/bdist.macosx-10.6-intel/egg/pgdb.py", line 359, in executemany
pg.OperationalError: internal error in 'BEGIN': not enough arguments for format string

这让我很困惑,因为当我打印参数和引用时,我可以看到元素的数量与%s标签的数量完全相同:

params = {0: 22, 1: 'ehj', 2: 'NULL', 3: 'NULL'}
query = 'INSERT INTO books VALUES (%s,%s,%s,%s);'

我究竟做错了什么?参数应该与 %s 的数量相同,对吧?

4

2 回答 2

1

你有两个问题:

  • 您正在使用位置参数,每个参数都%s将匹配第二个参数中的连续值cursor.execute(),此处应该是列表或元组。您想使用values而不是构建params字典。

  • 您不应该将字符串NULL用于空值,请使用None; 字符串将按字面意思插入(所以不是 SQL NULL,而是 *string 值'NULL'),Python 值None代表实际的空值。

    或者,您可以将参数替换NULL为生成INSERT语句中的值(因此生成的 SQL 具有NULL文字而不是参数。

我也不会使用笼统的except:陈述;您正在消除所有错误。抓住ValueError

#converts strings that are ints to int.
for i,x in enumerate(values):
    try:
        values[i] = int(x)
    except ValueError:
        pass

# Fills values with NULLs if needed
values += [None] * (no_of_columns - len(values))
    
query = "INSERT INTO {} VALUES ({});".format(
    table_name, ",".join(['%s'] * no_of_columns))

self.cur.execute(query, values)
于 2015-09-26T21:00:08.843 回答
0

确保你没有转义字符串,如果你只是传递异常,你将改变传递值的顺序。数据库也会进行对话,所以无论如何都不需要int()

#converts strings that are ints to int.
for i,x in enumerate(values):
    try:
        values[i] = int(x)
    except:
        values[i] = x # see note above

另外,这是我对同一问题的解决方案:

def db_insert(conn, cur, table, data):
    sql = ('INSERT INTO %s (' % table) + ', '.join(data.keys()) + ') VALUES(' + ', '.join(['?' for j in data.values()]) +')'

    cur.execute(sql, tuple(data.values()))
    lastid = cur.lastrowid
    conn.commit()

    return lastid

你可以像这样使用它:

conn = sqlite3.connect(DB_PATH)
cur = conn.cursor()

db_insert(conn, cur, 'ig_media', {
   'user_id': uid,
   'media_id': mid,
   'like_date': arrow.now().timestamp
})
于 2015-09-26T19:36:05.143 回答