sqlalchemy批量更新失败

问题描述 投票:0回答:1

我有一个表= foo(下面的最小示例):

house       processed
----------  ----------
95.0
10.0
63.0
6.0
55.0
1.0
19.0
1.0
30.0
21.0
sprite

我想将十进制值更改为整数,并找出该列中何时有非数字值。我已经尝试过使用query.filter().update()构造,尽管这给了我想要的东西,但是对于10万行,它需要花费很长时间。我知道bulk_update可以帮助我。但是我可能做错了。我的代码是:

class foo(Base):
    __tablename__ = "foo"
    rowid = Column(Integer, primary_key=True)
    house = Column(Float)
    processed = Column(String(255))

mappings = []
for idx, s in enumerate(session.query(foo), start=1):    
    if type(s.house) in (int, float):
        replace = int(s.house)            
        info = {'processed':replace}
    else:
        info = {'processed':'not number'}        
    mappings.append(info)  
session.bulk_update_mappings(foo, mappings)
session.commit()

映射[{'processed':95},{'processed':10},{'processed':63},{'processed':6},{'processed':55},{'processed':1 }, {'处理':19},{'处理':1},{'处理':30},{'处理':21},{'已处理':'非数字'}]

这给我一个错误:

关于表'foo'的更新语句预期将更新11行; 0个匹配

完整错误:

session.bulk_update_mappings(foo, mappings)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\M64H098\repo\Enrichments-bag\lib\site-packages\sqlalchemy\orm\session.py", line 2868, in bulk_update_mappings
    self._bulk_save_mappings(
  File "C:\Users\M64H098\repo\Enrichments-bag\lib\site-packages\sqlalchemy\orm\session.py", line 2885, in _bulk_save_mappings
    transaction = self.begin(subtransactions=True)
  File "C:\Users\M64H098\repo\Enrichments-bag\lib\site-packages\sqlalchemy\orm\session.py", line 947, in begin
    self.transaction = self.transaction._begin(nested=nested)
  File "C:\Users\M64H098\repo\Enrichments-bag\lib\site-packages\sqlalchemy\orm\session.py", line 316, in _begin
    self._assert_active()
  File "C:\Users\M64H098\repo\Enrichments-bag\lib\site-packages\sqlalchemy\orm\session.py", line 288, in _assert_active
    raise sa_exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: UPDATE statement on table 'foo' expected to update 11 row(s); 0 were matched. (Background on this error at: http://sqlalche.me/e/7s2a)

如何使用processed字典批量更新mapping列?

python sqlalchemy flask-sqlalchemy
1个回答
1
投票

bulk_update_mappings要求将要更新的行的主键包含在更新字典中。考虑到这一点,这很有意义-数据库需要一种方法来标识必须更新的行。在这种情况下,主键将是rowid模型的Foo

info = {'rowid': s.rowid, 'processed':replace}

摘自文档(重点是我的文档):

字典序列,...所有存在的但不属于主键的键都应用于UPDATE语句的SET子句; 必需的主键值应用于WHERE子句。

© www.soinside.com 2019 - 2024. All rights reserved.