Metadata-Version: 2.4
Name: xdjango-postgres-extra
Version: 2.1.2
Summary: Bringing all of PostgreSQL's awesomeness to Django.
Home-page: https://github.com/SectorLabs/django-postgres-extra
Author: Sector Labs
Author-email: open-source@sectorlabs.ro
License: MIT License
Keywords: django,postgres,extra,hstore,upsert,partioning,materialized,view
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 6.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Django<7.0,>=2.0
Requires-Dist: python-dateutil<=3.0.0,>=2.8.0
Requires-Dist: dataclasses; python_version <= "3.6"
Provides-Extra: dev
Requires-Dist: poethepoet==0.34.0; python_version >= "3.9" and extra == "dev"
Requires-Dist: poethepoet==0.30.0; (python_version >= "3.8" and python_version < "3.9") and extra == "dev"
Requires-Dist: poethepoet==0.19.0; (python_version >= "3.7" and python_version < "3.8") and extra == "dev"
Requires-Dist: poethepoet==0.13.1; (python_version >= "3.6" and python_version < "3.7") and extra == "dev"
Provides-Extra: test
Requires-Dist: psycopg2==2.9.10; python_version >= "3.8" and extra == "test"
Requires-Dist: psycopg2==2.9.9; (python_version >= "3.7" and python_version < "3.8") and extra == "test"
Requires-Dist: psycopg2==2.9.8; (python_version >= "3.6" and python_version < "3.7") and extra == "test"
Requires-Dist: types-psycopg2==2.9.21.20250516; python_version >= "3.9" and extra == "test"
Requires-Dist: types-psycopg2==2.9.8; (python_version >= "3.6" and python_version < "3.9") and extra == "test"
Requires-Dist: pytest==8.4.0; python_version > "3.8" and extra == "test"
Requires-Dist: pytest==7.0.1; python_version <= "3.8" and extra == "test"
Requires-Dist: pytest-benchmark==5.1.0; python_version > "3.8" and extra == "test"
Requires-Dist: pytest-benchmark==3.4.1; python_version <= "3.8" and extra == "test"
Requires-Dist: pytest-django==4.11.1; python_version > "3.7" and extra == "test"
Requires-Dist: pytest-django==4.5.2; python_version <= "3.7" and extra == "test"
Requires-Dist: pytest-cov==6.1.1; python_version > "3.8" and extra == "test"
Requires-Dist: pytest-cov==4.0.0; python_version <= "3.8" and extra == "test"
Requires-Dist: coverage==7.8.2; python_version > "3.8" and extra == "test"
Requires-Dist: coverage==7.6.1; (python_version >= "3.8" and python_version <= "3.8") and extra == "test"
Requires-Dist: coverage==6.2; python_version <= "3.7" and extra == "test"
Requires-Dist: tox==4.26.0; python_version > "3.8" and extra == "test"
Requires-Dist: tox==3.28.0; python_version <= "3.8" and extra == "test"
Requires-Dist: freezegun==1.5.2; python_version > "3.7" and extra == "test"
Requires-Dist: freezegun==1.2.2; python_version <= "3.7" and extra == "test"
Requires-Dist: syrupy==4.9.1; python_version >= "3.9" and extra == "test"
Requires-Dist: syrupy==2.3.1; python_version <= "3.8" and extra == "test"
Provides-Extra: test-report
Requires-Dist: coveralls==4.0.1; extra == "test-report"
Provides-Extra: analysis
Requires-Dist: black==22.3.0; extra == "analysis"
Requires-Dist: flake8==7.2.0; extra == "analysis"
Requires-Dist: autoflake==2.3.1; extra == "analysis"
Requires-Dist: autopep8==2.3.2; extra == "analysis"
Requires-Dist: isort==6.0.1; extra == "analysis"
Requires-Dist: docformatter==1.7.7; extra == "analysis"
Requires-Dist: mypy==1.16.0; extra == "analysis"
Requires-Dist: django-stubs==4.2.7; extra == "analysis"
Requires-Dist: typing-extensions==4.14.0; extra == "analysis"
Requires-Dist: types-dj-database-url==1.3.0.4; extra == "analysis"
Requires-Dist: types-python-dateutil==2.9.0.20250516; extra == "analysis"
Provides-Extra: docs
Requires-Dist: Sphinx==8.2.3; extra == "docs"
Requires-Dist: sphinx-rtd-theme==3.0.2; extra == "docs"
Requires-Dist: docutils==0.21.2; extra == "docs"
Requires-Dist: Jinja2==3.1.6; extra == "docs"
Provides-Extra: publish
Requires-Dist: build<2.0.0,>=1.2.0; extra == "publish"
Requires-Dist: twine<7.0.0,>=6.0.0; extra == "publish"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# xdjango-postgres-extra

