【问题标题】:sqlalchemy dynamic use of and_ in where clausesqlalchemy在where子句中动态使用and_
【发布时间】:2020-11-18 03:34:22
【问题描述】:

我正在尝试使用 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 执行这样的删除查询。

【问题讨论】:

    标签: python sql pandas sqlalchemy


    【解决方案1】:

    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)
    """
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      • 2019-10-12
      • 2016-12-28
      • 1970-01-01
      相关资源
      最近更新 更多