{ "info": { "author": "Mikhail Shvein", "author_email": "work_shvein_mihail@mail.ru", "bugtrack_url": null, "classifiers": [], "description": "# django-pg-returning\nA small library implementing PostgreSQL ability to return rows in DML statements for Django. \n[Link to PostgreSQL docs](https://www.postgresql.org/docs/10/static/sql-update.html)\n\n## Requirements\n* Python 2.7 or Python 3.4+\n* django >= 1.7 \n Previous versions may also work, but haven't been tested. \n bulk_create_returning method doesn't support .only() and .defer() filters for django before 1.10.\n* pytz\n* six\n* typing\n* psycopg2\n* PostgreSQL 9.3+ \n Previous versions may also work, but haven't been tested. \n\n## Installation\nInstall via pip: \n`pip install django-pg-returning` \nor via setup.py: \n`python setup.py install`\n\n## Usage\n\n### Integration\nThe easiest way to integrate, is to inherit your model from `UpdateReturningModel` instead of `django.db.models.Model`.\nIt already has redeclared Manager, supporting returning operations.\n```python\nfrom django.db import models\nfrom django_pg_returning import UpdateReturningModel\n\nclass MyModel(UpdateReturningModel): \n field = models.IntegerField()\n```\n\nIf you already have custom manager, you can implement `get_queryset()` method in it:\n```python\nfrom django.db import models\nfrom django_pg_returning import UpdateReturningQuerySet, UpdateReturningModel\n\nclass MyManager(models.Manager):\n def get_queryset(self):\n return UpdateReturningQuerySet(using=self.db, model=self.model)\n\nclass MyModel(UpdateReturningModel):\n objects = MyManager()\n\n field = models.IntegerField()\n```\n\nAnd if you have custom manager you can use a mixin:\n```python\nfrom django.db import models\nfrom django_pg_returning import UpdateReturningMixin, UpdateReturningModel\n\nclass MyQuerySet(models.QuerySet, UpdateReturningMixin):\n pass\n\nclass MyManager(models.Manager):\n def get_queryset(self):\n return MyQuerySet(using=self.db, model=self.model)\n\nclass MyModel(UpdateReturningModel):\n objects = MyManager()\n\n field = models.IntegerField()\n```\n\n### Methods\n#### QuerySet methods\nAfter QuerySet mixin is integrated with your model, your QuerySet-s will have 3 additional methods:\n```python\n# Any django queryset you like\nqs = MyModel.objects.all()\n\n# Update and return a ReturningQuerySet, described below\nresult = qs.update_returning(field=1)\n\n# Delete data and return a ReturningQuerySet, described below\nresult = qs.delete_returning()\n\n# Acts like django's QuerySet.bulk_create() method, but updates all model fields stored in database\n# Can be used to retrieve values, saved by database default/triggers etc.\nresult = MyModel.objects.bulk_create_returning([MyModel(field=1)])\n```\nBy default methods get all fields, fetched by the model. \nTo limit fields returned, you can use standard \n[QuerySet.only()](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.only) \nand \n[QuerySet.defer()](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#defer) methods.\nbulk_create_returning doesn't support this methods for django before 1.10.\n\n#### Model methods\nIf model instance is created, basic `save()` method is called. \nIf model is updated, database record is updated, and saved fields are refreshed with database values.\nThis may be useful, if you update fields with [F() expressions](https://docs.djangoproject.com/en/2.1/ref/models/expressions/#f-expressions).\nBy default all fields are saved and refreshed. \nUse [update_fields](https://docs.djangoproject.com/en/2.1/ref/models/instances/#specifying-which-fields-to-save) to specify concrete fields to save and refresh.\n```python\ninstance = MyModel.objects.create(pk=1, field=1)\ninstance.field = F('field') + 1\n\n# Basic save method will not change field and you don't know, what value is in database\ninstance.save()\nprint(instance.field)\n# Output: F('field') + Value(1)\n\n# Library method gives ability to fetch updated result \ninstance.save_returning()\nprint(instance.field)\n# Output: 2\n```\n\n*Important notes*:\n1) If you don't fetch field, and then try to get it, \nlibrary acts as django does - makes extra database query to fetch attribute deferred. \n2) These queries are not lazy, as well as basic \n[QuerySet.update()](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#update) \nand \n[QuerySet.delete()](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#delete) \nmethods. \n3) Primary key field is fetched not looking at limiting methods, as django needs it to form a QuerySet\n\n### ReturningQuerySet\nThe result of returning functions is django_pg_returning.ReturningQuerySet. \nIt is based on django's RawQuerySet, but adds some extra methods to be used easier.\nThe main difference is that *ReturningQuerySet caches query results*,\n while RawQuerySet executes query each time it is iterated.\nAll ReturningQuerySet methods are not executed on database side, they are executed in python on cached result.\nThe only way, ReturningQuerySet makes extra database query - is deferred field loading, described above.\nImplemented methods:\n```python\n# UPDATE ... RETURNING query is executed here once. The result is cached.\nresult = MyModel.objects.all().update_returning(field=1)\n\n# Get number of values fetched\nprint(result.count(), len(result))\n# Output: 1, 1\n\n# Index and slicing. Note that the order of result is not guaranteed by the database.\nprint(result[1], result[0:2])\n# Output: MyModel(...), [MyModel(...), MyModel(...), MyModel(...)]\n\n# Sintax sugar for indexing\nprint(result.first(), result.last())\n# Output: MyModel(...), MyModel(...)\n\n# Fetching values and values_list. Both methods use cache and return lists, not ValuesQuerySet like django does.\n# values() method cakked without fields will return all fields, fetched in returning method.\n# values_list() method called without fields will raise exception, as order or fields in result tuple is not obvious.\n\nprint(result.values())\n# Output: [{'id': 1, 'field': 1}, {'id': 2, 'field': 2}]\n\nprint(result.values('field'))\n# Output: [{'field': 1}, {'field': 2}]\n\nprint(result.values_list('field', flat=True))\n# Output: [1, 2]\n\nprint(result.values_list('field', 'id', named=True))\n# Output: [Row(field=1, id=1), Row(field=2, id=2)]\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/M1hacka/django-pg-returning", "keywords": "", "license": "BSD 3-clause \"New\" or \"Revised\" License", "maintainer": "", "maintainer_email": "", "name": "django-pg-returning", "package_url": "https://pypi.org/project/django-pg-returning/", "platform": "", "project_url": "https://pypi.org/project/django-pg-returning/", "project_urls": { "Homepage": "https://github.com/M1hacka/django-pg-returning" }, "release_url": "https://pypi.org/project/django-pg-returning/1.2.2/", "requires_dist": null, "requires_python": "", "summary": "A small library implementing PostgreSQL ability to return rows in DML statements for Django", "version": "1.2.2" }, "last_serial": 5904903, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "de142df86a3ea019f01642a6e2b90857", "sha256": "dc9c195264b9e6e9d2df0a6c10fb17306dc9a6c31ea9a090a5460e657c00eb8d" }, "downloads": -1, "filename": "django_pg_returning-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "de142df86a3ea019f01642a6e2b90857", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 4671, "upload_time": "2018-06-01T17:38:33", "url": "https://files.pythonhosted.org/packages/02/26/b5c828ecf0f5d399a28765ccf117e23ccd16e8978ea906d6543ce78507f9/django_pg_returning-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "50c459a83d348d2819fb80861d9d04b2", "sha256": "a4a241c49e5718fc74cc0c17f7b7a0fb0d6a6b2b31c4e45d7b42a1cef1c58cbb" }, "downloads": -1, "filename": "django-pg-returning-1.0.0.tar.gz", "has_sig": false, "md5_digest": "50c459a83d348d2819fb80861d9d04b2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5109, "upload_time": "2018-06-01T17:38:35", "url": "https://files.pythonhosted.org/packages/a4/a8/7da18c4ee022b81da3e1a744234dc1a4886ed987f7a3aaea624478adb5fc/django-pg-returning-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "80d13e00053b1e3eb717d887ed815adb", "sha256": "157fcdcb1290b7175bb7136278d808683bad37417c82607eaf8d92c0bab361e4" }, "downloads": -1, "filename": "django_pg_returning-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "80d13e00053b1e3eb717d887ed815adb", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6239, "upload_time": "2018-06-16T08:37:33", "url": "https://files.pythonhosted.org/packages/e2/24/833d5f7bf5ada7c485f5afc67c56a6924ef7f1082b8af00b868c8967cd4b/django_pg_returning-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c84bc17b53f77410960e7e2249dab395", "sha256": "7f60d7054d6cbfe7757c7c0f0da1236bf7335702f119f724693f5e94a75b7736" }, "downloads": -1, "filename": "django-pg-returning-1.0.1.tar.gz", "has_sig": false, "md5_digest": "c84bc17b53f77410960e7e2249dab395", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5649, "upload_time": "2018-06-16T08:37:34", "url": "https://files.pythonhosted.org/packages/d1/ea/2a8b98c665b9913edd0b7594183e5fbf6f26ee32592eb9c1bf53fcf6e0b4/django-pg-returning-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "14dab360d1d7fb85a8615756b1ab015f", "sha256": "676e15fd3b871f21ba9fd1ffadd792ac69eb9eda173eeaadd28c570fcf615466" }, "downloads": -1, "filename": "django_pg_returning-1.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "14dab360d1d7fb85a8615756b1ab015f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6396, "upload_time": "2018-10-28T10:51:34", "url": "https://files.pythonhosted.org/packages/e5/14/9649bb37191b30f9fa56d34993fda375d3dd09330c89d1c1e5a51a20d2e1/django_pg_returning-1.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dc8cdcf4614f08dfb9cac20a77ebd038", "sha256": "dfb5a0627ec9f59a281845cda8f841f28e4bdf27c48d3e6c815fabf37f405578" }, "downloads": -1, "filename": "django-pg-returning-1.0.2.tar.gz", "has_sig": false, "md5_digest": "dc8cdcf4614f08dfb9cac20a77ebd038", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5818, "upload_time": "2018-10-28T10:51:36", "url": "https://files.pythonhosted.org/packages/87/a8/7f1cda500446a6183d485e6bc6d4c3f3c4eea0f2e18dbe63d3cf6380987b/django-pg-returning-1.0.2.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "9c9663ac3f1a7e7e5201848eefa4605b", "sha256": "f59851316a182e562671e70dfeaffba9838ba94092b1bad2260dc0be007493a5" }, "downloads": -1, "filename": "django_pg_returning-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9c9663ac3f1a7e7e5201848eefa4605b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9225, "upload_time": "2019-02-10T05:26:17", "url": "https://files.pythonhosted.org/packages/19/49/fa8bd3afdc494bb4220b1e459ad95106eef1373a2875249624f70ee319a7/django_pg_returning-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e74ce5b23b680eb7cd17591e25c7c468", "sha256": "1ef46c1343887f75ad5f1384a69e51adbefde5c38b83dea6400320b0e92831f9" }, "downloads": -1, "filename": "django_pg_returning-1.1.0-py3.6.egg", "has_sig": false, "md5_digest": "e74ce5b23b680eb7cd17591e25c7c468", "packagetype": "bdist_egg", "python_version": "3.6", "requires_python": null, "size": 17234, "upload_time": "2019-06-02T03:38:43", "url": "https://files.pythonhosted.org/packages/2e/c7/b05c82625805f8345498397c58d138ca79f7c8eef066cdf97113fdff2198/django_pg_returning-1.1.0-py3.6.egg" }, { "comment_text": "", "digests": { "md5": "e83019fe66743bfc66c3661a08b36e5a", "sha256": "92ceb3e9c2f49ec3dfac0a44319aa40c172f67924df719980e03c0b68d4a126e" }, "downloads": -1, "filename": "django-pg-returning-1.1.0.tar.gz", "has_sig": false, "md5_digest": "e83019fe66743bfc66c3661a08b36e5a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8710, "upload_time": "2019-02-10T05:26:19", "url": "https://files.pythonhosted.org/packages/be/39/c2c19d5c57ebf37759f2d980887dca88201a2bd68fac6021c2241a698734/django-pg-returning-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "b93720dbbe3dbce27305993e79036325", "sha256": "5dd7cbe0511ba0c8ea0e989495116fddfb0f6b869d349fec6d29e84486a51bfc" }, "downloads": -1, "filename": "django_pg_returning-1.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b93720dbbe3dbce27305993e79036325", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10607, "upload_time": "2019-06-02T03:38:40", "url": "https://files.pythonhosted.org/packages/c1/de/4b58e0569ab225ae0841c48f534542a5e63fbe5764bca3fabaf11b208069/django_pg_returning-1.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "570f6f3cef8771bf5e115209f6b05866", "sha256": "28aebb26e5a07fd6e86d21aea3b6ab52545e5f7b8498f35907650e082d7dfa93" }, "downloads": -1, "filename": "django-pg-returning-1.1.1.tar.gz", "has_sig": false, "md5_digest": "570f6f3cef8771bf5e115209f6b05866", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9888, "upload_time": "2019-06-02T03:38:45", "url": "https://files.pythonhosted.org/packages/a8/2d/0e7f94cb44f191c6d92dcf7641b5661b7a7337ed9892f7844c15664fbfc8/django-pg-returning-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "eb792b901edba2d4d0c8654914f31038", "sha256": "506fad15a92351258c69f0ea64e6be0b5407b4f600d5e722988587fcf5ccc87b" }, "downloads": -1, "filename": "django_pg_returning-1.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "eb792b901edba2d4d0c8654914f31038", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11764, "upload_time": "2019-06-08T14:33:05", "url": "https://files.pythonhosted.org/packages/bb/63/c6e360c37e0c44518497d005907d554230e11ace9e8be87481386aefca70/django_pg_returning-1.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1fe4cfb73ad5b8a428d0ccad23b04c4b", "sha256": "718d6e91075364bfe4fb4a0cefd8b9c4d37f8add0fc073dbebf5934176767847" }, "downloads": -1, "filename": "django-pg-returning-1.2.0.tar.gz", "has_sig": false, "md5_digest": "1fe4cfb73ad5b8a428d0ccad23b04c4b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11424, "upload_time": "2019-06-08T14:33:08", "url": "https://files.pythonhosted.org/packages/5e/32/762172c177ffb72f328fbb03917d50e8ffc89f01d15693cbb3e31e34526f/django-pg-returning-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "0de360853fe23422df9b2784478d0c6a", "sha256": "f41aebece787131d0a18b243f21689c9e683ad1ad6b657c1f63c5283dce16043" }, "downloads": -1, "filename": "django_pg_returning-1.2.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0de360853fe23422df9b2784478d0c6a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11812, "upload_time": "2019-06-09T16:38:07", "url": "https://files.pythonhosted.org/packages/88/1c/5b9526749ff7ece272c4e3b0b31876afd34a87c21af054525707145ae8fc/django_pg_returning-1.2.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "499bc39ad9e62fc789b06252d0acb617", "sha256": "cd063bf56471136a8c89e9e2f46141de77db8d48189a2d6ddec51f566c3986e3" }, "downloads": -1, "filename": "django-pg-returning-1.2.1.tar.gz", "has_sig": false, "md5_digest": "499bc39ad9e62fc789b06252d0acb617", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11459, "upload_time": "2019-06-09T16:38:10", "url": "https://files.pythonhosted.org/packages/3b/3c/bc2f7f990984b26327fa25c91d2a07b0de3e308942b2f691d0dd67b50508/django-pg-returning-1.2.1.tar.gz" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "66d7ed47c74e4ebdea8cf08d16d613a8", "sha256": "2f5fb9f85d1fbbb65640cd17394550cd7287783576547494f15f47729ed5b294" }, "downloads": -1, "filename": "django_pg_returning-1.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "66d7ed47c74e4ebdea8cf08d16d613a8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11820, "upload_time": "2019-09-30T05:19:40", "url": "https://files.pythonhosted.org/packages/1e/a2/0a103622f9488571ea3f2116ad0f389906c22d457898f3a5c47fe5b375d8/django_pg_returning-1.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9314f891c82f299db7746e43ab6dd6fa", "sha256": "e3b1a8a956413e841e552e9149b52a1501fb2795bcb737eee2e6e083a3fbb913" }, "downloads": -1, "filename": "django-pg-returning-1.2.2.tar.gz", "has_sig": false, "md5_digest": "9314f891c82f299db7746e43ab6dd6fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11428, "upload_time": "2019-09-30T05:19:44", "url": "https://files.pythonhosted.org/packages/1b/e4/e61e365e7f4c4ba4f4e5adf29d80474cb2ce2c19991db95df5d3f57c782c/django-pg-returning-1.2.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "66d7ed47c74e4ebdea8cf08d16d613a8", "sha256": "2f5fb9f85d1fbbb65640cd17394550cd7287783576547494f15f47729ed5b294" }, "downloads": -1, "filename": "django_pg_returning-1.2.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "66d7ed47c74e4ebdea8cf08d16d613a8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11820, "upload_time": "2019-09-30T05:19:40", "url": "https://files.pythonhosted.org/packages/1e/a2/0a103622f9488571ea3f2116ad0f389906c22d457898f3a5c47fe5b375d8/django_pg_returning-1.2.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9314f891c82f299db7746e43ab6dd6fa", "sha256": "e3b1a8a956413e841e552e9149b52a1501fb2795bcb737eee2e6e083a3fbb913" }, "downloads": -1, "filename": "django-pg-returning-1.2.2.tar.gz", "has_sig": false, "md5_digest": "9314f891c82f299db7746e43ab6dd6fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11428, "upload_time": "2019-09-30T05:19:44", "url": "https://files.pythonhosted.org/packages/1b/e4/e61e365e7f4c4ba4f4e5adf29d80474cb2ce2c19991db95df5d3f57c782c/django-pg-returning-1.2.2.tar.gz" } ] }