django-pgtrigger


Namedjango-pgtrigger JSON
Version 4.11.1 PyPI version JSON
download
home_pagehttps://github.com/Opus10/django-pgtrigger
SummaryPostgres trigger support integrated with Django models.
upload_time2024-04-06 16:58:22
maintainerNone
docs_urlNone
authorWes Kendall
requires_python<4,>=3.8.0
licenseBSD-3-Clause
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # django-pgtrigger

`django-pgtrigger` helps you write [Postgres triggers](https://www.postgresql.org/docs/current/sql-createtrigger.html) for your Django models.

## Why should I use triggers?

Triggers can solve a variety of complex problems more reliably, performantly, and succinctly than application code.
For example,

* Protecting operations on rows or columns (`pgtrigger.Protect`).
* Making read-only models or fields (`pgtrigger.ReadOnly`).
* Soft-deleting models (`pgtrigger.SoftDelete`).
* Snapshotting and tracking model changes ([django-pghistory](https://django-pghistory.readthedocs.io/)).
* Enforcing field transitions (`pgtrigger.FSM`).
* Keeping a search vector updated for full-text search (`pgtrigger.UpdateSearchVector`).
* Building official interfaces (e.g. enforcing use of `User.objects.create_user` and not `User.objects.create`).
* Versioning models, mirroring fields, computing unique model hashes, and the list goes on...

All of these examples require no overridden methods, no base models, and no signal handling.

## Quick start

Install `django-pgtrigger` with `pip3 install django-pgtrigger` and add `pgtrigger` to `settings.INSTALLED_APPS`.

`pgtrigger.Trigger` objects are added to `triggers` in model `Meta`. `django-pgtrigger` comes with several trigger classes, such as `pgtrigger.Protect`. In the following, we're protecting the model from being deleted:

```python
import pgtrigger

class ProtectedModel(models.Model):
    """This model cannot be deleted!"""

    class Meta:
        triggers = [
            pgtrigger.Protect(name="protect_deletes", operation=pgtrigger.Delete)
        ]
```

When migrations are created and executed, `ProtectedModel` will raise an exception anytime a deletion is attempted.

Let's extend this example further and only protect deletions on inactive objects. In this example, the trigger conditionally runs when the row being deleted (the `OLD` row in trigger terminology) is still active:

```python
import pgtrigger

class ProtectedModel(models.Model):
    """Active object cannot be deleted!"""
    is_active = models.BooleanField(default=True)

    class Meta:
        triggers = [
            pgtrigger.Protect(
                name="protect_deletes",
                operation=pgtrigger.Delete,
                condition=pgtrigger.Q(old__is_active=True)
            )
        ]
```

`django-pgtrigger` uses `pgtrigger.Q` and `pgtrigger.F` objects to conditionally execute triggers based on the `OLD` and `NEW` rows. Combining these Django idioms with `pgtrigger.Trigger` objects can solve a wide variety of problems without ever writing SQL. Users, however, can still use raw SQL for complex cases.

Triggers are installed like other database objects. Run `python manage.py makemigrations` and `python manage.py migrate` to install triggers.

If triggers are new to you, don't worry. The [pgtrigger docs](https://django-pgtrigger.readthedocs.io/) cover triggers in more detail and provide many examples.

## Compatibility

`django-pgtrigger` is compatible with Python 3.8 - 3.12, Django 3.2 - 5.0, Psycopg 2 - 3, and Postgres 12 - 16.

## Documentation

[View the django-pgtrigger docs here](https://django-pgtrigger.readthedocs.io/) to learn more about:

* Trigger basics and motivation for using triggers.
* How to use the built-in triggers and how to build custom ones.
* Installing triggers on third-party models, many-to-many fields, and other advanced scenarios.
* Writing conditional triggers.
* Ignoring triggers dynamically and deferring trigger execution.
* Multiple database, schema, and partitioning support.
* Frequently asked questions, common issues, and upgrading.
* The commands, settings, and module.

## Installation

Install `django-pgtrigger` with:

    pip3 install django-pgtrigger

After this, add `pgtrigger` to the `INSTALLED_APPS` setting of your Django project.

## Other Material

After you've read the docs, check out [this tutorial](https://wesleykendall.github.io/django-pgtrigger-tutorial/) with interactive examples from a Django meetup talk.

The [DjangoCon 2021 talk](https://www.youtube.com/watch?v=Tte3d4JjxCk) also breaks down triggers and shows several examples.

## Contributing Guide

For information on setting up django-pgtrigger for development and contributing changes, view [CONTRIBUTING.md](CONTRIBUTING.md).

## Primary Authors

- [Wes Kendall](https://github.com/wesleykendall)

## Other Contributors

- @jzmiller1
- @rrauenza
- @ralokt
- @adamchainz
- @danifus
- @kekekekule
- @peterthomassen
- @pfouque

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Opus10/django-pgtrigger",
    "name": "django-pgtrigger",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4,>=3.8.0",
    "maintainer_email": null,
    "keywords": null,
    "author": "Wes Kendall",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/ad/2e/35ec851296e3dbfe58808576099c98d6c22085f56c0ec301ab1e7cfeba72/django_pgtrigger-4.11.1.tar.gz",
    "platform": null,
    "description": "# django-pgtrigger\n\n`django-pgtrigger` helps you write [Postgres triggers](https://www.postgresql.org/docs/current/sql-createtrigger.html) for your Django models.\n\n## Why should I use triggers?\n\nTriggers can solve a variety of complex problems more reliably, performantly, and succinctly than application code.\nFor example,\n\n* Protecting operations on rows or columns (`pgtrigger.Protect`).\n* Making read-only models or fields (`pgtrigger.ReadOnly`).\n* Soft-deleting models (`pgtrigger.SoftDelete`).\n* Snapshotting and tracking model changes ([django-pghistory](https://django-pghistory.readthedocs.io/)).\n* Enforcing field transitions (`pgtrigger.FSM`).\n* Keeping a search vector updated for full-text search (`pgtrigger.UpdateSearchVector`).\n* Building official interfaces (e.g. enforcing use of `User.objects.create_user` and not `User.objects.create`).\n* Versioning models, mirroring fields, computing unique model hashes, and the list goes on...\n\nAll of these examples require no overridden methods, no base models, and no signal handling.\n\n## Quick start\n\nInstall `django-pgtrigger` with `pip3 install django-pgtrigger` and add `pgtrigger` to `settings.INSTALLED_APPS`.\n\n`pgtrigger.Trigger` objects are added to `triggers` in model `Meta`. `django-pgtrigger` comes with several trigger classes, such as `pgtrigger.Protect`. In the following, we're protecting the model from being deleted:\n\n```python\nimport pgtrigger\n\nclass ProtectedModel(models.Model):\n    \"\"\"This model cannot be deleted!\"\"\"\n\n    class Meta:\n        triggers = [\n            pgtrigger.Protect(name=\"protect_deletes\", operation=pgtrigger.Delete)\n        ]\n```\n\nWhen migrations are created and executed, `ProtectedModel` will raise an exception anytime a deletion is attempted.\n\nLet's extend this example further and only protect deletions on inactive objects. In this example, the trigger conditionally runs when the row being deleted (the `OLD` row in trigger terminology) is still active:\n\n```python\nimport pgtrigger\n\nclass ProtectedModel(models.Model):\n    \"\"\"Active object cannot be deleted!\"\"\"\n    is_active = models.BooleanField(default=True)\n\n    class Meta:\n        triggers = [\n            pgtrigger.Protect(\n                name=\"protect_deletes\",\n                operation=pgtrigger.Delete,\n                condition=pgtrigger.Q(old__is_active=True)\n            )\n        ]\n```\n\n`django-pgtrigger` uses `pgtrigger.Q` and `pgtrigger.F` objects to conditionally execute triggers based on the `OLD` and `NEW` rows. Combining these Django idioms with `pgtrigger.Trigger` objects can solve a wide variety of problems without ever writing SQL. Users, however, can still use raw SQL for complex cases.\n\nTriggers are installed like other database objects. Run `python manage.py makemigrations` and `python manage.py migrate` to install triggers.\n\nIf triggers are new to you, don't worry. The [pgtrigger docs](https://django-pgtrigger.readthedocs.io/) cover triggers in more detail and provide many examples.\n\n## Compatibility\n\n`django-pgtrigger` is compatible with Python 3.8 - 3.12, Django 3.2 - 5.0, Psycopg 2 - 3, and Postgres 12 - 16.\n\n## Documentation\n\n[View the django-pgtrigger docs here](https://django-pgtrigger.readthedocs.io/) to learn more about:\n\n* Trigger basics and motivation for using triggers.\n* How to use the built-in triggers and how to build custom ones.\n* Installing triggers on third-party models, many-to-many fields, and other advanced scenarios.\n* Writing conditional triggers.\n* Ignoring triggers dynamically and deferring trigger execution.\n* Multiple database, schema, and partitioning support.\n* Frequently asked questions, common issues, and upgrading.\n* The commands, settings, and module.\n\n## Installation\n\nInstall `django-pgtrigger` with:\n\n    pip3 install django-pgtrigger\n\nAfter this, add `pgtrigger` to the `INSTALLED_APPS` setting of your Django project.\n\n## Other Material\n\nAfter you've read the docs, check out [this tutorial](https://wesleykendall.github.io/django-pgtrigger-tutorial/) with interactive examples from a Django meetup talk.\n\nThe [DjangoCon 2021 talk](https://www.youtube.com/watch?v=Tte3d4JjxCk) also breaks down triggers and shows several examples.\n\n## Contributing Guide\n\nFor information on setting up django-pgtrigger for development and contributing changes, view [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Primary Authors\n\n- [Wes Kendall](https://github.com/wesleykendall)\n\n## Other Contributors\n\n- @jzmiller1\n- @rrauenza\n- @ralokt\n- @adamchainz\n- @danifus\n- @kekekekule\n- @peterthomassen\n- @pfouque\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "Postgres trigger support integrated with Django models.",
    "version": "4.11.1",
    "project_urls": {
        "Documentation": "https://django-pgtrigger.readthedocs.io",
        "Homepage": "https://github.com/Opus10/django-pgtrigger",
        "Repository": "https://github.com/Opus10/django-pgtrigger"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "355c7e94a12fd1e0580f814d73e0934ad17b24ce5a9c716d43a1d0689f799e9a",
                "md5": "d532cbc844197d8e1c2ed22ca474c382",
                "sha256": "9ef664932b3b7fb06e6dc091e4e292d029c221804469ff42968dad272076915f"
            },
            "downloads": -1,
            "filename": "django_pgtrigger-4.11.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d532cbc844197d8e1c2ed22ca474c382",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4,>=3.8.0",
            "size": 33242,
            "upload_time": "2024-04-06T16:58:21",
            "upload_time_iso_8601": "2024-04-06T16:58:21.649772Z",
            "url": "https://files.pythonhosted.org/packages/35/5c/7e94a12fd1e0580f814d73e0934ad17b24ce5a9c716d43a1d0689f799e9a/django_pgtrigger-4.11.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ad2e35ec851296e3dbfe58808576099c98d6c22085f56c0ec301ab1e7cfeba72",
                "md5": "fba3f8dc740e26d45d068fe7095731d5",
                "sha256": "39862f229405c6fe49b33451e13910a70578ba569f7e8bea6ea82049058b371f"
            },
            "downloads": -1,
            "filename": "django_pgtrigger-4.11.1.tar.gz",
            "has_sig": false,
            "md5_digest": "fba3f8dc740e26d45d068fe7095731d5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4,>=3.8.0",
            "size": 29899,
            "upload_time": "2024-04-06T16:58:22",
            "upload_time_iso_8601": "2024-04-06T16:58:22.939181Z",
            "url": "https://files.pythonhosted.org/packages/ad/2e/35ec851296e3dbfe58808576099c98d6c22085f56c0ec301ab1e7cfeba72/django_pgtrigger-4.11.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-06 16:58:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Opus10",
    "github_project": "django-pgtrigger",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "circle": true,
    "tox": true,
    "lcname": "django-pgtrigger"
}
        
Elapsed time: 0.24127s