[![PyPI version](https://img.shields.io/pypi/v/xdjango-postgres-extra.svg)](https://pypi.org/project/xdjango-postgres-extra/)
[![Python versions](https://img.shields.io/pypi/pyversions/xdjango-postgres-extra.svg)](https://pypi.org/project/xdjango-postgres-extra/)
[![Django 6](https://img.shields.io/badge/Django-6.0-0C4B33.svg)](https://docs.djangoproject.com/en/6.0/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

`xdjango-postgres-extra` is a maintained fork of
[`django-postgres-extra`](https://github.com/SectorLabs/django-postgres-extra).
It extends Django's PostgreSQL backend with features such as atomic upserts,
table partitioning, views, materialized views, schema management, and explicit
table locking.

The PyPI distribution is named `xdjango-postgres-extra`. The Python package
and existing imports remain named `psqlextra`.

## Compatibility

- Django: 2.0 through 6.x (`Django>=2.0,<7.0`)
- Python: 3.6 through 3.14
- PostgreSQL: 11 or newer
- Psycopg: 2 and 3

Django 6 requires Python 3.12 or newer. The 2.1.x release line was verified with
Django 6.0.6 and Python 3.14.

## Installation

```bash
python -m pip install xdjango-postgres-extra
```

Use the `psqlextra` database backend in your Django settings:

```python
DATABASES = {
    "default": {
        "ENGINE": "psqlextra.backend",
        "NAME": "my_database",
        "USER": "my_user",
        "PASSWORD": "my_password",
        "HOST": "localhost",
        "PORT": "5432",
    }
}
```

Add the application when using features that require app registration:

```python
INSTALLED_APPS = [
    # ...
    "django.contrib.postgres",
    "psqlextra",
]
```

Existing application code continues to use `psqlextra` imports:

```python
from psqlextra.models import PostgresModel
```

## Features

- Atomic `INSERT ... ON CONFLICT` handling with `DO UPDATE` and `DO NOTHING`
- Bulk inserts and upserts
- PostgreSQL range, list, hash, and default table partitions
- Time-based partition management
- Database views and materialized views integrated with migrations
- PostgreSQL schema creation, deletion, and temporary schemas
- Explicit model and table locks
- `TRUNCATE TABLE`, including cascading truncation
- HStore constraints and expressions
- PostgreSQL-specific indexes and introspection

The upstream documentation remains the primary API reference:

- [Documentation](https://django-postgres-extra.readthedocs.io/en/master/)
- [Installation guide](https://django-postgres-extra.readthedocs.io/en/master/installation.html)
- [Feature reference](https://django-postgres-extra.readthedocs.io/en/master/index.html#features)

When following upstream installation instructions, install
`xdjango-postgres-extra` instead of `django-postgres-extra`.

## Development

Create a virtual environment and install the development extras:

```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev,test]"
```

Set a PostgreSQL test database URL:

```bash
export DATABASE_URL="postgres://psqlextra:password@localhost/psqlextra"
```

Run the available Poe tasks:

```bash
poe test
poe verify
```

## License

MIT. See [LICENSE](LICENSE).
