sqlalchemy - данные не помещаются в базу данных при фиксации, но присутствуют в сеансе (в памяти) - PullRequest
0 голосов
/ 28 мая 2019

Я добавляю данные в 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 голосов
/ 29 мая 2019

Вы можете найти возможный обходной путь, явно сбросив вашу сессию, когда это необходимо.

Тем не менее, я думаю, вам следует пересмотреть способ использования сессий.Сеансы предназначены для управления соединениями с базой данных, но вы используете их так, как если бы они находились там, где есть реальные соединения.

ИМХО, лучший способ сделать это - создать сеанс в экземпляре Error и использовать его при необходимости во всех вашихметоды.Еще лучшим способом для продолжения может быть создание сеанса в начале вашего «вызывающего» модуля и передача его в экземпляр Error и любому другому объекту, которому необходим доступ к базе данных.При этом вы могли бы даже повысить производительность и решить вашу проблему (?)

Подробнее о , как управлять сеансами в sqlalchemy doc .

РЕДАКТИРОВАТЬ:Кроме того, документ sqlalchemy перечисляет некоторые потенциальные проблемы при использовании с sqlite .Одна из них может быть причиной вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...