SQLAlchemy:循环遍历模型对象以复制它们时的KeyError

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

我想查询行并在更改每个属性时复制它们。这是我的代码。

 colObjs= db.session.query(Column).filter_by(chart_id=oldChartID).all()
 for colObj in colObjs:
   make_transient(colObj)
   print colObj.id
   del colObj.id
   colObj.chart_id= newChartID
   db.session.add(colObj)
   db.session.commit()

在这个例子中,colObjs有两个对象。我通过colObjs循环,越过每个colObj。循环中的第一项复制正常。但是当我尝试复制第二个时,我得到了这个错误。

Traceback (most recent call last):
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/path/to/local/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/path/to/myApp.py", line 859, in copyGraphic
    del colObj.id
  File "/path/to/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 227, in __delete__
    self.impl.delete(instance_state(instance), instance_dict(instance))
  File "/path/to/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 679, in delete
    del dict_[self.key]
KeyError: 'id'

此外,print语句在循环的第一项上的输出显示coloObj id,但第二项输出None

为什么会发生这种错误?我如何解决它?

python sqlalchemy
1个回答
1
投票

你得到异常的原因是你在循环中提交。总而言之,这通常是反模式。在之前的会话中的第一轮the act of committing will expire the Column instances之后,所以在第二次迭代中del colObj.id提升,因为对象已经过期并且没有加载状态。解决方案是在循环之后简单地移动提交。

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