【问题标题】:Bulk update in SQLAlchemy Core using WHERE使用 WHERE 在 SQLAlchemy Core 中进行批量更新
【发布时间】:2014-10-30 21:36:41
【问题描述】:

我已经设法在 SQLAlchemy 中使用批量插入,例如:

conn.execute(addresses.insert(), [ 
   {'user_id': 1, 'email_address' : 'jack@yahoo.com'},
   {'user_id': 1, 'email_address' : 'jack@msn.com'},
   {'user_id': 2, 'email_address' : 'www@www.org'},
   {'user_id': 2, 'email_address' : 'wendy@aol.com'},
])

我现在需要的是相当于更新的东西。我试过这个:

conn.execute(addresses.insert(), [ 
   {'user_id': 1, 'email_address' : 'jack@yahoo.com', 'id':12},
   {'user_id': 1, 'email_address' : 'jack@msn.com', 'id':13},
   {'user_id': 2, 'email_address' : 'www@www.org', 'id':14},
   {'user_id': 2, 'email_address' : 'wendy@aol.com', 'id':15},
])

期望每一行都根据'id'字段得到更新,但它不起作用。我假设是因为我没有指定 WHERE 子句,但我不知道如何使用字典中包含的数据指定 WHERE 子句。

有人可以帮帮我吗?

【问题讨论】:

    标签: python orm sqlalchemy


    【解决方案1】:

    @Jongbin Park 的解决方案使用复合主键对我有用。 (Azure SQL Server)。

    update_vals = []
    update_vals.append(dict(Name='name_a', StartDate='2020-05-26 20:17:32', EndDate='2020-05-26 20:46:03', Comment='TEST COMMENT 1'))
    update_vals.append(dict(Name='name_b', StartDate='2020-05-26 21:31:16', EndDate='2020-05-26 21:38:37', Comment='TEST COMMENT 2'))
    s.bulk_update_mappings(MyTable, update_vals)
    s.commit()
    

    其中 Name、StartDate 和 EndDate 都是复合 pk 的一部分。 'Comment' 是要在数据库中更新的值

    【讨论】:

      【解决方案2】:

      会话具有称为bulk_insert_mappingsbulk_update_mappings 的函数:documentation

      请注意,您必须在映射中提供主键

      # List of dictionary including primary key
      user_mappings = [{
          'user_id': 1, # This is pk?
          'email_address': 'jack@yahoo.com',
          '_id': 1
      }, ...]
      
      session.bulk_update_mappings(User, user_mappings)
      session.commit()
      

      【讨论】:

      • 不适用于我的复合主键。 (v_id, order)
      • @NickWoodhams 在我的情况下工作得很好,使用复合主键(Col1,col2)。你遇到了什么错误?
      • 请注意,该问题要求使用 SQLAlchemy 核心解决方案。此解决方案使用 SQLAlchemy ORM,而不是核心。
      【解决方案3】:

      阅读文档的Inserts, Updates and Deletes 部分。以下代码应该可以帮助您入门:

      from sqlalchemy.sql.expression import bindparam
      stmt = addresses.update().\
          where(addresses.c.id == bindparam('_id')).\
          values({
              'user_id': bindparam('user_id'),
              'email_address': bindparam('email_address'),
          })
      
      conn.execute(stmt, [
          {'user_id': 1, 'email_address' : 'jack@yahoo.com', '_id':1},
          {'user_id': 1, 'email_address' : 'jack@msn.com', '_id':2},
          {'user_id': 2, 'email_address' : 'www@www.org', '_id':3},
          {'user_id': 2, 'email_address' : 'wendy@aol.com', '_id':4},
      ])
      

      【讨论】:

      • 同样依赖多个选择的插入呢?
      • update() missing 1 required positional argument: 'values',这个例子中的地址是什么?
      • @HeddevanderHeide: addressesTable 的实例中
      • 这很慢。同样,对于插入,我注意到 conn.execute(table.insert().values([...]))conn.execute(table.insert(), [...]) 快得多。我可以为更新做类似的事情以使其更快吗?
      • 我认为更新后的链接现在是Insert, Updates, Deletes
      猜你喜欢
      • 2013-12-07
      • 2023-03-16
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      相关资源
      最近更新 更多