我的程序在执行 SQL 插入时总是遇到一个奇怪的问题。我定期(每天一次)在单个 INSERT 语句中使用 pymysql 发送大量数据,每隔几天我就会收到以下错误:
(sqlalchemy.exc.InvalidRequestError) 绑定(bind)参数“D”需要一个值 [SQL:
在我的代码中,这是数据库连接和插入完成的方式:
session 创建:
engine = sqlalchemy.create_engine(db_host, echo = False)
self.metadata = sqlalchemy.MetaData(engine)
DB_session = sqlalchemy.orm.sessionmaker(bind = engine)
session = DB_session()
插入函数:
def insert(self,sql):
complete = False
try:
self.session.execute(sql)
self.session.commit()
complete = True
except Exception as e:
# Do some logging
finally:
return complete
这是典型的插入语句的样子:
INSERT INTO my_db.my_table (field_1, field_2, field_3, ... field_32)
VALUES(data_set1),(data_set2),(data_set3)...(data_set500)
ON DUPLICATE KEY UPDATE
field_1=VALUES(field_1), field_2=VALUES(field_2), field_3=VALUES(field_3) ... field_32=VALUES(field_32)
我查过这个问题,通常它似乎发生在用户显式设置绑定(bind)参数并且缺少一个参数时,但我不明白为什么我的代码会发生这种情况,而我没有设置任何参数,而且我没有字段名称“D”或者知道“D”指的是什么。此外,让事情变得更加困惑的是,当我将完全相同的语句插入 MySQL Workbench 时,它执行时没有任何问题。
我认为问题可能源于尝试同时发送过多数据,因为我正在尝试更新/插入大量数据,每个数据都有很多字段。但如果是这样的话,多少数据就太多了,因为我不想将其分成 500 多个单独的插入内容?
最佳答案
你应该使用 textual-sql sqlalchemy 用于发送纯 sql 查询的功能,但请注意,sqlalchemy 假定您的查询已清理。
尝试使用 text 简单地转换您的查询:
from sqlalchemy.sql import text
session = ...
session.execute(text(sql))
注意它默认使用 autocommit=True,如果你想关闭它,检查 this doc
否则在sqlalchemy中还有2种其他方式来处理绑定(bind)参数:
如果您已经有了 sqlalchemy 的
Table
和Column
对象,首选方式和最面向对象的方式是使用Bind Parameter Objects
或者,您可以使用手动格式化的普通查询并提供带有绑定(bind)参数的字典,假设我有一个包含 2 列
id
的表test
&名称
。这是最安全的,因为它将依赖 sqlalchemy 来清理参数:
from sqlalchemy.sql import text
session = ...
insert_qry = """
INSERT INTO test (id, name) VALUES(:id1, :name1), (:id2, :name2)
ON DUPLICATE KEY UPDATE id=VALUES(id), name=VALUES(name)
"""
params = {'id1':1, 'name1': 'John', 'id2':2, 'name2': 'Bill'}
session.execute(text(insert_qry), params)
关于python - 插入缺少绑定(bind)参数的 sqlalchemy 错误,但在 Workbench 中有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57102045/