{ "info": { "author": "Anentropic", "author_email": "ego@anentropic.com", "bugtrack_url": null, "classifiers": [], "description": "=============================\ndjango-conditional-aggregates\n=============================\n\n|Build Status| |PyPi Version|\n\n|Python2.7|\n\n|Django1.6| |Django1.7|\n\n.. |Build Status| image:: https://travis-ci.org/anentropic/django-conditional-aggregates.svg?branch=master\n :alt: Build Status\n :target: https://travis-ci.org/anentropic/django-conditional-aggregates\n.. |PyPi Version| image:: https://badge.fury.io/py/django-conditional-aggregates.svg\n :alt: Latest PyPI version\n :target: https://pypi.python.org/pypi/django-conditional-aggregates/\n.. |Python2.7| image:: https://img.shields.io/badge/Python%202.7--brightgreen.svg\n :alt: Python 2.7\n.. |Django1.6| image:: https://img.shields.io/badge/Django%201.6--brightgreen.svg\n :alt: Django 1.6\n.. |Django1.7| image:: https://img.shields.io/badge/Django%201.7--brightgreen.svg\n :alt: Django 1.7\n\n\n*(Django 1.4 and 1.5 are not possible due to limitation of older `SQLCompiler` class)*\n\nNote: from Django 1.8 on this module is not needed as support is built-in: \nhttps://docs.djangoproject.com/en/1.8/ref/models/conditional-expressions/#case\n\nSometimes you need some conditional logic to decide which related rows to 'aggregate' in your aggregation function.\n\nIn SQL you can do this with a ``CASE`` clause, for example:\n\n.. code:: sql\n\n SELECT\n stats_stat.campaign_id,\n SUM(\n CASE WHEN (\n stats_stat.stat_type = a\n AND stats_stat.event_type = v\n )\n THEN stats_stat.count\n ELSE 0\n END\n ) AS impressions\n FROM stats_stat\n GROUP BY stats_stat.campaign_id\n\nNote this is different to doing Django's normal ``.filter(...).aggregate(Sum(...))`` ...what we're doing is effectively inside the ``Sum(...)`` part of the ORM.\n\nI believe these 'conditional aggregates' are most (perhaps *only*) useful when doing a ``GROUP BY`` type of query - they allow you to control exactly how the values in the group get aggregated, for example to only sum up rows matching certain criteria.\n\n\nUsage:\n\n``pip install django-conditional-aggregates``\n\n.. code:: python\n\n from django.db.models import Q\n from djconnagg import ConditionalSum\n\n # recreate the SQL example from above in pure Django ORM:\n report = (\n Stat.objects\n .values('campaign_id') # values + annotate => GROUP BY\n .annotate(\n impressions=ConditionalSum(\n 'count',\n when=Q(stat_type='a', event_type='v')\n ),\n )\n )\n\nNote that standard Django ``Q`` objects are used to formulate the ``CASE WHEN(...)`` clause. Just like in the rest of the ORM, you can combine them with ``() | & ~`` operators to make a complex query.\n\n``ConditionalSum`` and ``ConditionalCount`` aggregate functions are provided. There is also a base class if you need to make your own. The implementation of ``ConditionalSum`` is very simple and looks like this:\n\n.. code:: python\n\n from djconnagg.aggregates import ConditionalAggregate, SQLConditionalAggregate\n\n class ConditionalSum(ConditionalAggregate):\n name = 'ConditionalSum'\n\n class SQLClass(SQLConditionalAggregate):\n sql_function = 'SUM'\n default = 0", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/anentropic/django-conditional-aggregates", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "django-conditional-aggregates", "package_url": "https://pypi.org/project/django-conditional-aggregates/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-conditional-aggregates/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/anentropic/django-conditional-aggregates" }, "release_url": "https://pypi.org/project/django-conditional-aggregates/0.5.0/", "requires_dist": null, "requires_python": null, "summary": "Django aggregate functions which operate conditionally (i.e. generate SQL `CASE WHEN` statements)", "version": "0.5.0" }, "last_serial": 1626284, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "be05c5f7fd91e76d51055994dcd13402", "sha256": "b91726879179797f5dfd03c4ce6c1b8418e87cb3ee9c9d79bcb70121d84cba9f" }, "downloads": -1, "filename": "django-conditional-aggregates-0.1.0.tar.gz", "has_sig": false, "md5_digest": "be05c5f7fd91e76d51055994dcd13402", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4264, "upload_time": "2015-02-04T01:13:57", "url": "https://files.pythonhosted.org/packages/39/b8/10bef97c3b49fe29448f765f6245fcca77be69e211cf3a7c54f1f1852cce/django-conditional-aggregates-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "566109d54fa747f7f018418ea57d8fd5", "sha256": "80885348b7d3a97aa1bb045ca21414fb9425eed04a1420f9ddeac85e4042ad45" }, "downloads": -1, "filename": "django-conditional-aggregates-0.2.0.tar.gz", "has_sig": false, "md5_digest": "566109d54fa747f7f018418ea57d8fd5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3861, "upload_time": "2015-02-11T16:09:54", "url": "https://files.pythonhosted.org/packages/07/96/c2735d2137e98c345fe99228cacfc0c62a31b5f94ebac0eba9e7e56c11be/django-conditional-aggregates-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "0a4ed41f22a5e278200d38aaf1306240", "sha256": "7cfb6bae0dedfd06d2bab16f62d04bdf751b0aa26dd5324bafac86b9484b590a" }, "downloads": -1, "filename": "django-conditional-aggregates-0.3.0.tar.gz", "has_sig": false, "md5_digest": "0a4ed41f22a5e278200d38aaf1306240", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6484, "upload_time": "2015-07-08T17:57:32", "url": "https://files.pythonhosted.org/packages/03/7e/1a0bbaf39f916eb715a5294c607ef8715047d0bb827a24cd7d134e74a0ad/django-conditional-aggregates-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "996f065d29d7fa70bab0af394f808021", "sha256": "2a89a430706c985eaf92c1384059bb88201b5925699a9f57032188cce290f26e" }, "downloads": -1, "filename": "django-conditional-aggregates-0.3.1.tar.gz", "has_sig": false, "md5_digest": "996f065d29d7fa70bab0af394f808021", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6543, "upload_time": "2015-07-09T07:12:35", "url": "https://files.pythonhosted.org/packages/64/ce/2864d5e2746b8190d5c05b9a1de2ed0f1deae652a20e744229e4a8dd7987/django-conditional-aggregates-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "b58d887c77a415f1e65d9569b355d92f", "sha256": "e9285cac4bf1cc9e3820f24f7609ed3f1b72e9f26e9ea8e3bf90e5ba522c3699" }, "downloads": -1, "filename": "django-conditional-aggregates-0.3.2.tar.gz", "has_sig": false, "md5_digest": "b58d887c77a415f1e65d9569b355d92f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6757, "upload_time": "2015-07-09T07:13:50", "url": "https://files.pythonhosted.org/packages/a9/62/155d98ec15ee7c13e37240d19b0f2840fe4b42bdfaed7948933f7fa39d04/django-conditional-aggregates-0.3.2.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "d13d9068c29b939e9cc787971406a2d2", "sha256": "ed434799e998bf7e3bc80d2c5245d5c7911f6b6e4b79930fea642beb4cb9e542" }, "downloads": -1, "filename": "django-conditional-aggregates-0.4.0.tar.gz", "has_sig": false, "md5_digest": "d13d9068c29b939e9cc787971406a2d2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6832, "upload_time": "2015-07-09T09:54:51", "url": "https://files.pythonhosted.org/packages/44/7a/9cf8a777d2fdad1b6c87291622eb23ecd019c29b5f90c1557c5c16a08025/django-conditional-aggregates-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "f5a0037f42918cf9221514454e15ce0c", "sha256": "a6e3039a6b337736c765211f61475d0505f431df1f7bbb90bdeb4dd8b92a6570" }, "downloads": -1, "filename": "django-conditional-aggregates-0.5.0.tar.gz", "has_sig": false, "md5_digest": "f5a0037f42918cf9221514454e15ce0c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4392, "upload_time": "2015-07-09T12:54:50", "url": "https://files.pythonhosted.org/packages/0c/cf/1238c821abeb574cdae2da43855ae467fa2b07a2a4fe0cbed15a3f95ff8c/django-conditional-aggregates-0.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f5a0037f42918cf9221514454e15ce0c", "sha256": "a6e3039a6b337736c765211f61475d0505f431df1f7bbb90bdeb4dd8b92a6570" }, "downloads": -1, "filename": "django-conditional-aggregates-0.5.0.tar.gz", "has_sig": false, "md5_digest": "f5a0037f42918cf9221514454e15ce0c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4392, "upload_time": "2015-07-09T12:54:50", "url": "https://files.pythonhosted.org/packages/0c/cf/1238c821abeb574cdae2da43855ae467fa2b07a2a4fe0cbed15a3f95ff8c/django-conditional-aggregates-0.5.0.tar.gz" } ] }