Будет ли выполняться мой триггер postgresql, даже если я установлю значение из модели django при сохранении?
Я создал триггер на каждую строку INSERT/UPDATE для установки created_at и updated_at соответственно.
Триггер:
CREATE OR REPLACE FUNCTION insert_update_function() RETURNS trigger AS $BODY$
BEGIN
-- CHECKING OPERATION TYPE AND DECIDE COLUMN
IF TG_OP = 'INSERT' THEN
NEW.created_at := current_timestamp;
ELSE
NEW.updated_at := current_timestamp;
END IF;
RETURN NEW;
END; $BODY$ LANGUAGE plpgsql VOLATILE;
Применять триггер только к тем таблицам, где существует колонка updated_at
DO $$
DECLARE
t text;
BEGIN
FOR t IN
SELECT table_name FROM information_schema.columns WHERE column_name = 'updated_at'
LOOP
EXECUTE format('CREATE TRIGGER insert_update_trigger
BEFORE INSERT OR UPDATE ON %I
FOR EACH ROW EXECUTE PROCEDURE insert_update_function()', t,t);
END loop;
END;
$$ language plpgsql;
Когда я делаю INSERT/UPDATE из необработанного SQL, я не предоставляю эти два столбца, т.е. created_at и updated_at. т.е. created_at и updated_at, он автоматически срабатывает и добавляется в мою таблицу, что ожидаемо и нормально, но теперь мой вопрос в том, когда я пытаюсь INSERT/UPDATE строки таблицы через Django BaseModel, где я устанавливаю created_at и updated_at, триггер будет снова вызван?
Django BaseModel с пользовательским save()
class TimeStampedModel(models.Model):
"""
An abstract base class model that provides self-updating
``created_at`` and ``modified_at`` fields.
"""
created_at = AutoCreatedField('created_at')
updated_at = AutoLastModifiedField('updated_at')
def save(self, *args, **kwargs):
"""
Overriding the save method in order to make sure that
updated_at field is updated even if it is not given as
a parameter to the update field argument.
"""
update_fields = kwargs.get('update_fields', None)
if update_fields:
kwargs['update_fields'] = set(update_fields).union({'updated_at'})
super().save(*args, **kwargs)
class Meta:
abstract = True
Да, он будет вызван. Изменения триггера Postgresql перекрывают изменения оператора, когда вы возвращаете триггер с помощью return new
. Если вы не хотите этого, вы можете добавить условие (оператор when) к своим триггерам