sqlalchemy-提交时数据未推送到数据库,但存在于会话中(在内存中)

时间:2019-05-28 17:27:24

标签: python-2.7 sqlite sqlalchemy

我正在将数据添加到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'})

这应该在数据库中添加行或使用新数据更新行。 它适用于某些插入,而对于某些无效。

1 个答案:

答案 0 :(得分:0)

在需要时通过明确flushing您的会话,您可以找到可能的解决方法。

也就是说,我认为您应该重新考虑使用会话的方式。会话旨在管理数据库连接,但是您就像在实际连接一样使用它们。

恕我直言,更好的方法是在Error实例中创建一个会话,并在所有方法中都需要时使用它。 一种更好的处理方法是在“调用”模块开始时创建一个会话,并将其传递给Error实例以及任何其他需要访问数据库的对象。 这样做甚至可以带来更好的性能,并且可以解决您的问题(?)

有关how to manage sessions in the sqlalchemy doc的更多详细信息。

编辑:此外,sqlalchemy doc lists some potential problems when used with sqlite。其中之一可能是导致您出现问题的原因。