我有一个表= 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
列?
bulk_update_mappings要求将要更新的行的主键包含在更新字典中。考虑到这一点,这很有意义-数据库需要一种方法来标识必须更新的行。在这种情况下,主键将是rowid
模型的Foo
。
info = {'rowid': s.rowid, 'processed':replace}
摘自文档(重点是我的文档):
字典序列,...所有存在的但不属于主键的键都应用于UPDATE语句的SET子句; 必需的主键值应用于WHERE子句。