.. image:: https://github.com/matific/broken-down-models/actions/workflows/tests.yml/badge.svg
:alt: Test status
Break a large model down, transparently
---------------------------------------
In a project that goes on for several years, models tend to grow and
accumulate fields. If you aren't very disciplined about this, you wake up
one day, and find that one of your central tables, one with millions of
rows, has 43 columns, including some TextFields. Most of them are not
required most of the time, but the default (and common) use is to fetch all
of them; also, since this table is queried a lot, the mere fact that it has
so many columns makes some of the access slower.
When you realize that, you want to break it into components, such that
only a few, most-important columns will participate in the large searches,
while further details will be searched and fetched only when needed.
But that is a scary proposition -- it might involve subtle code changes,
break not just field access but also ORM queries... and this is a central
model. The change imagined is open-heart surgery on a large project.
Maybe, if we look the other way, it won't bother us too much...
**broken-down-models** is here to help you. This is a library which can
help you refactor your large model into a set of smaller ones, each with
its own database table, while most of your project code remains unchanged.
How?
----
Django already includes a mechanism where fields for one model are stored
in more than one table: Multi Table Inheritance (also known as MTI).
That's what happens when we do "normal" inheritance of models, without
specifying anything special in the Meta of either of the models.
Python also supports Multiple Inheritance -- one class can have many parent
classes. And this also works with Django's MTI -- we can have multiple MTI.
Usually, when we think of a "core" set of attributes with different extensions,
and we decide to implement it with MTI, we put this core set in a parent
model, and make the extensions subclass it. But in the situation where we
try to break down an existing model, this would mean that code which currently
uses the large model will have to change, to recognize the new parts.
**broken-down-models** puts this idea on its head: The extensions become
parent models, and the core set is defined in a model which inherits them all.
This way, all the fields are still fields of of the model we started with,
for all purposes -- including not just attribute access, but also ORM queries.
For this to really work well, though, some further modifications are required;
this is why the library exists, and it is explained in its documentation.
Raw data
{
"_id": null,
"home_page": "https://github.com/Matific/broken-down-models",
"name": "broken-down-models",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "Django,models,database,optimization,refactoring",
"author": "Shai Berger",
"author_email": "shai.berger@slatescience.com",
"download_url": "https://files.pythonhosted.org/packages/b7/7b/08e90c513617ed59955210c883b4f1513308d32da89d72c8670776727038/broken-down-models-0.3.1.tar.gz",
"platform": null,
"description": ".. image:: https://github.com/matific/broken-down-models/actions/workflows/tests.yml/badge.svg\n :alt: Test status\n\n\nBreak a large model down, transparently\n---------------------------------------\n\nIn a project that goes on for several years, models tend to grow and\naccumulate fields. If you aren't very disciplined about this, you wake up\none day, and find that one of your central tables, one with millions of\nrows, has 43 columns, including some TextFields. Most of them are not\nrequired most of the time, but the default (and common) use is to fetch all\nof them; also, since this table is queried a lot, the mere fact that it has\nso many columns makes some of the access slower.\n\nWhen you realize that, you want to break it into components, such that\nonly a few, most-important columns will participate in the large searches,\nwhile further details will be searched and fetched only when needed.\n\nBut that is a scary proposition -- it might involve subtle code changes,\nbreak not just field access but also ORM queries... and this is a central\nmodel. The change imagined is open-heart surgery on a large project.\nMaybe, if we look the other way, it won't bother us too much...\n\n**broken-down-models** is here to help you. This is a library which can\nhelp you refactor your large model into a set of smaller ones, each with\nits own database table, while most of your project code remains unchanged.\n\nHow?\n----\n\nDjango already includes a mechanism where fields for one model are stored\nin more than one table: Multi Table Inheritance (also known as MTI).\nThat's what happens when we do \"normal\" inheritance of models, without\nspecifying anything special in the Meta of either of the models.\n\nPython also supports Multiple Inheritance -- one class can have many parent\nclasses. And this also works with Django's MTI -- we can have multiple MTI.\n\nUsually, when we think of a \"core\" set of attributes with different extensions,\nand we decide to implement it with MTI, we put this core set in a parent\nmodel, and make the extensions subclass it. But in the situation where we\ntry to break down an existing model, this would mean that code which currently\nuses the large model will have to change, to recognize the new parts.\n\n**broken-down-models** puts this idea on its head: The extensions become\nparent models, and the core set is defined in a model which inherits them all.\nThis way, all the fields are still fields of of the model we started with,\nfor all purposes -- including not just attribute access, but also ORM queries.\nFor this to really work well, though, some further modifications are required;\nthis is why the library exists, and it is explained in its documentation.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A set of utlities for breaking a large Django model down to separate components",
"version": "0.3.1",
"split_keywords": [
"django",
"models",
"database",
"optimization",
"refactoring"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "80b6a60c852ddaf271ba89c2133661dee26919f22d3af9e54e8a172c6922990d",
"md5": "ae13048dfffef6543de0307df0b73261",
"sha256": "f44ebf64c44eb4e12bfe05e677f3a0f5194c00dc4b9957a44c12f05f8f9fbfd6"
},
"downloads": -1,
"filename": "broken_down_models-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ae13048dfffef6543de0307df0b73261",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 16266,
"upload_time": "2023-02-05T19:33:35",
"upload_time_iso_8601": "2023-02-05T19:33:35.791471Z",
"url": "https://files.pythonhosted.org/packages/80/b6/a60c852ddaf271ba89c2133661dee26919f22d3af9e54e8a172c6922990d/broken_down_models-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b77b08e90c513617ed59955210c883b4f1513308d32da89d72c8670776727038",
"md5": "5f439c655a7793535004fd44cebe6ab6",
"sha256": "118e8f9ca1d00c2ab01e68ddd8bccb278b181fc2dd7f9e8cb80e73aa34fa613c"
},
"downloads": -1,
"filename": "broken-down-models-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "5f439c655a7793535004fd44cebe6ab6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 16657,
"upload_time": "2023-02-05T19:33:33",
"upload_time_iso_8601": "2023-02-05T19:33:33.627875Z",
"url": "https://files.pythonhosted.org/packages/b7/7b/08e90c513617ed59955210c883b4f1513308d32da89d72c8670776727038/broken-down-models-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-02-05 19:33:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "Matific",
"github_project": "broken-down-models",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "broken-down-models"
}