我有一本包含键和值的字典,如:

my_dict = {'a':33, 'b': 'something', 'c': GETDATE(), 'd': 55}

假设SQL表中的列名也像dict的键一样命名,即"a、b、c、d".

实际字典是20多个键:值对.

密码

我用pyodbc.connect创建了一个cursor,可以用它执行SQL INSERT语句:

for k in my_dict.keys():
    cursor.execute(
    '''
        INSERT INTO TABLEabc (%s)
        VALUES (%s)
    '''
    % (k, my_dict[k])
    )

但这似乎效率很低,因为每次都是一个新的SQL操作.

  1. 使用循环插入值的最简单方法是什么?
  2. 我如何编写它,使它只插入一个值?

推荐答案

如果您使用的是pyodbc,那么这可能会起作用:

columns = {row.column_name for row in cursor.columns(table='TABLEabc')}

safe_dict = {key: val for key, val in my_dict.items() if key in columns}

# generate a parameterised query for the keys in our dict
query = "INSERT INTO TABLEabc ({columns}) VALUES ({value_placeholders})".format(
    columns=", ".join(safe_dict.keys()),
    value_placeholders=", ".join(["?"] * len(safe_dict)),
)

cursor.execute(query, list(safe_dict.values()))

它旨在避免SQL注入,因为:

  • 我们只过滤数据库中实际列名的键
  • 我们使用pyodbc cursor execute参数,因此值将被正确转义

可能不起作用的地方:

  • 如果需要引用和转义任何列名,这不会自动发生,因此将失败

引用/转义是特定于db的,因此我们必须判断实际db的规则,并将其应用于格式化到查询中的dict键.(或者找到某种方法让pyodbc为我们做到这一点,如果可能的话不确定)

如果您相信您的my_dict不会包含恶意代码,那么您可以简化为:

query = "INSERT INTO TABLEabc ({columns}) VALUES ({value_placeholders})".format(
    columns=", ".join(my_dict.keys()),
    value_placeholders=", ".join(["?"] * len(my_dict)),
)

cursor.execute(query, list(my_dict.values()))

Python相关问答推荐

try 与gemini-pro进行多轮聊天时出错

删除最后一个pip安装的包

在Wayland上使用setCellWidget时,try 编辑QTable Widget中的单元格时,PyQt 6崩溃

log 1 p numpy的意外行为

使用setuptools pyproject.toml和自定义目录树构建PyPi包

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

Asyncio:如何从子进程中读取stdout?

如何并行化/加速并行numba代码?

如何更改groupby作用域以找到满足掩码条件的第一个值?

如何在PySide/Qt QColumbnView中删除列

如何使用两个关键函数来排序一个多索引框架?

Python—转换日期:价目表到新行

提高算法效率的策略?

Odoo16:模板中使用的docs变量在哪里定义?

mdates定位器在图表中显示不存在的时间间隔

PYTHON中的pd.wide_to_long比较慢

Django抛出重复的键值违反唯一约束错误

按列表分组到新列中

如何使用Polars从AWS S3读取镶木地板文件

GEKKO中若干参数的线性插值动态优化