При створенні чи оновлені записів через код (функції 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 запитує базу даних через вже закрешениу транзакцію.