Перехоплення помилок SQL

При створенні чи оновлені записів через код (функції create та write) можуть виникати помилки цілістності даних з боку СУБД. Найбільш часто це обов'язкові поля для create та обмеження задані _sql_constraints.

Форми Odoo обробляють ці обмеження автоматично. Коли ви пишете створення або оновлення через код, наприклад, при написання кастомних контролерів, вам потрібно працювати з ними вручну.

Скажімо, маємо цю просту модель:

class DemoModel(models.Model):
    _name = 'my.demo.model'
    name = fields.Char()
    _sql_constraints = [('name_uniq', 'unique("name")', 'Name must be unique')]

Коли обмеження порушується, виникає помилка psycopg2.IntegrityError. Вам потрібно перехопити помилку і вирішити проблему. І тут настає складна частина – швидше за все ви зіткнетеся з InternalError:

InternalError: current transaction is aborted, commands ignored until end of transaction block.

Це відбувається тому, що після помилки PostgreSQL не дозволить наступні запити в тій самій транзакції. Спершу потрібно завершити транзакцію шляхом підтвердження або відкату.

Ось повний приклад:

class DemoModelController(http.Controller):
    @http.route('/demo/create/', auth='public', website=True)
    def create(self, name):
        try:
            http.request.env['my.demo.model'].create({'name': name, })
            return http.request.render('my.thank_you_page')
        except IntegrityError:
            http.request._cr.rollback()
            return http.request.render('my.error_page')

Не можна використовувати звичайний стиль http.request.env.cr, оскільки env запитує базу даних через вже закрешениу транзакцію.


Перехоплення помилок SQL
Володимир Карабанов 9 лютого 2023 р.
Поділитися цією публікацією
Теги
Архів
Save... force_save