Skip to content

Models

Models you create using DbmModel look similar to your Pydantic or Django models.

The purpose of your models is to validate your data, if you want to normalize it and save it using dbm. If you wish, you can use your model to perform simple operations on your related data, for example; get, filter, all, update and save.

Pydbm can perform type validation, custom validation and custom normalization.

Basic model usage

from pydbm import DbmModel

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    username: str

User here is a model with one field; username. Field of username is str type, and it is required field. Also, It includes a one more field named id. This field is automatically generated by Pydbm and these fields are equal.

Now, let’s create a user.

user = UserModel(username="hakancelik")
user is an instance of UserModel. It has a username field and id field. If no ValidationError raises, it means that the data is valid.

Let’s get attributes of user.

assert user.username == "hakancelik"
assert user.id == "20087fb9cf70fb074239826d21c18ea3"

assert user.fields == {'username': 'hakancelik'}

Default values

If you want to set a default value for a field, you can assign a default value to the field directly.

from pydbm import DbmModel

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    salt: str = "my-unpredictable-salt"
    username: str

While id generates in my new user model, I set a salt value to generate different in my model, now my id will be different from the one above.

user = UserModel(username="hakancelik")

assert user.username == "hakancelik"
assert user.id == "908cbfedd18749b69a39d3771f6762a2"

assert user.fields == {'username': 'hakancelik'}
As you can see with this example, the values of all fields are taken by default during id generation. But If you want you can change of the fields while generating id.

Unique Together

from pydbm import DbmModel

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    salt: str = "my-unpredictable-salt"
    username: str

    class Config:
        unique_together = ("username",)

Now, We create a new user same as above, user’s id will be same.

user = UserModel(username="hakancelik")

assert user.username == "hakancelik"
assert user.id == "20087fb9cf70fb074239826d21c18ea3"

assert user.fields == {'username': 'hakancelik'}

Table Name

In Pydbm, default table name is model name. You can change or control it by using table_name attribute in Config class.

from pydbm import DbmModel

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    salt: str = "my-unpredictable-salt"
    username: str

    class Config:
        unique_together = ("username",)
        table_name = "users"

Now even if the class name changes, you will not lose your data.


Operations Supported by the Model

So far, we have written a simple model example and got its values, but we have not performed any data operations yet, let’s examine what’s available.

Save

Save method is used to save the valid data to the database.

user = UserModel(username="hakancelik")
user.save()
That’s it, now we have saved our user to the database. In addition If you wish, you can update any field belonging to the instance and then have it updated in your database.

user = UserModel(username="hakan")
user.save()  # save user to database for the first time

user.username="hakancelik"
user.save()  # update username field

UserModel.objects.get(id=user.id) == UserModel(username=”hakancelik”)

Get

Get method is used to get the data from the database and return it as a model instance. To fetch single data from the database and get it as a model instance, you can pass the unique together fields of the model.

try:
    user = UserModel.objects.get(id=user.id)
except UserModel.DoesNotExist:
    print("User does not exist")

If the user exists in the database, it will return the user, otherwise it raises UserModel.DoesNotExists exception.

try:
    user = UserModel.objects.get(name="hakan", surname="celik")
except UserModel.RiskofReturningMultipleObjects:
    print("Risk of Returning Multiple Users")

If name and surname fields are unique together, it will return the user, otherwise it raises UserModel.RiskofReturningMultipleObjects exception.

Update

Update method is used to update the data in the database, when you use this method id is not changed.

user = UserModel.objects.get(user.id)
user.update(username="hakan")

assert user.username == "hakan"
assert user.id == "908cbfedd18749b69a39d3771f6762a2"  # id is not changed  
Delete

Delete user from database.

user = UserModel.objects.get(user.id)
user.delete()
Create

Create method is used to save the data to the database and return the data as a model instance.

user = UserModel.objects.create(username="hakancelik")

It is the same as save, but it returns the user.

All

All method is used to get all data from the database and iterate model instances.

users = list(UserModel.objects.all())
Filter

Filter method is used to filter data from the database and iterate model instances. You can filter data by using the fields of the model.

users = list(UserModel.objects.filter(username="hakancelik"))
Exists

Exists method is used to check if the data exists in the database, returns True if the data exists, otherwise returns False. If you pass unique together fields of the model, it will be faster.

is_exists: bool = UserModel.objects.exists(username="hakancelik")

## Model properties

`as_dict()`

returns a dictionary of the model's fields and values.

`fields`

returns a dictionary of the model's fields and values.


## Field

By using the Field, it is possible to define the default value, default factory, validators and normalizations of the field.
If type of field is int, then it can be validated min_value and max_value.

> Type validation is performed automatically, you do not need to define it.
> Just define the type annotation of the field.


### Default value
When it is used, then the field is a not required field.

```python
from pydbm import DbmModel, Field

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    salt: str = Field(default="my-unpredictable-salt")
    username: str
Default factory

When it is used, then the field is a not required field.

from pydbm import DbmModel, Field

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    salt: str = Field(default_factory=lambda: "my-unpredictable-salt")
    username: str
Custom Normalization

It can be defined list of normalization functions, to normalize the field value.

from pydbm import DbmModel, Field

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    username: str = Field(normalize=[lambda x: x.lower()])

In here, username field will be lowered case.

Custom Validation

We have some built-in validators, but you can also create your own validator. For more information, see Validators.

from pydbm import DbmModel, Field

__all__ = (
    "UserModel",
)

class UserModel(DbmModel):
    username: str = Field(
        validators=[lambda value: value.startswith("@")]
    )

Last update: July 19, 2023
Created: July 19, 2023