# django-pgbulk
`django-pgbulk` provides functions for doing native Postgres bulk upserts (i.e. [UPDATE ON CONFLICT](https://www.postgresql.org/docs/current/sql-insert.html)), bulk updates, and [COPY FROM](https://www.postgresql.org/docs/current/sql-copy.html).
Bulk upserts can distinguish between updated/created rows and ignore unchanged updates.
Bulk updates are true bulk updates, unlike Django's [bulk_update](https://docs.djangoproject.com/en/4.2/ref/models/querysets/#bulk-update) which can still suffer from *O(N)* queries and can create poor locking scenarios.
Bulk copies can significantly speed-up bulk inserts, sometimes by an order of magnitude over Django's `bulk_create`.
## Quick Start
### Examples
#### Update or insert rows
```python
import pgbulk
pgbulk.upsert(
MyModel,
[
MyModel(int_field=1, some_attr="some_val1"),
MyModel(int_field=2, some_attr="some_val2"),
],
# These are the fields that identify the uniqueness constraint.
["int_field"],
# These are the fields that will be updated if the row already
# exists. If not provided, all fields will be updated
["some_attr"]
)
```
#### Bulk update rows
```python
import pgbulk
pgbulk.update(
MyModel,
[
MyModel(id=1, some_attr='some_val1'),
MyModel(id=2, some_attr='some_val2')
],
# These are the fields that will be updated. If not provided,
# all fields will be updated
['some_attr']
)
```
#### Copy rows into a table
```python
import pgbulk
pgbulk.copy(
MyModel,
# Insert these rows using COPY FROM
[
MyModel(id=1, some_attr='some_val1'),
MyModel(id=2, some_attr='some_val2')
],
)
```
### Advanced Features
Here are some advanced features at a glance:
- `pgbulk.upsert` can categorize which rows were inserted or updated.
- `pgbulk.upsert` and `pgbulk.update` can ignore updating unchanged fields.
- `pgbulk.upsert` and `pgbulk.update` can use expressions in updates.
## Documentation
[View the django-pgbulk docs here](https://django-pgbulk.readthedocs.io/) for more examples.
## Compatibility
`django-pgbulk` is compatible with Python 3.9 - 3.13, Django 4.2 - 5.1, Psycopg 2 - 3, and Postgres 13 - 17.
## Installation
Install `django-pgbulk` with:
pip3 install django-pgbulk
## Contributing Guide
For information on setting up django-pgbulk for development and contributing changes, view [CONTRIBUTING.md](CONTRIBUTING.md).
## Creators
- [Wes Kendall](https://github.com/wesleykendall)
## Other Contributors
- @max-muoto
- @dalberto
Raw data
{
"_id": null,
"home_page": "https://github.com/AmbitionEng/django-pgbulk",
"name": "django-pgbulk",
"maintainer": null,
"docs_url": null,
"requires_python": "<4,>=3.9.0",
"maintainer_email": null,
"keywords": null,
"author": "Wes Kendall",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/cf/ed/085e8a7c1bc5713219471cc0b8a06dddff5558c584c67962b3f80b310865/django_pgbulk-3.2.2.tar.gz",
"platform": null,
"description": "# django-pgbulk\n\n`django-pgbulk` provides functions for doing native Postgres bulk upserts (i.e. [UPDATE ON CONFLICT](https://www.postgresql.org/docs/current/sql-insert.html)), bulk updates, and [COPY FROM](https://www.postgresql.org/docs/current/sql-copy.html).\n\nBulk upserts can distinguish between updated/created rows and ignore unchanged updates.\n\nBulk updates are true bulk updates, unlike Django's [bulk_update](https://docs.djangoproject.com/en/4.2/ref/models/querysets/#bulk-update) which can still suffer from *O(N)* queries and can create poor locking scenarios.\n\nBulk copies can significantly speed-up bulk inserts, sometimes by an order of magnitude over Django's `bulk_create`.\n\n## Quick Start\n\n### Examples\n\n#### Update or insert rows\n\n```python\nimport pgbulk\n\npgbulk.upsert(\n MyModel,\n [\n MyModel(int_field=1, some_attr=\"some_val1\"),\n MyModel(int_field=2, some_attr=\"some_val2\"),\n ],\n # These are the fields that identify the uniqueness constraint.\n [\"int_field\"],\n # These are the fields that will be updated if the row already\n # exists. If not provided, all fields will be updated\n [\"some_attr\"]\n)\n```\n\n#### Bulk update rows\n\n```python\nimport pgbulk\n\npgbulk.update(\n MyModel,\n [\n MyModel(id=1, some_attr='some_val1'),\n MyModel(id=2, some_attr='some_val2')\n ],\n # These are the fields that will be updated. If not provided,\n # all fields will be updated\n ['some_attr']\n)\n```\n\n#### Copy rows into a table\n\n```python\nimport pgbulk\n\npgbulk.copy(\n MyModel,\n # Insert these rows using COPY FROM\n [\n MyModel(id=1, some_attr='some_val1'),\n MyModel(id=2, some_attr='some_val2')\n ],\n)\n```\n\n### Advanced Features\n\nHere are some advanced features at a glance:\n\n- `pgbulk.upsert` can categorize which rows were inserted or updated.\n- `pgbulk.upsert` and `pgbulk.update` can ignore updating unchanged fields.\n- `pgbulk.upsert` and `pgbulk.update` can use expressions in updates.\n\n## Documentation\n\n[View the django-pgbulk docs here](https://django-pgbulk.readthedocs.io/) for more examples.\n\n## Compatibility\n\n`django-pgbulk` is compatible with Python 3.9 - 3.13, Django 4.2 - 5.1, Psycopg 2 - 3, and Postgres 13 - 17.\n\n## Installation\n\nInstall `django-pgbulk` with:\n\n pip3 install django-pgbulk\n\n## Contributing Guide\n\nFor information on setting up django-pgbulk for development and contributing changes, view [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Creators\n\n- [Wes Kendall](https://github.com/wesleykendall)\n\n## Other Contributors\n\n- @max-muoto\n- @dalberto\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "Native Postgres update, upsert, and copy operations.",
"version": "3.2.2",
"project_urls": {
"Documentation": "https://django-pgbulk.readthedocs.io",
"Homepage": "https://github.com/AmbitionEng/django-pgbulk",
"Repository": "https://github.com/AmbitionEng/django-pgbulk"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f357ec9bd9faa121fbfcd8bbbed3b6a4e9e14725ba6e11c3c7eca27a85b37792",
"md5": "255c7c8f187ebe3bd65f4662d7231633",
"sha256": "73a66f4436da70af98daa3ee2de4ebb9acfa050c392681ed053055180784d595"
},
"downloads": -1,
"filename": "django_pgbulk-3.2.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "255c7c8f187ebe3bd65f4662d7231633",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4,>=3.9.0",
"size": 11286,
"upload_time": "2025-01-02T22:27:12",
"upload_time_iso_8601": "2025-01-02T22:27:12.709347Z",
"url": "https://files.pythonhosted.org/packages/f3/57/ec9bd9faa121fbfcd8bbbed3b6a4e9e14725ba6e11c3c7eca27a85b37792/django_pgbulk-3.2.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "cfed085e8a7c1bc5713219471cc0b8a06dddff5558c584c67962b3f80b310865",
"md5": "a18bb83feeb7321482ecb0f0d12c6124",
"sha256": "bdc97cedba1a02734c9609cdf80296a1022ce9a6a497d4e8f3b25170768d945e"
},
"downloads": -1,
"filename": "django_pgbulk-3.2.2.tar.gz",
"has_sig": false,
"md5_digest": "a18bb83feeb7321482ecb0f0d12c6124",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4,>=3.9.0",
"size": 11943,
"upload_time": "2025-01-02T22:27:13",
"upload_time_iso_8601": "2025-01-02T22:27:13.688248Z",
"url": "https://files.pythonhosted.org/packages/cf/ed/085e8a7c1bc5713219471cc0b8a06dddff5558c584c67962b3f80b310865/django_pgbulk-3.2.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-02 22:27:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AmbitionEng",
"github_project": "django-pgbulk",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"circle": true,
"tox": true,
"lcname": "django-pgbulk"
}