# relations-dil
DB/API Modeling
Relations is designed to be a simple, straight forward, flexible DIL (data interface layer).
Quite different from other DIL's, it has the singular, microservice based purpose to:
- Create models with very little code, independent of backends
- Create CRUD API with a database backend from those models with very little code
- Create microservices to use those same models but with that CRUD API as the backend
Ya, that last one is kinda new I guess.
Say we create a service, composed of microservices, which in turn is to be consumed by other services made of microservices.
You should only need to define the model once. Your conceptual structure is the same, to the DB, the API, and anything using that API. You shouldn't have say that structure over and over. You shouldn't have to define CRUD endpoints over and over. That's so boring, tedious, and unnecessary.
Furthermore, the conceptual structure is based not the backend of what you've going to use at that moment of time (scaling matters) but on the relations, how the pieces interact. If you know the structure of the data, that's all you need to interact with the data.
So with Relations, Models and Fields are defined independent of any backend, which instead is set at runtime. So the API will use a DB, everything else will use that API.
This is package is just a piece of that whole process, the base abstract classes, etc. But with a mock source, you can see how it all works.
# Example
```python
import relations
# The SOURCE in a model is a string, used to access a source in Relations's global registry
class Base(relations.Model):
SOURCE = "example"
# The Models automatically have the same SOURCE by using this Base
class Unit(Base):
id = int
name = str
class Test(Base):
id = int
unit_id = int # Relations aren't defined here, but outside the models
name = str
# Creation a Relation from unit.id to test.unit_id (default)
relations.OneToMany(Unit, Test)
# This defines the "example" source to be an in memory store
relations.unittest.MockSource("example")
# Create Unit named yep and store
Unit("yep").create()
# Query a single Unit with the name "yep" and access its id
Unit.one(name="yep").id # 1
# Create two Units, named people and stuff, because name is the first non readdonly field
Unit([["people"], ["stuff"]]).create()
# Retrieve a single Unit with name stuff, and set the name to "things" (but don't save)
unit = Unit.one(name="stuff").set(name="things")
# Save the update (returns number of records updated))
unit.update() # 1
# Retrieve a single Unit with id 2, and set the name to "thing"
unit = Unit.one(2)
unit.name = "thing"
# Add a child test with name "more" (first non readonly that's not already set)
unit.test.add("moar")
unit.update()
# Find all the Tests with a parent Unit with name "thing", and an id greater than 0
tests = Test.many(unit__name="thing", id__gt=0)
tests[0].name # "moar"
```
Raw data
{
"_id": null,
"home_page": "https://github.com/relations-dil/python-relations",
"name": "relations-dil",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Gaffer Fitch",
"author_email": "relations@gaf3.com",
"download_url": "https://files.pythonhosted.org/packages/24/6c/f4ae9ce385811ad669544b013f65ace238d55e2c08fc893d9f805627372f/relations-dil-0.6.13.tar.gz",
"platform": null,
"description": "# relations-dil\n\nDB/API Modeling\n\nRelations is designed to be a simple, straight forward, flexible DIL (data interface layer).\n\nQuite different from other DIL's, it has the singular, microservice based purpose to:\n- Create models with very little code, independent of backends\n- Create CRUD API with a database backend from those models with very little code\n- Create microservices to use those same models but with that CRUD API as the backend\n\nYa, that last one is kinda new I guess.\n\nSay we create a service, composed of microservices, which in turn is to be consumed by other services made of microservices.\n\nYou should only need to define the model once. Your conceptual structure is the same, to the DB, the API, and anything using that API. You shouldn't have say that structure over and over. You shouldn't have to define CRUD endpoints over and over. That's so boring, tedious, and unnecessary.\n\nFurthermore, the conceptual structure is based not the backend of what you've going to use at that moment of time (scaling matters) but on the relations, how the pieces interact. If you know the structure of the data, that's all you need to interact with the data.\n\nSo with Relations, Models and Fields are defined independent of any backend, which instead is set at runtime. So the API will use a DB, everything else will use that API.\n\nThis is package is just a piece of that whole process, the base abstract classes, etc. But with a mock source, you can see how it all works.\n\n# Example\n\n```python\n\nimport relations\n\n# The SOURCE in a model is a string, used to access a source in Relations's global registry\n\nclass Base(relations.Model):\n SOURCE = \"example\"\n\n# The Models automatically have the same SOURCE by using this Base\n\nclass Unit(Base):\n id = int\n name = str\n\nclass Test(Base):\n id = int\n unit_id = int # Relations aren't defined here, but outside the models\n name = str\n\n# Creation a Relation from unit.id to test.unit_id (default)\n\nrelations.OneToMany(Unit, Test)\n\n# This defines the \"example\" source to be an in memory store\n\nrelations.unittest.MockSource(\"example\")\n\n# Create Unit named yep and store\n\nUnit(\"yep\").create()\n\n# Query a single Unit with the name \"yep\" and access its id\nUnit.one(name=\"yep\").id # 1\n\n# Create two Units, named people and stuff, because name is the first non readdonly field\nUnit([[\"people\"], [\"stuff\"]]).create()\n\n# Retrieve a single Unit with name stuff, and set the name to \"things\" (but don't save)\nunit = Unit.one(name=\"stuff\").set(name=\"things\")\n\n# Save the update (returns number of records updated))\nunit.update() # 1\n\n# Retrieve a single Unit with id 2, and set the name to \"thing\"\nunit = Unit.one(2)\nunit.name = \"thing\"\n\n# Add a child test with name \"more\" (first non readonly that's not already set)\n\nunit.test.add(\"moar\")\nunit.update()\n\n# Find all the Tests with a parent Unit with name \"thing\", and an id greater than 0\ntests = Test.many(unit__name=\"thing\", id__gt=0)\ntests[0].name # \"moar\"\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "",
"version": "0.6.13",
"project_urls": {
"Homepage": "https://github.com/relations-dil/python-relations"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1aaa07d342e42c45a3e49ab8acbabe54c0a2e38b7eb9794719bfb611db0291ff",
"md5": "45efbc76c8c19a2a7007499521594b44",
"sha256": "31ad133c06272d021954ff997dc337d99eb4704d3efb5ea09368489bc002ef72"
},
"downloads": -1,
"filename": "relations_dil-0.6.13-py3-none-any.whl",
"has_sig": false,
"md5_digest": "45efbc76c8c19a2a7007499521594b44",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 26792,
"upload_time": "2023-06-27T17:07:59",
"upload_time_iso_8601": "2023-06-27T17:07:59.477725Z",
"url": "https://files.pythonhosted.org/packages/1a/aa/07d342e42c45a3e49ab8acbabe54c0a2e38b7eb9794719bfb611db0291ff/relations_dil-0.6.13-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "246cf4ae9ce385811ad669544b013f65ace238d55e2c08fc893d9f805627372f",
"md5": "42a011b3cac4fce2a30336c46a08ae90",
"sha256": "878ae770f8eea2b0f373b28414374a546449236efb609bb7baeb6189722f5d68"
},
"downloads": -1,
"filename": "relations-dil-0.6.13.tar.gz",
"has_sig": false,
"md5_digest": "42a011b3cac4fce2a30336c46a08ae90",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 25091,
"upload_time": "2023-06-27T17:08:01",
"upload_time_iso_8601": "2023-06-27T17:08:01.192743Z",
"url": "https://files.pythonhosted.org/packages/24/6c/f4ae9ce385811ad669544b013f65ace238d55e2c08fc893d9f805627372f/relations-dil-0.6.13.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-06-27 17:08:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "relations-dil",
"github_project": "python-relations",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [],
"lcname": "relations-dil"
}