ODetaM
A simple ODM (Object Document Mapper) for Deta Base base on pydantic.
Installation
pip install odetam
Usage
Create pydantic models as normal, but inherit from DetaModel instead of pydantic
BaseModel. You will need to set the environment variable PROJECT_KEY to your Deta
project key so that databases can be accessed/created. This is a secret key, so handle
it appropriately (hence the environment variable). Intended for use with FastAPI, but
the Deta API is not asynchronous, so any framework could potentially be used.
Bases will be automatically created based on model names (changed from
PascalCase/CamelCase case to snake_case). A key field (Deta's unique id) will be
automatically added to any model. You can supply the key on creation, or Deta will
generate one automatically and it will be added to the object when it is saved.
Example
import datetime
from typing import List
from odetam import DetaModel
class Captain(DetaModel):
name: str
joined: datetime.date
ships: List[str]
# create
kirk = Captain(
name="James T. Kirk",
joined=datetime.date(2252, 1, 1),
ships=["Enterprise"],
)
sisko = Captain(
name="Benjamin Sisko",
joined=datetime.date(2350, 1, 1),
ships=["Deep Space 9", "Defiant"],
)
# initial save, key is now set
kirk.save()
# update the object
kirk.ships.append("Enterprise-A")
# save again, this will be an update
kirk.save()
sisko.save()
Captain.get_all()
# [
# Captain(
# name="James T. Kirk",
# joined=datetime.date(2252, 01, 01),
# ships=["Enterprise", "Enterprise-A"],
# key="key1",
# ),
# Captain(
# name="Benjamin Sisko",
# joined=datetime.date(2350, 01, 01),
# ships=["Deep Space 9", "Defiant"],
# key="key2",
# ),
# ]
Captain.get("key1")
# Captain(
# name="James T. Kirk",
# joined=datetime.date(2252, 01, 01),
# ships=["Enterprise", "Enterprise-A"],
# key="key1",
# )
Captain.query(Captain.name == "James T. Kirk")
# Captain(
# name="James T. Kirk",
# joined=datetime.date(2252, 01, 01),
# ships=["Enterprise", "Enterprise-A"],
# key="key1",
# )
Captain.query(Captain.ships.contains("Defiant"))
# Captain(
# name="Benjamin Sisko",
# joined=datetime.date(2350, 01, 01),
# ships=["Deep Space 9", "Defiant"],
# )
Captain.query(Captain.name.prefix("Ben"))
# Captain(
# name="Benjamin Sisko",
# joined=datetime.date(2350, 01, 01),
# ships=["Deep Space 9", "Defiant"],
# )
kirk.delete()
Captain.delete_key("key2")
Captain.get_all()
# []
# you can also save several at once for better speed
Captain.put_many([kirk, sisko])
# [
# Captain(
# name="James T. Kirk",
# joined=datetime.date(2252, 01, 01),
# ships=["Enterprise", "Enterprise-A"],
# key="key1",
# ),
# Captain(
# name="Benjamin Sisko",
# joined=datetime.date(2350, 01, 01),
# ships=["Deep Space 9", "Defiant"],
# key="key2",
# ),
# ]
Save
Models have the .save() method which will always behave as an upsert, updating a
record if it has a key, otherwise creating it and setting a key. Deta has pure insert
behavior, but it's less performant. If you need it, please open a pull request.
Querying
All basic comparison operators are implemented to map to their equivalents as
(Model.field >= comparison_value). There is also a .contains() and .not_contains()
method for strings and lists of strings, as well as a .prefix() method for strings.
There is also a .range() for number types that takes a lower and upper bound. You can
also use & as AND and | as OR. ORs cannot be nested within ands, use a list of
options as comparison instead. You can use as many ORs as you want, as long as they
execute after the ANDs in the order of operations. This is due to how the Deta Base api
works.
Deta Base
Direct access to the base is available in the dunder attribute __db__, though the
point is to avoid that.
Exceptions
DetaError: Base exception when anything goes wrong.ItemNotFound: Fairly self-explanatory...NoProjectKey:PROJECT_KEYenv var has not been set correctly. See Deta documentation.InvalidDetaQuery: Something is wrong with queries. Make sure you aren't using queries with unsupported types
Metadata
Release files for odetam 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ODetaM-1.0.3.tar.gz | 6.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ODetaM-1.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.7 kB
Release files / ODetaM-1.0.3.tar.gz
| Download URL | ODetaM-1.0.3.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
36000a4f5d945200272868cdc2593c511c5f74a5bf8328d4397b35270566c072
|
|
BLAKE2b-256 checksum How to use checksums |
2fb9fff2dd75ff129f2ef17b6ef986052b24f2883e7934de9e001d2dfa9815ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.4 CPython/3.9.6 Linux/5.13.4-arch2-1
|
Release files / ODetaM-1.0.3-py3-none-any.whl
| Download URL | ODetaM-1.0.3-py3-none-any.whl |
|---|---|
| Size | 6.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d2ed659906b06dd4a6aacc66461f6635a96bb7eb2a7d3823ed68182f537b2e15
|
|
BLAKE2b-256 checksum How to use checksums |
611bd162b1b89b514bb2070a5b087dfd1fc93b8a6a61da181c8ee5a328e11e03
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.4 CPython/3.9.6 Linux/5.13.4-arch2-1
|