#node.js #postgresql #stored-procedures #triggers #sequelize.js
#node.js #postgresql #хранимые процедуры #триггеры #sequelize.js
Вопрос:
Я хочу реализовать soft_delete. Итак, я создал перехват в моем классе модели, beforeBulkDelete
который вызывает хранимую процедуру, которая помещает некоторую дату в deleted_at
столбец и возвращает TRIGGER
.
Я хочу вернуть NULL
в качестве триггера, чтобы фактическое удаление не произошло.
Я попытался создать триггеры с помощью CREATE TRIGGER
команды вместо использования перехватов Sequelize, и это работает нормально. Но я хотел бы сделать это с помощью перехватов.
Вот мой класс модели —
```export default function defineAttachment(
sequelize: Sequelize.Sequelize,
DataTypes: any
) {
const XerceCaseAttachment = sequelize.define(
'XerceCaseAttachment',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
.
.
.
deletedAt: {
type: DataTypes.DATE,
field: 'deleted_at',
},
},
{
tableName: 'attachments',
hooks: {
beforeBulkDestroy: (options: any) => {
sequelize.query(`SELECT soft_delete();`, {
type: sequelize.QueryTypes.DELETE,
transaction: options.transaction,
});
},
},
}
);```
Вот моя soft_delete
хранимая процедура —
```CREATE OR REPLACE FUNCTION soft_delete()
RETURNS TRIGGER AS
$$
BEGIN
RAISE NOTICE 'test triggers';
EXECUTE 'UPDATE attachments SET deleted_at = current_timestamp WHERE id = $1';
RETURN NULL;
END;
$$ LANGUAGE PLPGSQL;```
Я получаю следующую ошибку —
```Unhandled rejection SequelizeDatabaseError: trigger functions can only be called as triggers
at Query.formatError (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/sequelize/lib/dialects/postgres/query.js:363:16)
at query.catch.err (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/sequelize/lib/dialects/postgres/query.js:86:18)
at bound (domain.js:395:14)
at runBound (domain.js:408:12)
at tryCatcher (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/promise.js:690:18)
at _drainQueueStep (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/async.js:138:12)
at _drainQueue (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues [as _onImmediate] (/home/ishankhanduja/Cyberdyne/cyberdyne/server/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
at process.topLevelDomainCallback (domain.js:120:23)```
Ожидание —
Он не должен удалять строку, вместо этого некоторая дата сохраняется в deleted_at
Комментарии:
1. Используйте триггер. Это более эффективно и надежно.
2. @LaurenzAlbe Спасибо за ваш ответ. Но есть ли какая-то конкретная причина использовать триггеры вместо перехватов? Я имею в виду с точки зрения производительности или чего-то еще?. Потому что я использовал перехваты для создания записей, и это работает нормально.
3. Мои причины таковы: 1) это быстрее и 2) это надежно (выполняется в одной транзакции). Отказ от ответственности: будучи специалистом по базам данных, я больше доверяю базе данных.