ORM for asyncio world by dataclass
Project description
Danio
Danio is a ORM for python asyncio world.It is designed to make getting easy and clearly.It builds on python's dataclass and encode's databases
Features
- keep OOM in mind, custom your Field and Model behavior easily
- type hints any where, no more need to memorize words your field names any more
- base CRUD operation, transactions, lock and so on
- signals like before save, after save and so on
- complex operation like bulk create, upsert, create or update and so on
- assist model schema migration
- support MySQL/PostgreSQL/SQLite
- hints generation
install
pip install danio
Documents
Glance
db = danio.Database(
"mysql://root:letmein@server:3306/test",
maxsize=3,
charset="utf8mb4",
use_unicode=True,
connect_timeout=60,
)
@dataclasses.dataclass
class User(danio.Model):
# auto generated by danio:
# --------------------Danio Hints--------------------
# TABLE NAME: user
# TABLE IS MIGRATED!
ID: typing.ClassVar[danio.Field] # "id" serial PRIMARY KEY NOT NULL
NAME: typing.ClassVar[danio.Field] # "name" varchar(255) NOT NULL
AGE: typing.ClassVar[danio.Field] # "age" int NOT NULL
CREATED_AT: typing.ClassVar[
danio.Field
] # "created_at" timestamp without time zone NOT NULL
UPDATED_AT: typing.ClassVar[
danio.Field
] # "updated_at" timestamp without time zone NOT NULL
GENDER: typing.ClassVar[danio.Field] # "gender" int NOT NULL
# --------------------Danio Hints--------------------
class Gender(enum.Enum):
MALE = 0
FEMALE = 1
OTHER = 2
id: typing.Annotated[int, danio.IntField(primary=True, type="serial")] = 0
name: typing.Annotated[str, danio.CharField(comment="User name")] = ""
age: typing.Annotated[int, danio.IntField] = 0
created_at: typing.Annotated[
datetime.datetime,
danio.DateTimeField(type="timestamp without time zone", comment="when created"),
] = dataclasses.field(default_factory=datetime.datetime.now)
updated_at: typing.Annotated[
datetime.datetime,
danio.DateTimeField(type="timestamp without time zone", comment="when updated"),
] = dataclasses.field(default_factory=datetime.datetime.now)
gender: typing.Annotated[Gender, danio.IntField(enum=Gender)] = Gender.MALE
async def before_create(self, validate=True):
await super().before_create(validate=True)
async def before_update(self, validate=True):
self.updated_at = datetime.datetime.now()
await super().before_update(validate=True)
async def validate(self):
await super().validate()
if not self.name:
raise danio.ValidateException("Empty name!")
@classmethod
def get_database(
cls, operation: danio.Operation, table: str, *args, **kwargs
) -> danio.Database:
return db
# base CRUD
user = await User(name="batman").save()
user = await User.where(User.NAME == "batman").fetch_one()
user.gender = User.Gender.MALE
await user.save()
await user.delete()
# sql chain
await User.where(User.NAME != "").limit(10).fetch_all()
# multi where condition
await User.where(User.ID != 1, User.NAME != "").fetch_all()
await User.where(User.ID != 1).where(User.NAME != "").fetch_all()
await User.where(User.ID <= 10, User.ID >= 20, is_and=False).fetch_all()
# complicated expression
await User.where(User.ID == 1).update(age=(User.AGE + 1) / (User.AGE / 12) - 2)
await User.where((User.AGE + 1) == 3).fetch_all()
# complicated sql operation
await User.where(User.ID == u.id).update(
age=User.AGE.case(User.AGE > 10, 1, default=18).case(User.AGE <= 0, 10)
)
created, updated = await UserProfile.upsert(
[
dict(id=1, name="upsert"),
],
update_fields=["name"],
)
# bulk operation
await User.bulk_create([User(name=f"user_{i}") for i in range(10)])
await User.bulk_update(await User.fetch_all())
await User.bulk_delete(await User.fetch_all())
# shortcut
user, created = await User(id=1, name="created?").get_or_create(
key_fields=(User.ID,)
)
user, created, updated = await User(id=2, name="updated?").create_or_update(
key_fields=(User.ID,)
)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
danio-0.5.1.tar.gz
(19.4 kB
view details)
Built Distribution
danio-0.5.1-py3-none-any.whl
(21.5 kB
view details)
File details
Details for the file danio-0.5.1.tar.gz
.
File metadata
- Download URL: danio-0.5.1.tar.gz
- Upload date:
- Size: 19.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.2 CPython/3.10.10 Linux/5.15.83-1-pve
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e1fea3c025f1eb69de74c8fc2429a9edeeefa15d637533bcd7adbedd5d7f14c5 |
|
MD5 | c3525bbe0d3f66d5ed9e6efc080119f8 |
|
BLAKE2b-256 | c23c99835f99ec529d110d5075c79cdcd5d903e6b05ff1db24a950ef724d3de7 |
File details
Details for the file danio-0.5.1-py3-none-any.whl
.
File metadata
- Download URL: danio-0.5.1-py3-none-any.whl
- Upload date:
- Size: 21.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.2 CPython/3.10.10 Linux/5.15.83-1-pve
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e8a747c7b9d4e05076bc280ba84f3bc2fdf8214ec86db5b9499f8bb9672d0771 |
|
MD5 | 4aed39d484bff8b84678f54e9226e5ba |
|
BLAKE2b-256 | b574618b9014a782e81597dab4b13bf62e30d0ec5abfe83627d9de962e7f82b2 |