{ "info": { "author": "Peter Demin", "author_email": "peterdemin@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": ".. image:: https://img.shields.io/pypi/v/flask_replicated.svg\n :target: https://pypi.python.org/pypi/flask_replicated\n\nSUMMARY\n-------\n\nFlask replicated is a Flask extension, designed to work with\nSqlAlchemy. It's purpose it to provide more or less automatic\nmaster-slave replication. On each request, extension determines database\nusage intention (to read or to write into a database). Then, it picks\nright database url inside overriden ``db.get_engine()`` whenever request\nhandler tries to access database.\n\nINSTALLATION\n------------\n\n1. Install flask replicated distribution using ``pip install flask_replicated``.\n\n2. In flask ``app.config`` configure your database bindings a standard way::\n\n SQLALCHEMY_DATABASE_URI = '%(schema)s://%(user)s:%(password)s@%(master_host)s/%(database)s'\n SQLALCHEMY_BINDS = {\n 'master': SQLALCHEMY_DATABASE_URI,\n 'slave': '%(schema)s://%(user)s:%(password)s@%(slave_host)s/%(database)s'\n }\n\n3. Register app extension::\n\n app = Flask(...)\n ...\n FlaskReplicated(app)\n\nUSAGE\n-----\n\nFlask replicated routes SQL queries into different databases based on\nrequest method. If method is one of ``READONLY_METHODS`` which are defined\nas set(['GET', 'HEAD'])\n\nWhile this is usually enough there are cases when DB access is not\ncontrolled explicitly by your business logic. Good examples are implicit\ncreation of sessions on first access, writing some bookkeeping info,\nimplicit registration of a user account somewhere inside the system.\nThese things can happen at arbitrary moments of time, including during\nGET requests.\n\nTo handle these situations wrap appropriate view function with\n``@flask_replicated.changes_database`` decorator. It will mark function to\nalways use master database url.\n\nConversely, wrap the view function with the ``@use_slave_database``\ndecorator if you want to ensure that it always uses the slave replica.\n\nGET after POST\n~~~~~~~~~~~~~~\n\nThere is a special case that needs addressing when working with\nasynchronous replication scheme. Replicas can lag behind a master\ndatabase on receiving updates. In practice this mean that after\nsubmitting a POST form that redirects to a page with updated data this\npage may be requested from a slave replica that wasn't updated yet. And\nthe user will have an impression that the submit didn't work.\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/peterdemin/python-flask-replicated", "keywords": "flask sqlalchemy replication master slave", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "flask_replicated", "package_url": "https://pypi.org/project/flask_replicated/", "platform": "", "project_url": "https://pypi.org/project/flask_replicated/", "project_urls": { "Homepage": "https://github.com/peterdemin/python-flask-replicated" }, "release_url": "https://pypi.org/project/flask_replicated/1.3/", "requires_dist": null, "requires_python": "", "summary": "Flask SqlAlchemy router for stateful master-slave replication", "version": "1.3" }, "last_serial": 5340108, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "91ceadb2fc77798a28ee75b144459e40", "sha256": "6626aa583e4375f01076b2d5ec2b46e1081c605cc7f8368530a7e9337975e5ec" }, "downloads": -1, "filename": "flask_replicated-1.0.tar.gz", "has_sig": false, "md5_digest": "91ceadb2fc77798a28ee75b144459e40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2356, "upload_time": "2015-05-06T09:47:59", "url": "https://files.pythonhosted.org/packages/ae/ed/9863a7307b1eaeb50e2a9e96577b001afd040658f0c62812424c27614483/flask_replicated-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "e70ef5d5becd5a49721065010d5ff86b", "sha256": "e08700f5ad02dfeae07797c3c1dbba2365a286660ff93d1e10cde5e2348edb09" }, "downloads": -1, "filename": "flask_replicated-1.1.tar.gz", "has_sig": false, "md5_digest": "e70ef5d5becd5a49721065010d5ff86b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2578, "upload_time": "2016-04-27T21:10:43", "url": "https://files.pythonhosted.org/packages/9e/7e/9c9b7d6638c05db5dab8414baee67cd30ced08b5b96ffebfefa01b49b3bf/flask_replicated-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "0c3a0b7b40330c70cc8bf1160d04b03c", "sha256": "4682ae43b597246b3db2066c394c05f4f8371614dd88871b1d25068bd6a0fa72" }, "downloads": -1, "filename": "flask_replicated-1.2-py2-none-any.whl", "has_sig": false, "md5_digest": "0c3a0b7b40330c70cc8bf1160d04b03c", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 5026, "upload_time": "2017-03-31T17:07:17", "url": "https://files.pythonhosted.org/packages/a1/f1/5556d3340731c477b5a949b83460dfbd058fbe7699ee829ec364d5242f26/flask_replicated-1.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c528e704aee1f283b0ef9ee2246df2a8", "sha256": "cfb6f7244b1b0b499b670307073d99d75a9824417c36fb2c629cc8f5605ef2da" }, "downloads": -1, "filename": "flask_replicated-1.2.tar.gz", "has_sig": false, "md5_digest": "c528e704aee1f283b0ef9ee2246df2a8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2876, "upload_time": "2017-03-31T17:07:15", "url": "https://files.pythonhosted.org/packages/8c/78/12ceaabc22613cecbef6356700c18a2491f0be3fb16ded385c866f03e32e/flask_replicated-1.2.tar.gz" } ], "1.3": [ { "comment_text": "", "digests": { "md5": "da031e0a54b2a40400c20dc10ab298a8", "sha256": "877d278b45d6de39189c6d076b71452d6d176e0d823c3f922922ba793546d36e" }, "downloads": -1, "filename": "flask_replicated-1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "da031e0a54b2a40400c20dc10ab298a8", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 3203, "upload_time": "2019-05-30T23:13:36", "url": "https://files.pythonhosted.org/packages/87/77/ccdfdf47da52f46c7f1373f11d36ad677ffccafdf511fa1b01f4b32b4cc6/flask_replicated-1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "53e2eb0731aa950b647d997c64cdae14", "sha256": "ccbfc1fadd9c06a9a7b69fa55c3a998b1deab702f8602250ea64fe3b405e036f" }, "downloads": -1, "filename": "flask_replicated-1.3.tar.gz", "has_sig": false, "md5_digest": "53e2eb0731aa950b647d997c64cdae14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3061, "upload_time": "2019-05-30T23:13:34", "url": "https://files.pythonhosted.org/packages/b3/e1/000a77f8b9c07ff0ffd32145d75346e46b7f16fc1e49c9ea4afb5a255860/flask_replicated-1.3.tar.gz" } ], "1.3a0": [ { "comment_text": "", "digests": { "md5": "7b88f7f5d0918ff253764bb837b50611", "sha256": "f01e53f68afb8ae670ef77644c9fb85c548ad6dfb39e172a508d9e0ba844d9dd" }, "downloads": -1, "filename": "flask_replicated-1.3a0-py3-none-any.whl", "has_sig": false, "md5_digest": "7b88f7f5d0918ff253764bb837b50611", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 3169, "upload_time": "2019-05-30T23:01:02", "url": "https://files.pythonhosted.org/packages/64/2b/8842cdb0ef479fc87c305a8c5eb5010df4198ed4b4001903f0f0387113c9/flask_replicated-1.3a0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "95c67a5451322b4912404e49ff09b6f9", "sha256": "98e10947a49034d26e38170c770d136ce0f26e2ceebed9ef4c2b5239310c3fb3" }, "downloads": -1, "filename": "flask_replicated-1.3a0.tar.gz", "has_sig": false, "md5_digest": "95c67a5451322b4912404e49ff09b6f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3235, "upload_time": "2019-05-30T23:01:01", "url": "https://files.pythonhosted.org/packages/51/89/d710b3c83252122ca6c18522f3d261c12e0a3f0d8e412d8408ed1e098c0a/flask_replicated-1.3a0.tar.gz" } ], "1.3a1": [ { "comment_text": "", "digests": { "md5": "71660dea6ef7d4cb2cbab25a4add14d8", "sha256": "8091668e0fedf98942da5cc8eb5cf82c4b8db9db1cdf341f705f2f1adaeff54b" }, "downloads": -1, "filename": "flask_replicated-1.3a1-py3-none-any.whl", "has_sig": false, "md5_digest": "71660dea6ef7d4cb2cbab25a4add14d8", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 3223, "upload_time": "2019-05-30T23:12:12", "url": "https://files.pythonhosted.org/packages/f8/b0/5977dd631a805055eee95dc4ffed59e3b7107700357882718345d25c05f6/flask_replicated-1.3a1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "96f11b1dec09a7e2558e1f6168971642", "sha256": "593246b19f155892540c823764b0d65fbdb7674bd8549deca0782313ec888c35" }, "downloads": -1, "filename": "flask_replicated-1.3a1.tar.gz", "has_sig": false, "md5_digest": "96f11b1dec09a7e2558e1f6168971642", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3071, "upload_time": "2019-05-30T23:12:11", "url": "https://files.pythonhosted.org/packages/57/e6/20a34dd7f4dbf39605121e0bb813b53c1fad0a1de56394d9f57a1118c5bb/flask_replicated-1.3a1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "da031e0a54b2a40400c20dc10ab298a8", "sha256": "877d278b45d6de39189c6d076b71452d6d176e0d823c3f922922ba793546d36e" }, "downloads": -1, "filename": "flask_replicated-1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "da031e0a54b2a40400c20dc10ab298a8", "packagetype": "bdist_wheel", "python_version": "3.6", "requires_python": null, "size": 3203, "upload_time": "2019-05-30T23:13:36", "url": "https://files.pythonhosted.org/packages/87/77/ccdfdf47da52f46c7f1373f11d36ad677ffccafdf511fa1b01f4b32b4cc6/flask_replicated-1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "53e2eb0731aa950b647d997c64cdae14", "sha256": "ccbfc1fadd9c06a9a7b69fa55c3a998b1deab702f8602250ea64fe3b405e036f" }, "downloads": -1, "filename": "flask_replicated-1.3.tar.gz", "has_sig": false, "md5_digest": "53e2eb0731aa950b647d997c64cdae14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3061, "upload_time": "2019-05-30T23:13:34", "url": "https://files.pythonhosted.org/packages/b3/e1/000a77f8b9c07ff0ffd32145d75346e46b7f16fc1e49c9ea4afb5a255860/flask_replicated-1.3.tar.gz" } ] }