SQLAlchemy 1.x
你可以这样做:
my_id = 3
result = engine.execute("DELETE FROM my_table WHERE id = %s", my_id)
或
result = engine.execute("DELETE FROM my_table WHERE id = %(id)s", {'id': my_id})
在这两个语句中,您都假设底层数据库连接库(例如 psycopg2 或 pg8000)正在使用 %-formatting 来绑定查询参数。为了避免这种依赖,您可以使用sqlalchemy.text 来构建查询字符串:
import sqlalchemy as sa
result = engine.execute(sa.text("DELETE FROM my_table WHERE id = :id"), id=my_id)
让 sqlalchemy 构建查询并处理参数绑定和引用。
你应该不使用普通的python字符串格式化函数来绑定查询参数:
engine.execute("DELETE FROM my_table WHERE id = %s" % my_id)
engine.execute("DELETE FROM my_table WHERE id = {}".format(my_id))
engine.execute(f"DELETE FROM my_table WHERE id = {my_id}")
使用这些方法可能会使您的应用程序遭受 SQL 注入攻击,因为查询参数可能没有被正确引用。
风格要点:不能使用del 作为变量名。 Python 已经有了del statement,尝试重新分配名称del 会导致SyntaxError。此外,DELETE 语句返回的 ResultProxy 对象不包含任何行,因此将结果分配给变量没有什么意义。
SQLAlchemy 2.0
在 SQLAlchemy 2.0(仍在开发中)或在引擎的 future 标志设置为 True 的 SQLAlchemy 1.4 中,无法再直接执行原始 SQL 字符串*,也不能使用隐式连接如engine.execute。
原始 SQL 语句必须由 sqlalchemy.text 包装,参数作为字典传递,因此代码如下所示:
with engine.begin() as conn:
conn.execute(sa.text('DELETE FROM my_table WHERE id = :id'), {'id': my_id})
面向对象的风格
不管你使用的是什么版本,你都可以操作Table对象来删除行
# Reflect an existing table from the database.
tbl = sa.Table('my_table', sa.MetaData(), autoload_with=engine)
with engine.begin() as conn:
conn.execute(tbl.delete().where(tbl.c.id == my_id))
conn.execute(sa.delete(tbl).where(tbl.c.id == my_other_id))
* 如果你真的必须的话,你仍然可以使用Connection.exec_driver_sql 执行原始 SQL。