API Reference

Commands

django-pgtrigger comes with the python manage.py pgtrigger command, which has several subcommands that are described below.

ls

Use python manage.py pgtrigger ls to list all triggers managed by django-pgtrigger. The installation status and trigger URI will be shown.

The following are valid installation status markers:

  • INSTALLED: The trigger is installed and up to date

  • OUTDATED: The trigger is installed, but it has not been migrated to the current version.

  • UNINSTALLED: The trigger is not installed.

  • PRUNE: A trigger is no longer in the codebase and still installed.

  • UNALLOWED: Trigger installation is not allowed for this database. Only applicable in a multi-database environment.

Note that every installed trigger, including ones that will be pruned, will show whether they are enabled or disabled. Disabled triggers are installed but do not run.

Tip

You can provide trigger URIs as arguments to python manage.py pgtrigger ls to only list specific triggers. The URI is the last column returned by python manage.py pgtrigger ls.

install

Use python manage.py pgtrigger install to install triggers. If no arguments are provided, all triggers are installed and any orphaned ones will be pruned.

You can provide trigger URIs as arguments to install specific triggers or filter triggers on a database with the --database argument.

uninstall

Uninstall has the same behavior as python manage.py pgtrigger install except triggers will be uninstalled.

Danger

Running uninstall will globally uninstall triggers. If you need to temporarily ignore a trigger, see the Ignoring Execution section.

enable

python manage.py pgtrigger enable enables triggers. Similar to other commands, one can provide trigger URIs or the database.

disable

Disable has the same behavior as python manage.py pgtrigger enable except triggers will be disabled.

Danger

Running disable will globally disable the execution of triggers. If you need to temporarily ignore a trigger, see the Ignoring Execution section.

prune

python manage.py pgtrigger prune will uninstall any triggers managed by django-pgtrigger that are no longer in the codebase.

Note

Pruning happens automatically when doing python manage.py pgtrigger install or python manage.py pgtrigger uninstall.

Python Package

Below are the core classes and functions of the pgtrigger module.

Level clause

pgtrigger.Row = <pgtrigger.core.Level object>

For specifying row-level triggers (the default)

pgtrigger.Statement = <pgtrigger.core.Level object>

For specifying statement-level triggers

When clause

pgtrigger.After = <pgtrigger.core.When object>

For specifying AFTER in the when clause of a trigger

pgtrigger.Before = <pgtrigger.core.When object>

For specifying BEFORE in the when clause of a trigger

pgtrigger.InsteadOf = <pgtrigger.core.When object>

For specifying INSTEAD OF in the when clause of a trigger

Operation clause

pgtrigger.Truncate = <pgtrigger.core.Operation object>

For specifying TRUNCATE as the trigger operation

pgtrigger.Delete = <pgtrigger.core.Operation object>

For specifying DELETE as the trigger operation

pgtrigger.Insert = <pgtrigger.core.Operation object>

For specifying INSERT as the trigger operation

pgtrigger.Update = <pgtrigger.core.Operation object>

For specifying UPDATE as the trigger operation

class pgtrigger.UpdateOf(*columns)[source]

For specifying UPDATE OF as the trigger operation.

Referencing clause

class pgtrigger.Referencing(*, old=None, new=None)[source]

For specifying the REFERENCING clause of a statement-level trigger

Timing clause

pgtrigger.Immediate = <pgtrigger.core.Timing object>

For specifying IMMEDIATE as the default timing for deferrable triggers

pgtrigger.Deferred = <pgtrigger.core.Timing object>

For specifying DEFERRED as the default timing for deferrable triggers

Conditions

class pgtrigger.Condition(sql=None)[source]

For specifying free-form SQL in the condition of a trigger.

class pgtrigger.Q(*args, _connector=None, _negated=False, **kwargs)[source]

Similar to Django’s Q object, allows referencing the old and new rows in a trigger condition.

class pgtrigger.F(*args, **kwargs)[source]

Similar to Django’s F object, allows referencing the old and new rows in a trigger condition.

class pgtrigger.IsDistinctFrom(lhs, rhs)[source]

A custom IS DISTINCT FROM field lookup for common trigger conditions. For example, pgtrigger.Q(old__field__df=pgtrigger.F("new__field")).

class pgtrigger.IsNotDistinctFrom(lhs, rhs)[source]

A custom IS NOT DISTINCT FROM field lookup for common trigger conditions. For example, pgtrigger.Q(old__field__ndf=pgtrigger.F("new__field")).

Triggers

class pgtrigger.Trigger(*, name=None, level=None, when=None, operation=None, condition=None, referencing=None, func=None, declare=None, timing=None)[source]

For specifying a free-form PL/pgSQL trigger function or for creating derived trigger classes.

class pgtrigger.Protect(*, name=None, level=None, when=None, operation=None, condition=None, referencing=None, func=None, declare=None, timing=None)[source]

A trigger that raises an exception.

class pgtrigger.SoftDelete(*, name=None, condition=None, field=None, value=<object object>)[source]

Sets a field to a value when a delete happens.

Supply the trigger with the “field” that will be set upon deletion and the “value” to which it should be set. The “value” defaults to False.

