All Projects → codemation → pydbantic

codemation / pydbantic

Licence: Apache-2.0 license
A single model for shaping, creating, accessing, storing data within a Database

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to pydbantic

json2python-models
Generate Python model classes (pydantic, attrs, dataclasses) based on JSON datasets with typing module support
Stars: ✭ 119 (-13.14%)
Mutual labels:  models, pydantic
bonobo-sqlalchemy
PREVIEW - SQL databases in Bonobo, using sqlalchemy
Stars: ✭ 23 (-83.21%)
Mutual labels:  sqlalchemy, databases
sqlalchemy-enum34
SQLAlchemy type to store standard enum.Enum values
Stars: ✭ 47 (-65.69%)
Mutual labels:  sqlalchemy, databases
Sqlalchemy Imageattach
SQLAlchemy extension for attaching images to entities.
Stars: ✭ 107 (-21.9%)
Mutual labels:  sqlalchemy, databases
Awesome Sqlalchemy
A curated list of awesome tools for SQLAlchemy
Stars: ✭ 2,316 (+1590.51%)
Mutual labels:  sqlalchemy, databases
Ormar
python async mini orm with fastapi in mind and pydantic validation
Stars: ✭ 155 (+13.14%)
Mutual labels:  sqlalchemy, databases
reactant
Generate code for "models, views, and urls" based on Python type annotations. Supports Django REST, SQLAlchemy, Peewee.
Stars: ✭ 14 (-89.78%)
Mutual labels:  sqlalchemy, pydantic
sqlalchemy-utc
SQLAlchemy type to store aware datetime values
Stars: ✭ 87 (-36.5%)
Mutual labels:  sqlalchemy, databases
nim-gatabase
Connection-Pooling Compile-Time ORM for Nim
Stars: ✭ 103 (-24.82%)
Mutual labels:  sqlalchemy, databases
python-artifactory
Typed interactions with the Jfrog Artifactory REST API
Stars: ✭ 34 (-75.18%)
Mutual labels:  pydantic
spectree
API spec validator and OpenAPI document generator for Python web frameworks.
Stars: ✭ 190 (+38.69%)
Mutual labels:  pydantic
limitless-engine
OpenGL C++ Graphics Engine
Stars: ✭ 95 (-30.66%)
Mutual labels:  models
timely-beliefs
Model data as beliefs (at a certain time) about events (at a certain time).
Stars: ✭ 15 (-89.05%)
Mutual labels:  sqlalchemy
cloudrun-fastapi
FastAPI on Google Cloud Run
Stars: ✭ 112 (-18.25%)
Mutual labels:  sqlalchemy
osprey
🦅Hyperparameter optimization for machine learning pipelines 🦅
Stars: ✭ 71 (-48.18%)
Mutual labels:  models
sqlconstruct
Functional approach to query database using SQLAlchemy
Stars: ✭ 22 (-83.94%)
Mutual labels:  sqlalchemy
Apollo
A basic Application with multiple functionalities built with FastAPI aim to help Users Buy New Items Provided using PaypalAPI 🚀
Stars: ✭ 22 (-83.94%)
Mutual labels:  sqlalchemy
KazukoBot
An anime themed telegram group management bot based on sqlalchemy database running on python3.
Stars: ✭ 25 (-81.75%)
Mutual labels:  sqlalchemy
flask-db
A Flask CLI extension to help migrate and manage your SQL database.
Stars: ✭ 56 (-59.12%)
Mutual labels:  sqlalchemy
flask-celery-sqlalchemy
An example app to show how to get Flask, Celery, and SQLAlchemy working together
Stars: ✭ 33 (-75.91%)
Mutual labels:  sqlalchemy

'db' within pydantic - A single model for shaping, creating, accessing, storing data within a Database

Documentation Status PyPI versionUnit & Integration Tests

Key Features

  • Automatic Migration on Schema Changes
  • Flexible Data Types
  • One Model for type validation & database access
  • Dynamic Model Relationships
  • Integrated Redis Caching Support

Documentation

https://pydbantic.readthedocs.io/en/latest/

Setup

$ pip install pydbantic
$ pip install pydbantic[sqlite]
$ pip install pydbantic[mysql]
$ pip install pydbantic[postgres]

Basic Usage - Model

from typing import List, Optional, Union
from pydbantic import DataBaseModel, PrimaryKey

class Department(DataBaseModel):
    department_id: str = PrimaryKey()
    name: str
    company: str
    is_sensitive: bool = False
    positions: List[Optional['Positions']] = []  # One to Many

class Positions(DataBaseModel):
    position_id: str = PrimaryKey()
    name: str
    department: Department = None               # One to One mapping 
    employees: List[Optional['Employee']] = []  # One to Many

class EmployeeInfo(DataBaseModel):
    ssn: str = PrimaryKey()
    first_name: str
    last_name: str
    address: str
    address2: Optional[str]
    city: Optional[str]
    zip: Optional[int]
    new: Optional[str]
    employee: Optional[Union['Employee', dict]] = None # One to One 

class Employee(DataBaseModel):
    employee_id: str = PrimaryKey()
    employee_info: Optional[EmployeeInfo] = None  # One to One
    position: List[Optional[Positions]] = []      # One to Many 
    salary: float
    is_employed: bool
    date_employed: Optional[str]

