Python使用SqlAlchemy更新SQL表报FROM expression expected错误如何解决
问题原因
你调用update()方法时传入的第一个参数bookdetails是你定义的图书录入函数名,不是SQLAlchemy可识别的表对象,因此触发了ArgumentError: FROM expression expected错误。
修复方案
提供两种可选修复方式,按需选择即可:
方案1:直接执行原生SQL(改动最小)
如果你更熟悉原生SQL语法,可以直接执行UPDATE语句,同时用参数化查询避免SQL注入风险,修改issuebooks函数代码如下:
def issuebooks(): print("issue the books") issue_book = input("which book to issue:") # 参数化查询库存,避免SQL注入 frame = pd.read_sql("select Quantities from bookdetails where BookName = ?", connection, params=(issue_book,)) if frame.empty: print("未查询到指定图书") return current_qty = int(frame.iloc[0,0]) if current_qty <= 0: print("当前图书库存不足,无法借出") return # 执行更新操作 connection.execute("UPDATE bookdetails SET Quantities = Quantities - 1 WHERE BookName = ?", (issue_book,)) # 提交事务,否则修改不会持久化到数据库 connection.commit() print(f"图书《{issue_book}》借出成功,剩余库存:{current_qty-1}")
方案2:反射表对象使用SQLAlchemy原生update语法
如果你需要沿用SQLAlchemy的ORM语法操作,需要先反射得到数据库中的表对象再传入update方法:
- 首先在创建engine、connection的代码后新增表反射逻辑:
from sqlalchemy import MetaData, Table # 反射获取数据库中的表对象 metadata = MetaData() book_table = Table(table_name, metadata, autoload_with=engine)
- 修改
issuebooks函数的更新逻辑:
def issuebooks(): print("issue the books") issue_book = input("which book to issue:") frame = pd.read_sql("select Quantities from bookdetails where BookName = ?", connection, params=(issue_book,)) if frame.empty: print("未查询到指定图书") return current_qty = int(frame.iloc[0,0]) if current_qty <= 0: print("当前图书库存不足,无法借出") return # 传入正确的表对象构造update语句 updated_value_query = update(book_table).values(Quantities = current_qty - 1).where(book_table.c.BookName == issue_book) connection.execute(updated_value_query) connection.commit() print(f"图书《{issue_book}》借出成功,剩余库存:{current_qty-1}")
其他注意事项
- 原代码中直接用字符串拼接SQL语句存在SQL注入风险,统一替换为
?占位符的参数化查询更安全 - SQLAlchemy默认开启事务,执行增删改操作后必须调用
connection.commit()提交,否则修改不会同步到数据库 - 原代码中
int(frame.values)写法错误,pandas的DataFrame的values属性返回二维数组,需要取frame.iloc[0,0]才能拿到库存数值
内容的提问来源于stack exchange,提问作者Chitransh Mathur
相关产品推荐
相关产品推荐

