Simple library that makes working with classes and databases more convenient in python.
omen2 will take a set of classes, and a database, and link them together.
omen2 allows the user to:
- serialize created objects to the db
- query the db and return objects, not rows
- query for related objects
- access/lock/update singleton objects across multiple threads
- roll back changes on exceptions
- create objects not-bound to the db, and later, bind them
- cache objects in use, flexible cache-control
omen2 is not fully flexible with regards to database structure:
- related tables must have primary keys
from notanorm import SqliteDb
from omen2 import Omen
class MyOmen(Omen):
version = 2
@staticmethod
def schema(version):
# use an omen2-compatible schema, which is a semicolon-delimited sqlite-compatible create statement
return """create table cars(id integer primary key, color text not null, gas_level double default 1.0);
create table doors(carid integer, type text, primary key (carid, type));"""
# or, just return a list of type-annotated classes derived from ObjBase
# or, don't have one at all, it's ok
# you don't have to codegen, you can also just derive from omen2.ObjBase
# but you have to match your database system to the model one way or another
# either manual, codegen, or dbgen
MyOmen.codegen()
# assuming this is example.py
import example_gen as gen_objs
# every table has a row_type, you can derive from it
class Car(gen_objs.cars_row):
def __init__(self, color="black", **kws):
self.not_saved_to_db = "some thing"
self.doors = gen_objs.doors_relation(self, kws.pop("doors", None), carid=lambda: self.id)
super().__init__(color=color, **kws)
@property
def gas_pct(self):
# read only props are fine
return self.gas_level * 100
# if you're using code generation, every db table has a type, you can derive from it
class Cars(gen_objs.cars):
# feel free to redefine the row_type used
row_type = Car
db = SqliteDb(":memory:")
mgr = MyOmen(db, cars=Cars)
# there's always a mapping from table class to instance
# so Omen knows what classes are in charge of what tables
mgr.cars = mgr[Cars]
# fine too (or stick in init)
mgr.cars = Cars(self)
# by default, you can always iterate on tables
assert mgr.cars.count() == 0
car = Car() # creates a default car (black, full tank)
car.color = "red"
car.gas_level = 0.5
# you don't need to create a class, if you use the code-generated one
car.doors.add(gen_objs.doors_row(type="a"))
car.doors.add(gen_objs.doors_row(type="b"))
car.doors.add(gen_objs.doors_row(type="c"))
car.doors.add(gen_objs.doors_row(type="d"))
mgr.cars.add(car)
# cars have ids, generated by the db
assert car.id
mgr.cars.add(Car(color="red", gas_level=0.3, doors=[gen_objs.doors_row(type=str(i)) for i in range(4)]))
assert sum(1 for _ in mgr.cars.select(color="red")) == 2 # 2
print("cars:", list(mgr.cars.select(color="red")))
car = mgr.cars.select_one(color="red", gas_level=0.3)
with car:
car.gas_level = 0.9
assert len(car.doors) == 4
To run codegen manually, rather than "inline", you can run: omen2-codegen my.package.MyClassName.
Commiting this file, and running this as a git-hook on any change is a useful pattern.
Metadata
Release files for omen2 2.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| omen2-2.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Release files / omen2-2.1.5-py3-none-any.whl
| Download URL | omen2-2.1.5-py3-none-any.whl |
|---|---|
| Size | 28.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
09e8b1eda58f5ffa32eaba76e876b16911f9ff60cf9363c0db384adf588aaec2
|
|
BLAKE2b-256 checksum How to use checksums |
83d8352be42c15edb2f25ec1c41448cb76db53f9f4d7a09c1e269fc2930679a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.3.0 pkginfo/1.7.0 requests/2.27.1 setuptools/46.0.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.6.9
|