Basic Usage - Connecting a Database to Models

import asyncio
from pydbantic import Database
from models import Employee, EmployeeInfo, Positions, Department

async def main():
    db = await Database.create(
        'sqlite:///test.db',
        tables=[
            Employee,
            EmployeeInfo,
            Positions,
            Department
        ]
    )

if __name__ == '__main__':
    asyncio.run(main())

Model Usage

Import and use the models where you need them. As long as DB as already been created, the Models can accesss the & Use the connected DB

from models import (
    Employee, 
    EmployeeInfo, 
    Position, 
    Department
)

Model - Creation

    # create department 
    hr_department = await Department.create(
        id='d1234',
        name='hr'
        company='abc-company',
        is_sensitive=True,
    )

Via instance using insert or save

    hr_department = Department.create(
        id='d1234',
        name='hr'
        company='abc-company',
        is_sensitive=True,
    )

    await hr_department.insert()
    await hr_department.save()

Insert with related models

    # create a Position in Hr Department
    hr_manager = Position.create(
        id='p1234',
        name='manager',
        department=hr_department
    )
    
    # create instance on an hr employee
    hr_emp_info = EmployeeInfo.create(
        ssn='123-456-789',
        first_name='john',
        last_name='doe',
        address='123 lane',
        city='snake city',
        zip=12345
    )

    # create an hr employee 
    hr_employee = await Employee.create(
        id='e1234',
        employee_info=hr_emp_info,
        position=hr_manager,
        is_employed=True,
        date_employed='1970-01-01'
    )

Filtering

    # get all hr managers currently employed
    managers = await Employee.filter(
        Employee.position==hr_manager, # conditional
        is_employed=True               # key-word argument
    )

    first_100_employees = await Employee.all(
        limit=100
    )

See also filtering operators

Deleting

    # remove all managers not employed anymore
    for manager in await Employee.filter(
        position=hr_manager,
        is_employed=False
    ):
        await manager.delete()

Updating

    # raise salary of all managers
    for manager in await Employee.filter(
        position=hr_manager,
        is_employed=False
    ):
        manager.salary = manager.salary + 1000.0
        await manager.update() # or manager.save()

.save() results in a new row created in Employee table as well as the related EmployeeInfo, Position, Department tables if not yet created. s

What is pydbantic

pydbantic was built to solve some of the most common pain developers may face working with databases.

  • migrations
  • model creation / managment
  • dynamic relationships
  • caching

pydbantic believes that related data should be stored together, in the shape the developer plans to use

pydbantic knows data is rarely flat or follows a set schema

pydbantic understand migrations are not fun, and does them for you

pydbantic speaks many types

Pillars

Models

pydbantic most basic object is a DataBaseModel. This object may be comprised of almost any pickle-able python object, though you are encouraged to stay within the type-validation land by using pydantic's BaseModels and validators.

Primary Keys

DataBaseModel 's also have a priamry key, which is the first item defined in a model or marked with = PrimaryKey()

class NotesBm(DataBaseModel):
    id: str = PrimaryKey()
    text: Optional[str]  # optional
    data: DataModel      # required 
    coridinates: tuple   # required
    items: list          # required
    nested: dict = {'nested': True} # Optional - w/ Default

Model Types & Typing

DataBaseModel items are capable of being multiple layers deep following pydantic model validation

  • Primary Key - First Item, must be unique
  • Required - items without default values are assumed required
  • Optional - marked explicitly with typing.Optional or with a default value
  • Union - Accepts Either specified input type Union[str|int]
  • List[item] - Lists of specified items

Input datatypes without a natural / built in serialization path are serialized using pickle and stored as bytes. More on this later.

Migrations

pydbantic handles migrations automatically in response to detected model changes: New Field, Removed Field, Modified Field, Renamed Field, Primary Key Changes

Renaming an exiting column

Speical consideration is needed when renaming a field in a DataBaseModel, extra metadata __renamed__ is needed to ensure existing data is migrated:

# field `first_name` is renamed to `first_names`

class EmployeeInfo(DataBaseModel):
    __renamed__= [{'old_name': 'first_name', 'new_name': 'first_names'}]
    ssn: str = PrimaryKey()
    first_names: str
    last_name: str
    address: str
    address2: Optional[str]
    city: Optional[str]
    zip: Optional[int]

Cache

Adding cache with Redis is easy with pydbantic, and is complete with built in cache invalidation.

    db = await Database.create(
        'sqlite:///test.db',
        tables=[Employee],
        cache_enabled=True,
        redis_url="redis://localhost"
    )

Models with arrays of Foreign Objects

DataBaseModel models can support arrays of both BaseModels and other DataBaseModel. Just like single DataBaseModel references, data is stored in separate tables, and populated automatically when the child DataBaseModel is instantiated.

from uuid import uuid4
from datetime import datetime
from typing import List, Optional
from pydbantic import DataBaseModel, PrimaryKey


def time_now():
    return datetime.now().isoformat()
def get_uuid4():
    return str(uuid4())

class Coordinate(DataBaseModel):
    id: str = PrimaryKey(default=get_uuid4)
    lat_long: tuple
    journeys: List[Optional["Journey"]] = []

class Journey(DataBaseModel):
    trip_id: str = PrimaryKey(default=get_uuid4)
    waypoints: List[Optional[Coordinate]] = []
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].