Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 8, 2013 18:17:18

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с транзакциями

Пытаемся сделать множественный insert в базу. Если данные не корректны - проблема с индексами, типами и тд., то такие строки нам не нужны.
Получился код представления:

@view_config(route_name="loader",
                 request_method="POST",
                 renderer="json")
    def _loader(self):
        # ........
        for i, el in enumerate(els):
            try:
                # .......
                ask = page.xpath(el.ask_xpath)
                bid = page.xpath(el.bid_xpath)
                r = DBSession.query(Rate).filter(Rate.date==datetime.date.today()).first()
                if r: DBSession.delete(r)
                r = Rate(ask = ask, bid = bid)
                DBSession.add(rate)
            except Exception, e:
                pass
            finally:
                self.request.session.flash(i, queue='loader');
        return dict(parse_progress=self.request.session.pop_flash('loader'))

Выполнение кода приводит к ошибке
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().

Если ставим DBSession.rollback() в блок исключений, то получаем
ResourceClosedError: The transaction is closed

Похожий вопрос задавался здесь, но предложенные решения не рабочие



Отредактировано dorian (Янв. 8, 2013 18:18:19)

Офлайн

#2 Янв. 9, 2013 09:14:37

sank
Зарегистрирован: 2012-10-05
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с транзакциями

Такое ощущение, что в каждой итерации начинается новая транзакция, т.к. ошибка “ To begin a new transaction with this Session, first issue Session.rollback()” появляется тогда, когда есть незакрытая транзакция и какая-то новая транзакция пытается что-то делать в базе.
Может как-то явно попробовать начать транзакцию и в ней все изменения делать?

Офлайн

#3 Янв. 9, 2013 12:49:17

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблема с транзакциями

После DBSession.rollback() в обработке исключения нужно создать новый объект DBSession.
Но это больше похоже на устранение последствий, а не причин.

После изменения модели нужно делать DBSession.flush(), чтобы обновить состояние модели.
Проверьте состояние DBSession.autoflush. Должно быть True.
И только после обработки всех данных закоммитить транзакцию во внешнем блоке try…except (сейчас у вас в коде его нет).



Офлайн

#4 Янв. 9, 2013 15:56:29

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с транзакциями

Lexander
После DBSession.rollback() в обработке исключения нужно создать новый объект DBSession.Но это больше похоже на устранение последствий, а не причин.После изменения модели нужно делать DBSession.flush(), чтобы обновить состояние модели.Проверьте состояние DBSession.autoflush. Должно быть True.И только после обработки всех данных закоммитить транзакцию во внешнем блоке try…except (сейчас у вас в коде его нет).

Перед тем как создавалась тема, были испробованы:
DBSession.flush()+DBSession.rollback() - ResourceClosedError: The transaction is closed
transaction.commit()+transaction.abort() - на первой итерации закрывается транзакция
автокомит и автофлуш включены

sank
Такое ощущение, что в каждой итерации начинается новая транзакция, т.к. ошибка “ To begin a new transaction with this Session, first issue Session.rollback()” появляется тогда, когда есть незакрытая транзакция и какая-то новая транзакция пытается что-то делать в базе.Может как-то явно попробовать начать транзакцию и в ней все изменения делать?
Вся печаль в том, что закомитить можно через transaction.commit(), но как и писал выше, это автоматом прекращает выполнение кода.



Отредактировано dorian (Янв. 9, 2013 15:58:39)

Офлайн

#5 Янв. 9, 2013 16:42:43

sank
Зарегистрирован: 2012-10-05
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с транзакциями

Дык вы явно транзакцию запускать пробовали?

connection = engine.connect()
trans = connection.begin()
try:
    r1 = connection.execute(table1.select())
    connection.execute(table1.insert(), col1=7, col2='this is some data')
    trans.commit()
except:
    trans.rollback()
    raise
стырено отсюда: http://docs.sqlalchemy.org/en/rel_0_7/core/connections.html#using-transactions
Я сам по причине лени не пробовал, но думается мне надо туда копать …
Если не поможет, то, думаю, нужно явный execute делать, вместо использования объектов.
Либо курить доку и разбираться чо там ORM делает в случае появления SQL-ных эксепшенов.

… у вас ситуация немного не штатная. Вы хотите на эксепшене ничего не делать, продолжая транзакцию, поэтому тут ORM может вам палки в колёса ставить.

Отредактировано sank (Янв. 9, 2013 16:44:55)

Офлайн

#6 Янв. 9, 2013 17:54:51

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблема с транзакциями

sank
Дык вы явно транзакцию запускать пробовали?
При условии включенного автокоммита, если явная транзакция сработает, значит либо баг в Алхимии, либо ошибка в алгоритме.

Что выдает монитор операций СУБД?
Возможно, какие-то команды лишние идут.



Офлайн

#7 Янв. 9, 2013 18:01:44

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблема с транзакциями

Плюс я бы проверил connection.info перед каждой операцией.



Офлайн

#8 Янв. 11, 2013 08:57:15

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Проблема с транзакциями

Офлайн

#9 Янв. 13, 2013 19:05:23

dorian
От:
Зарегистрирован: 2006-05-18
Сообщения: 79
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с транзакциями

bismigalis
не оно? http://stackoverflow.com/a/575711/1449350
нет
в общем пришлось проверять каждое значение, иного выхода не нашлось. Проблема судя по всему в pyramid_tm ибо этот код вне пирамиды и без pyramid_tm работает как нужно.



Офлайн

#10 Янв. 24, 2013 08:15:03

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Проблема с транзакциями

dorian
в общем пришлось проверять каждое значение

А можно поподробнее, а то хочется понять в чем там собака была

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version