{ "info": { "author": "GoPythonGo.com", "author_email": "info@gopythongo.com, scottb@opennetworking.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: BSD License", "Operating System :: POSIX" ], "description": "Django Database Connection Autoreconnect\n========================================\n\n.. image:: https://coveralls.io/repos/github/jdelic/django-dbconn-retry/badge.svg?branch=HEAD\n :target: https://coveralls.io/github/jdelic/django-dbconn-retry?branch=HEAD\n\n.. image:: https://travis-ci.org/jdelic/django-dbconn-retry.svg?branch=master\n :target: https://travis-ci.org/jdelic/django-dbconn-retry\n\nThis library monkeypatches ``django.db.backends.base.BaseDatabaseWrapper`` so\nthat when a database operation fails because the underlying TCP connection was\nalready closed, it first tried to reconnect, instead of immediately raising\nan ``OperationException``.\n\n\nWhy is this useful?\n-------------------\nI use `HAProxy`_ as a load-balancer in front of my PostgreSQL databases all\nthe time, sometimes in addition to ``pgbouncer``. Even though you can mostly\nprevent surprises by enabling TCP keep-alive packets through `tcpka`_,\n`clitcpka`_ and `srvtcpka`_, I still encounter situations where the\nunderlying TCP connection has been closed through the load-balancer. Most often\nthis results in\n\n.. code-block::\n\n django.db.utils.OperationalError: server closed the connection unexpectedly\n This probably means the server terminated abnormally before or while\n processing the request.\n\nThis library patches Django such that it try to reconnect once before failing.\n\nAnother application of this is when using `Hashicorp Vault`_, where\ncredentials for a database connection can expire at any time and then need to\nbe refreshed from Vault.\n\n\nHow to install?\n---------------\nJust pull the library in using ``pip install django-dbconn-retry``. Then add\n``django_dbconn_retry`` to ``INSTALLED_APPS`` in your ``settings.py``.\n\n\nSettings\n---------------\n\nDATABASES = {\n 'default': {\n ...\n 'MAX_RETRIES': 2, #\n 'RETRY_DELAY': .500, # in seconds\n }\n}\n\n\nSignals\n-------\nThe library provides an interface for other code to plug into the process to,\nfor example, allow `12factor-vault`_ to refresh the database credentials\nbefore the code tries to reestablish the database connection. These are\nimplemented using `Django Signals`_.\n\n=========================== ==================================================\nSignal Description\n=========================== ==================================================\n``pre_reconnect`` Installs a hook of the type\n ``Callable[[type, BaseDatabaseWrapper], None]``\n that will be called before the library tries to\n reestablish a connection. 12factor-vault uses this\n to refresh the database credentials from Vault.\n``post_reconnect`` Installs a hook of the type\n ``Callable[[type, BaseDatabaseWrapper], None]``\n that will be called after the library tried to\n reestablish the connection. Success or failure has\n not been tested at this point. So the connection\n may be in any state.\n=========================== ==================================================\n\n\nLicense\n=======\n\nCopyright (c) 2018, Jonas Maurus\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\n may be used to endorse or promote products derived from this software\n without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n.. _12factor-vault: https://github.com/jdelic/12factor-vault/\n.. _Django Signals: https://docs.djangoproject.com/en/dev/topics/signals/\n.. _HAProxy: http://www.haproxy.org/\n.. _tcpka:\n https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#option%20tcpka\n.. _clitcpka:\n https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-option%20clitcpka\n.. _srvtcpka:\n https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#option%20srvtcpka\n.. _Hashicorp Vault: https://vaultproject.io/\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/jdelic/django-dbconn-retry/", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "django-dbconn-retry-python27", "package_url": "https://pypi.org/project/django-dbconn-retry-python27/", "platform": "", "project_url": "https://pypi.org/project/django-dbconn-retry-python27/", "project_urls": { "Homepage": "https://github.com/jdelic/django-dbconn-retry/" }, "release_url": "https://pypi.org/project/django-dbconn-retry-python27/0.1.6/", "requires_dist": null, "requires_python": "", "summary": "Patch Django to retry a database connection first before failing.", "version": "0.1.6" }, "last_serial": 4034306, "releases": { "0.1.6": [ { "comment_text": "", "digests": { "md5": "187c100088894d57b98e60db0344435f", "sha256": "e5356070e98dd1f547dc858a22dd7959cd63cebd22fe3e14b95e768e797bd44f" }, "downloads": -1, "filename": "django-dbconn-retry-python27-0.1.6.tar.gz", "has_sig": false, "md5_digest": "187c100088894d57b98e60db0344435f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7734, "upload_time": "2018-07-05T19:58:39", "url": "https://files.pythonhosted.org/packages/91/4b/38570cd9cbdd4e2d2f73647f3f8ca8dbfa028c60656765599e7a3af2414e/django-dbconn-retry-python27-0.1.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "187c100088894d57b98e60db0344435f", "sha256": "e5356070e98dd1f547dc858a22dd7959cd63cebd22fe3e14b95e768e797bd44f" }, "downloads": -1, "filename": "django-dbconn-retry-python27-0.1.6.tar.gz", "has_sig": false, "md5_digest": "187c100088894d57b98e60db0344435f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7734, "upload_time": "2018-07-05T19:58:39", "url": "https://files.pythonhosted.org/packages/91/4b/38570cd9cbdd4e2d2f73647f3f8ca8dbfa028c60656765599e7a3af2414e/django-dbconn-retry-python27-0.1.6.tar.gz" } ] }