Note

This trigger currently only supports nullable BooleanField, CharField, and IntField fields.

class pgtrigger.FSM(*, name=None, condition=None, field=None, transitions=None)[source]

Enforces a finite state machine on a field.

Supply the trigger with the “field” that transitions and then a list of tuples of valid transitions to the “transitions” argument.

Note

Only non-null CharField fields are currently supported.

class pgtrigger.UpdateSearchVector(*, name=None, vector_field=None, document_fields=None, config_name=None)[source]

Updates a django.contrib.postgres.search.SearchVectorField from document fields.

Supply the trigger with the vector_field that will be updated with changes to the document_fields. Optionally provide a config_name, which defaults to pg_catalog.english.

This trigger uses tsvector_update_trigger to update the vector field. See the Postgres docs for more information.

Note

UpdateSearchVector triggers are not compatible with pgtrigger.ignore since it references a built-in trigger. Trying to ignore this trigger results in a RuntimeError.

Runtime execution

pgtrigger.constraints(timing, *uris, databases=None)[source]

Set deferrable constraint timing for the given triggers, which will persist until overridden or until end of transaction. Must be in a transaction to run this.

Parameters
  • timing (pgtrigger.Timing) – The timing value that overrides the default trigger timing.

  • *uris (str) – Trigger URIs over which to set constraint timing. If none are provided, all trigger constraint timing will be set. All triggers must be deferrable.

  • databases (List[str], default=None) – The databases on which to set constraints. If none, all postgres databases will be used.

Raises
  • RuntimeError – If the database of any triggers is not in a transaction.

  • ValueError – If any triggers are not deferrable.

pgtrigger.ignore(*uris, databases=None)[source]

Dynamically ignore registered triggers matching URIs from executing in an individual thread. If no URIs are provided, ignore all pgtriggers from executing in an individual thread.

Parameters
  • *uris (str) – Trigger URIs to ignore. If none are provided, all triggers will be ignored.

  • databases (List[str], default=None) – The databases to use. If none, all postgres databases will be used.

Examples

Ingore triggers in a context manager:

with pgtrigger.ignore("my_app.Model:trigger_name"):
    # Do stuff while ignoring trigger

Ignore multiple triggers as a decorator:

@pgtrigger.ignore("my_app.Model:trigger_name", "my_app.Model:other_trigger")
def my_func():
    # Do stuff while ignoring trigger
pgtrigger.schema(*schemas, databases=None)[source]

Sets the search path to the provided schemas.

If nested, appends the schemas to the search path if not already in it.

Parameters
  • *schemas (str) – Schemas that should be appended to the search path. Schemas already in the search path from nested calls will not be appended.

  • databases (List[str], default=None) – The databases to set the search path. If none, all postgres databases will be used.

Registry

pgtrigger.register(*triggers)[source]

Register the given triggers with wrapped Model class.

Parameters

*triggers (pgtrigger.Trigger) – Trigger classes to register.

Examples

Register by decorating a model:

@pgtrigger.register(
    pgtrigger.Protect(
        name="append_only",
        operation=(pgtrigger.Update | pgtrigger.Delete)
    )
)
class MyModel(models.Model):
    pass

Register by calling functionally:

pgtrigger.register(trigger_object)(MyModel)
pgtrigger.registered(*uris)[source]

Get registered trigger objects.

Parameters

*uris (str) – URIs of triggers to get. If none are provided, all triggers are returned. URIs are in the format of {app_label}.{model_name}:{trigger_name}.

Returns

Matching trigger objects.

Return type

List[Tuple[models.Model, pgtrigger.Trigger]]

Installation

pgtrigger.install(*uris, database=None)[source]

Install triggers.

Parameters
  • *uris (str) – URIs of triggers to install. If none are provided, all triggers are installed and orphaned triggers are pruned.

  • database (str, default=None) – The database. Defaults to the “default” database.

pgtrigger.uninstall(*uris, database=None)[source]

Uninstalls triggers.

Parameters
  • *uris (str) – URIs of triggers to uninstall. If none are provided, all triggers are uninstalled and orphaned triggers are pruned.

  • database (str, default=None) – The database. Defaults to the “default” database.

pgtrigger.enable(*uris, database=None)[source]

Enables registered triggers.

Parameters
  • *uris (str) – URIs of triggers to enable. If none are provided, all triggers are enabled.

  • database (str, default=None) – The database. Defaults to the “default” database.

pgtrigger.disable(*uris, database=None)[source]

Disables triggers.

Parameters
  • *uris (str) – URIs of triggers to disable. If none are provided, all triggers are disabled.

  • database (str, default=None) – The database. Defaults to the “default” database.

pgtrigger.prunable(database=None)[source]

Return triggers that are candidates for pruning

Parameters

database (str, default=None) – The database. Defaults to the “default” database.

pgtrigger.prune(database=None)[source]

Remove any pgtrigger triggers in the database that are not used by models. I.e. if a model or trigger definition is deleted from a model, ensure it is removed from the database

Parameters

database (str, default=None) – The database. Defaults to the “default” database.