我正在尝试使用dict
来执行SQL INSERT
。逻辑基本上是:
INSERT INTO table (dict.keys()) VALUES dict.values()
但是,我很难确定正确的语法/流程来执行此操作。这就是我目前所拥有的:
# data = {...}
sorted_column_headers_list = []
sorted_column_values_list = []
for k, v in data.items():
sorted_column_headers_list.append(k)
sorted_column_values_list.append(v)
sorted_column_headers_string = ', '.join(sorted_column_headers_list)
sorted_column_values_string = ', '.join(sorted_column_values_list)
cursor.execute("""INSERT INTO title (%s)
VALUES (%s)""",
(sorted_column_headers_string, sorted_column_values_string))
从这里我得到一个SQL异常(我认为与逗号也包含在我拥有的一些值中这一事实相关)。做上述事情的正确方法是什么?
答案 0 :(得分:55)
我认为使用MySQL的评论并不完全。 MySQLdb不在列中进行参数替换,只是值(IIUC) - 所以可能更像是
placeholders = ', '.join(['%s'] * len(myDict))
columns = ', '.join(myDict.keys())
sql = "INSERT INTO %s ( %s ) VALUES ( %s )" % (table, columns, placeholders)
cursor.execute(sql, myDict.values())
你没有在列上逃脱,所以你可能想先检查一下......
有关更完整的解决方案,请参阅http://mail.python.org/pipermail/tutor/2010-December/080701.html
答案 1 :(得分:19)
您想要为查询添加参数占位符。这可能会得到你所需要的:
qmarks = ', '.join('?' * len(myDict))
qry = "Insert Into Table (%s) Values (%s)" % (qmarks, qmarks)
cursor.execute(qry, myDict.keys() + myDict.values())
答案 2 :(得分:15)
这里总是很好的答案,但在Python 3中,你应该写下以下内容:
placeholder = ", ".join(["%s"] * len(dict))
stmt = "insert into `{table}` ({columns}) values ({values});".format(table=table_name, columns=",".join(dict.keys()), values=placeholder)
cur.execute(stmt, list(dict.values()))
不要忘记将dict.values()
转换为列表,因为在Python 3中,dict.values()
会返回一个视图,而不是列表。
此外, NOT 将dict.values()
倒入stmt
,因为它会通过join
将字符串中的引号撕掉,从而导致MySQL错误插入它。所以你应该总是动态地将它放在cur.execute()
中。
答案 3 :(得分:2)
table='mytable'
columns_string= '('+','.join(myDict.keys())+')'
values_string = '('+','.join(map(str,myDict.values()))+')'
sql = """INSERT INTO %s %s
VALUES %s"""%(table, columns_string,values_string)
答案 4 :(得分:2)
我尝试了@ furicle的解决方案,但它仍然将所有内容输入为字符串 - 如果你的dict是混合的,那么这可能不会像你想要的那样工作。我遇到了类似的问题,这就是我提出的问题 - 这只是一个查询构建器,您可以使用它(带有更改)来处理您选择的任何数据库。看看吧!
def ins_query_maker(tablename, rowdict):
keys = tuple(rowdict)
dictsize = len(rowdict)
sql = ''
for i in range(dictsize) :
if(type(rowdict[keys[i]]).__name__ == 'str'):
sql += '\'' + str(rowdict[keys[i]]) + '\''
else:
sql += str(rowdict[keys[i]])
if(i< dictsize-1):
sql += ', '
query = "insert into " + str(tablename) + " " + str(keys) + " values (" + sql + ")"
print(query) # for demo purposes we do this
return(query) #in real code we do this
这很粗糙,仍然需要进行健全性检查等,但它按预期工作。 对于一个词典:
tab = {'idnumber': 1, 'fname': 'some', 'lname': 'dude', 'dob': '15/08/1947', 'mobile': 5550000914, 'age' : 70.4}
运行查询我得到以下输出
答案 5 :(得分:2)
此代码对我有用(Python 3):
fields = (str(list(dictionary.keys()))[1:-1])
values = (str(list(dictionary.values()))[1:-1])
sql = 'INSERT INTO Table (' + fields + ') VALUES (' + values + ')'
cursor.execute(sql)
它确实依赖字典以相同顺序输出其键和值。我不清楚这是否总是正确的:)
答案 6 :(得分:1)
我参加聚会有点晚了,但是我倾向于选择另一种方式,因为我的数据通常已经是字典的形式。如果以%(columnName)s的形式列出绑定变量,则可以在执行时使用字典来绑定它们。由于变量按名称绑定,因此部分解决了列排序问题。我说的部分原因是,您仍然必须确保插入的列和值部分正确映射。但字典本身可以按任何顺序排列(因为字典无论如何都是无序的)
也许可以通过更多的Python方式来实现所有这些功能,但是将列名放入列表并进行处理可以确保我们具有静态的顺序来构建column&values子句。
data_dict = {'col1': 'value 1', 'col2': 'value 2', 'col3': 'value 3'}
columns = data_dict.keys()
cols_comma_separated = ', '.join(columns)
binds_comma_separated = ', '.join(['%(' + item + ')s' for item in columns])
sql = f'INSERT INTO yourtable ({cols_comma_separated}) VALUES ({binds_comma_separated})'
cur.execute(sql, data_dict)
现在,像这样动态创建列和值子句是否是个好主意,是SQL注入线程的主题。
答案 7 :(得分:1)
在动态构建查询时,确保正确引用 identifiers 和 values 很重要。否则你就有风险
2021-07-11
未引用可能会被评估为 2003
),则会导致数据损坏或错误引用值最好委托给 DB-API 连接器。但是,连接器包并不总是提供引用标识符的方法,因此您可能需要手动执行此操作。 MySQL 使用反引号 (`) 来引用标识符。
此代码引用标识符和值。它适用于 MySQLdb、mysql.connector 和 pymysql,适用于 Python 3.5+。
data = {'col1': val1, 'col2': val2, ...}
# Compose a string of quoted column names
cols = ','.join([f'`{k}`' for k in data.keys()])
# Compose a string of placeholders for values
vals = ','.join(['%s'] * len(data))
# Create the SQL statement
stmt = f'INSERT INTO `tbl` ({cols}) VALUES ({vals})'
# Execute the statement, delegating the quoting of values to the connector
cur.execute(stmt, tuple(data.values()))
答案 8 :(得分:0)
我将此线程用于自己的用途,并试图使其更简单
ins_qry = "INSERT INTO {tablename} ({columns}) VALUES {values};" .format(
tablename=my_tablename,
columns=', '.join(myDict.keys()),
values=tuple(myDict.values())
)
cursor.execute(ins_qry)
如果需要插入行的主键,请确保使用db_connection.commit()
和cursor.lastrowid
提交插入的数据
答案 9 :(得分:0)
columns =','.join(str(x).replace('/','_')for row_dict.keys())中的x
values =','.join(“'” + str(x).replace('/','_')+“'”对于row_dict.values())中的x
sql =“将%s(%s)值插入(%s); %(“表名”,列,值)
适用于python3
答案 10 :(得分:0)
这对我有用
cursor.execute("INSERT INTO table (col) VALUES ( %(col_value) )",
{'col_value': 123})
答案 11 :(得分:0)
如果您有包含字典数量的列表 例如:lst=[d1,d2,d3,d4]
那么下面一个对我有用:
for i in lst:
placeholders = ', '.join(['%s'] * len(i))
columns = ', '.join(i.keys())
sql = "INSERT INTO %s ( %s ) VALUES ( %s )" % (table, columns, placeholders)
cursor.execute(sql,list(i.values()))
conn.commit()
注意:不要永远不要忘记提交,否则您将无法看到插入到表中的列和值
答案 12 :(得分:-2)
keys = str(dict.keys())
keys.replace('[', '(')
keys.replace(']', ')')
keys.replace("'",'')
vals = str(dict.values())
vals.replace('[', '(')
vals.replace(']', ')')
cur.execute('INSERT INTO table %s VALUES %s' % (keys, vals))
keys = str(dict.keys())[9:].replace('[', '').replace(']', '')
vals = str(dict.values())[11:].replace('[', '').replace(']', '')