我正在尝试使用 sqlalchemy 构建删除查询。 delete 子句的 where 部分应该动态构造以满足多个条件。例如:
DELETE FROM table
WHERE table.col1 = x1
AND table.col2 = x2
AND ...
以下是我的代码的简化部分。
def upsert(key_col):
...
# Build the WHERE clause of your DELETE statement from rows in the dataframe.
cond = df.apply(lambda row: sa.and_(detail_table.c[key_col] == row[key_col]), axis=1)
cond = sa.or_(*cond)
# Define and execute the DELETE
delete = detail_table.delete().where(cond)
with engine.connect() as conn:
conn.execute(delete)
...
这适用于从具有单个主键列的表中删除行。我希望能够将 key_col
作为具有复合主键的表的列表传递。
我可以做类似的事情
cond = df.apply(lambda row: sa.and_(detail_table.c[key_col[0]] == row[key_col[0]],
detail_table.c[key_col[1]] == row[key_col[1]],
detail_table.c[key_col[2]] == row[key_col[2]]),
axis=1)
但我希望能够在运行时根据 key_col
的大小动态创建上述内容。我猜有更好的方法可以使用 sqlalchemy 执行此类删除查询。
最佳答案
SQLAlchemy 将接受多个 .where
结构并将它们与在一起,例如,
import sqlalchemy as sa
engine = sa.create_engine("mssql+pyodbc://@mssqlLocal64", echo=True)
detail_table = sa.Table(
"#detail_table",
sa.MetaData(),
sa.Column("col1", sa.Integer),
sa.Column("col2", sa.Integer),
)
detail_table.create(bind=engine)
# test data
criteria = [(detail_table.c.col1, 3), (detail_table.c.col2, 5)]
del_stmt = detail_table.delete()
for crit in criteria:
col, val = crit
del_stmt = del_stmt.where(col == val)
with engine.begin() as conn:
conn.execute(del_stmt)
"""console output:
sqlalchemy.engine.base.Engine DELETE FROM [#detail_table] WHERE [#detail_table].col1 = ? AND [#detail_table].col2 = ?
sqlalchemy.engine.base.Engine (3, 5)
"""
关于python - sqlalchemy在where子句中动态使用and_,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63138442/