我正在将数据添加到sqlalchemy。但是有时数据不会更新或插入数据库。但是提交成功,我可以在会话对象的内存中看到数据。 即
session.identity_map
在sqlalchemy 1.3.3上运行。 python 2.7。 ubuntu 18.04
from sqlalchemy.orm import Session
from . import Errors as ExecuteErrors
class Errors(object):
def __init__(self, sqlalchemy_engine, d):
self.sqlalchemy_engine = sqlalchemy_engine
self.d = d
def upsert(self, error):
session = Session(self.sqlalchemy_engine)
row = session.query(ExecuteErrors).filter_by(**{'c_name':error['c_name'], 'c_type':error['c_type'],
'f_name':error['f_name']}).scalar()
session.close()
if row:
self.update(error)
else:
self.insert(error)
def insert(self, error):
e = ExecuteErrors(**{'c_name':error['c_name'], 'c_type':error['c_type'], 'f_name':error['f_name'],
'msg':error['msg'], 'details':error['details']})
session = Session(self.sqlalchemy_engine, expire_on_commit=False)
session.add(e)
session.identity_map
session.commit()
session.close()
def update(self, error):
session = Session(self.sqlalchemy_engine, expire_on_commit=False)
session.query(ExecuteErrors).filter_by(**{'c_name':error['c_name'], 'c_type':error['c_type'],
'f_name':error['f_name']}).update({'msg': error['msg'], 'details': error['details']})
session.commit()
session.close()
def get_errors(self):
session = Session(self.sqlalchemy_engine)
e = session.query(ExecuteErrors).all()
session.close()
return e
def clear(self):
session = Session(self.sqlalchemy_engine)
session.query(ExecuteErrors).delete()
session.commit()
session.close()
致电:
e = Error(engine, 'emp')
e.upsert({'c_name':'filter','c_type':'task','f_name':'f1','msg':'TypeError','details':'xyz'})
这应该在数据库中添加行或使用新数据更新行。 它适用于某些插入,而对于某些无效。
答案 0 :(得分:0)
在需要时通过明确flushing您的会话,您可以找到可能的解决方法。
也就是说,我认为您应该重新考虑使用会话的方式。会话旨在管理数据库连接,但是您就像在实际连接一样使用它们。
恕我直言,更好的方法是在Error实例中创建一个会话,并在所有方法中都需要时使用它。 一种更好的处理方法是在“调用”模块开始时创建一个会话,并将其传递给Error实例以及任何其他需要访问数据库的对象。 这样做甚至可以带来更好的性能,并且可以解决您的问题(?)
有关how to manage sessions in the sqlalchemy doc的更多详细信息。
编辑:此外,sqlalchemy doc lists some potential problems when used with sqlite。其中之一可能是导致您出现问题的原因。