def __init__(self, label: str, tortoise_model: Type[Model]) -> None: self.label = label self.tortoise_model = tortoise_model self.pydantic_model = pydantic_model_creator(self.tortoise_model, name=f"{label}") self.creation_model = pydantic_model_creator(self.tortoise_model, name=f"New{label}", exclude_readonly=True)
async def get_resource( resource: str, query: QueryItem = Depends(get_query), model=Depends(get_model) ): menu = app.model_menu_mapping[resource] qs = model.all() for filter_ in menu.custom_filters: qs = filter_.get_queryset(qs) if query.where: for name, value in query.where.items(): filter_cls = get_filter_by_name(name) if filter_cls: qs = filter_cls.get_queryset(qs, value) else: qs = qs.filter(**{name: value}) sort = query.sort for k, v in sort.items(): if k in menu.sort_fields: if v == -1: qs = qs.order_by(f"-{k}") elif v == 1: qs = qs.order_by(k) resource = await app.get_resource(resource) result = await qs.limit(query.size).offset((query.page - 1) * query.size) creator = pydantic_model_creator( model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields ) data = [] for item in result: item_dict = creator.from_orm(item).dict() item_dict["_rowVariant"] = item_dict.pop("rowVariant", None) item_dict["_cellVariants"] = item_dict.pop("cellVariants", None) data.append(item_dict) return GetManyOut(total=await qs.count(), data=data)
async def get_some(client_key, dict_name, **kwargs): """ Получить список моделей, одну модель с фильтрацией. Пока что есть только получение списка без фильтра """ obj_state = await tortoise_state.get(server=gethostname(), pid=getpid()) if not obj_state.state: await Tortoise.init(config=cfg_tortoise.get_tortoise_config()) obj_state.state = True await obj_state.save() class_model = get_orm_class(client_key=client_key, dict_name=dict_name) if not class_model: raise ORMProcessingError('Model not found!') pyd_model = pydantic_model_creator(class_model) if 'filter' in kwargs and kwargs['filter']: # Фильтрация model_queryset = class_model.filter(**kwargs['filter']) else: model_queryset = class_model.all() if 'order_by' in kwargs and kwargs['order_by']: # Сортировка model_queryset = model_queryset.order_by(*kwargs['order_by']) model_list = await pyd_model.from_queryset(model_queryset) if not model_list: raise ORMProcessingError('Model`s items not found') res = jsonable_encoder(model_list) return res
async def create_some(client_key, dict_name, body): """ Универсальная вставка модели """ state = await tortoise_state.state_check() if not state: await tortoise_state.state_activate() class_model = get_orm_class(client_key=client_key, dict_name=dict_name) if not class_model: raise ORMCreateError('Model not found!') pyd_model = pydantic_model_creator(class_model) global_response = [] if isinstance(body, dict): # Вставка одного объекта res = await model_create(ClassOrm=class_model, ClassPyd=pyd_model, data_model=body, soft_insert=False) global_response.append(res) else: # Вставка нескольких объектов for data_mod in body: res = await model_create(ClassOrm=class_model, ClassPyd=pyd_model, data_model=data_mod, soft_insert=True) global_response.append(res) return global_response
async def create_some(client_key, dict_name, body): """ Универсальная вставка модели """ obj_state = await tortoise_state.get(server=gethostname(), pid=getpid()) if not obj_state.state: await Tortoise.init(config=cfg_tortoise.get_tortoise_config()) obj_state.state = True await obj_state.save() class_model = get_orm_class(client_key=client_key, dict_name=dict_name) if not class_model: raise ORMCreateError('Model not found!') pyd_model = pydantic_model_creator(class_model) global_response = [] if isinstance(body, dict): # Вставка одного объекта res = await model_create(ClassOrm=class_model, ClassPyd=pyd_model, data_model=body, soft_insert=False) global_response.append(res) else: # Вставка нескольких объектов for data_mod in body: res = await model_create(ClassOrm=class_model, ClassPyd=pyd_model, data_model=data_mod, soft_insert=True) global_response.append(res) return global_response
async def export(resource: str, query: QueryItem = Depends(get_query), model=Depends(get_model)): qs = model.all() if query.where: qs = qs.filter(**query.where) resource = await app.get_resource(resource) result = await qs creator = pydantic_model_creator( model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields ) data = map(lambda x: creator.from_orm(x).dict(), result) output = io.BytesIO() workbook = xlsxwriter.Workbook(output) worksheet = workbook.add_worksheet() for row, item in enumerate(data): col = 0 for k, v in item.items(): if row == 0: worksheet.write(row, col, k) worksheet.write(row + 1, col, v) col += 1 workbook.close() output.seek(0) return StreamingResponse(output)
class WithPydantic(Model): _pydantic_model = pydantic_model_creator(Model) async def to_pydantic(self): return await self._pydantic_model.from_tortoise_orm(self) async def to_json(self, indent: Optional[int] = None): return (await self.to_pydantic()).json(indent)
async def read_children( current_educator: Educator = Depends(auth.get_current_educator), ): db_children = crud.get_all_child(current_educator.educator_id) if not db_children: raise HTTPException(status.HTTP_404_NOT_FOUND, detail=f"Children not found") ChildPydantic = pydantic_model_creator(Child, exclude=("events", "educator")) return await ChildPydantic.from_queryset(db_children)
async def debug_user(self, ctx: MyContext, who: discord.User): """ Nope! TMI. Spoiler alert. """ player = await self.bot.db.get_player(who) Player_Pydantic = pydantic_model_creator(models.Player) playpy = await Player_Pydantic.from_tortoise_orm(player) await ctx.send(playpy.json(indent=4))
async def create_one(parsed=Depends(parse_body), model=Depends(get_model)): body, resource_fields = parsed m2m_fields = model._meta.m2m_fields creator = pydantic_model_creator(model, include=resource_fields, exclude=m2m_fields) try: obj = await handle_m2m_fields_create_or_update(body, m2m_fields, model, app.user_model) except IntegrityError as e: return JSONResponse(status_code=HTTP_409_CONFLICT, content=dict(msg=f"Create Error,{e}")) return creator.from_orm(obj).dict()
async def read_my_child(current_parent: Parent = Depends(auth.get_current_parent),): db_child = await crud.get_child(current_parent.child_id) if not db_child: raise HTTPException(status.HTTP_404_NOT_FOUND, detail=f"Child not found") ChildPydantic = pydantic_model_creator( Child, exclude=("events", "educator", "parents") ) return await ChildPydantic.from_tortoise_orm(db_child)
async def get_one( id: int, resource: str, model=Depends(get_model) ): obj = await get_object_or_404(model, pk=id) resource = await app.get_resource(resource) include = resource.resource_fields.keys() creator = pydantic_model_creator(model, include=include) return creator.from_orm(obj).dict()
async def run(): await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.generate_schemas() Event_Pydantic = pydantic_model_creator(Event) Event_Pydantic_List = pydantic_queryset_creator(Event) Tournament_Pydantic = pydantic_model_creator(Tournament) Team_Pydantic = pydantic_model_creator(Team) # print(Event_Pydantic_List.schema_json(indent=4)) # print(Event_Pydantic.schema_json(indent=4)) # print(Tournament_Pydantic.schema_json(indent=4)) # print(Team_Pydantic.schema_json(indent=4)) tournament = await Tournament.create(name="New Tournament") tournament2 = await Tournament.create(name="Old Tournament") await Event.create(name="Empty") event = await Event.create(name="Test", tournament=tournament) event2 = await Event.create(name="TestLast", tournament=tournament) event3 = await Event.create(name="Test2", tournament=tournament2) await Address.create(city="Santa Monica", street="Ocean", event=event) await Address.create(city="Somewhere Else", street="Lane", event=event2) team1 = await Team.create(name="Onesies") team2 = await Team.create(name="T-Shirts") team3 = await Team.create(name="Alternates") await event.participants.add(team1, team2, team3) await event2.participants.add(team1, team2) await event3.participants.add(team1, team3) p = await Event_Pydantic.from_tortoise_orm(await Event.get(name="Test")) print("One Event:", p.json(indent=4)) p = await Tournament_Pydantic.from_tortoise_orm( await Tournament.get(name="New Tournament")) print("One Tournament:", p.json(indent=4)) p = await Team_Pydantic.from_tortoise_orm(await Team.get(name="Onesies")) print("One Team:", p.json(indent=4)) pl = await Event_Pydantic_List.from_queryset( Event.filter(address__event_id__isnull=True)) print("All Events without addresses:", pl.json(indent=4))
async def update_bill( bill_id: UUID, bill: BillUpdatePydantic, current_educator: Educator = Depends(auth.get_current_educator), ): await crud.update_bill(bill_id, bill.dict(exclude_defaults=True)) db_bill = await crud.get_bill(bill_id) BillPydantic = pydantic_model_creator( Bill, exclude=("child.educator", "child.events", "child.parents") ) return await BillPydantic.from_tortoise_orm(db_bill)
async def read_bill( bill_id: UUID, current_user: Union[Educator, Parent] = Depends(auth.get_current_user), ): db_bill = await crud.get_bill(bill_id) if not db_bill: raise HTTPException(status.HTTP_404_NOT_FOUND, "bill not found") BillPydantic = pydantic_model_creator( Bill, exclude=("child.educator", "child.events", "child.parents") ) return await BillPydantic.from_tortoise_orm(db_bill)
async def read_child( child_id: UUID, current_user: Union[Educator, Parent] = Depends(auth.get_current_user), ): db_child = await crud.get_child(child_id) if not db_child: raise HTTPException(status.HTTP_404_NOT_FOUND, f"Child {child_id} not found") ChildPydantic = pydantic_model_creator(Child, exclude=("events", "educator")) return await ChildPydantic.from_tortoise_orm(db_child)
async def read_all_bill( current_user: Union[Educator, Parent] = Depends(auth.get_current_user) ): if isinstance(current_user, Parent): db_bill = crud.get_bill_by_child_id(current_user.child_id) else: children_ids = [child.child_id for child in await current_user.children] db_bill = crud.get_bill_by_children_ids(children_ids) BillPydantic = pydantic_model_creator( Bill, exclude=("child.educator", "child.events", "child.parents") ) return await BillPydantic.from_queryset(db_bill)
async def update_child( child_id: UUID, child: ChildCreatePydantic, current_educator: Educator = Depends(auth.get_current_educator), ): if not child.educator_id: child.educator_id = current_educator.educator_id await crud.update_child(child_id, child.dict(exclude_defaults=True)) db_child = await crud.get_child(child_id) ChildPydantic = pydantic_model_creator(Child, exclude=("events", "educator")) return await ChildPydantic.from_tortoise_orm(db_child)
async def get_one(id: int, resource: str, model=Depends(get_model)): obj = await get_object_or_404(model, pk=id) # type:Model m2m_fields = model._meta.m2m_fields resource = await app.get_resource(resource, exclude_m2m_field=False) include = resource.resource_fields.keys() creator = pydantic_model_creator(model, include=include, exclude=m2m_fields) ret = creator.from_orm(obj).dict() for m2m_field in m2m_fields: if m2m_field in include: relate_model = getattr(obj, m2m_field) # type:ManyToManyRelation ids = await relate_model.all().values_list(relate_model.remote_model._meta.pk_attr) ret[m2m_field] = list(map(lambda x: x[0], ids)) ret["__str__"] = str(obj) return ret
async def create_one( resource: str, body=Depends(get_body), model=Depends(get_model) ): resource = await app.get_resource(resource) creator = pydantic_model_creator(model, include=resource.resource_fields.keys()) try: obj = await model.create(**body) except IntegrityError as e: return ORJSONResponse(status_code=HTTP_409_CONFLICT, content=dict( message=f'Create Error,{e}' )) return creator.from_orm(obj).dict()
async def update_one(id: int, parsed=Depends(parse_body), model=Depends(get_model)): body, resource_fields = parsed m2m_fields = model._meta.m2m_fields try: obj = await handle_m2m_fields_create_or_update(body, m2m_fields, model, False, id) except IntegrityError as e: return UJSONResponse(status_code=HTTP_409_CONFLICT, content=dict(message=f"Update Error,{e}")) creator = pydantic_model_creator(model, include=resource_fields, exclude=m2m_fields) return creator.from_orm(obj).dict()
async def create_child( child: ChildCreatePydantic, request: Request, current_educator: Educator = Depends(auth.get_current_educator), ): if not child.educator_id: child.educator_id = current_educator.educator_id placeholder_link = f"{request.base_url}photos/placeholder.jpg" child_dict = child.dict() child_dict["photo_link"] = placeholder_link db_child = await crud.create_child(child_dict) ChildPydantic = pydantic_model_creator(Child, exclude=("events", "educator")) return await ChildPydantic.from_tortoise_orm(db_child)
async def get_resource( resource: str, query: QueryItem = Depends(get_query), model=Depends(get_model) ): qs = model.all() if query.where: qs = qs.filter(**query.where) result = await qs.limit(query.size).offset((query.page - 1) * query.size) resource = await app.get_resource(resource) creator = pydantic_model_creator(model, include=resource.resource_fields.keys()) return GetManyOut( total=await qs.count(), data=list(map(lambda x: creator.from_orm(x).dict(), result)) )
async def update_one( resource: str, id: int, body=Depends(get_body), model=Depends(get_model) ): try: await model.filter(pk=id).update(**body) except IntegrityError as e: return ORJSONResponse(status_code=HTTP_409_CONFLICT, content=dict( message=f'Update Error,{e}' )) user_ = await get_object_or_404(model, pk=id) resource = await app.get_resource(resource, exclude_readonly=True) creator = pydantic_model_creator(model, include=resource.resource_fields.keys()) return creator.from_orm(user_).dict()
async def create_bill( bill: BillCreatePydantic, current_educator: Educator = Depends(auth.get_current_educator), ): BillPydantic = pydantic_model_creator( Bill, exclude=("child.educator", "child.events", "child.parents") ) if bill.child_id: db_bill = await crud.create_bill(bill.dict()) return await BillPydantic.from_tortoise_orm(db_bill) else: children_ids = [child.child_id for child in await current_educator.children] for child_id in children_ids: bill_dict = bill.dict() bill_dict["child_id"] = child_id await crud.create_bill(bill_dict) db_bill = crud.get_bill_by_children_ids(children_ids) return await BillPydantic.from_queryset(db_bill)
async def read_event( child_id: UUID = Query(None), date: datetime.date = Query(...), current_user: Union[Educator, Parent] = Depends(auth.get_current_user), ): if isinstance(current_user, Parent): child_id = current_user.child_id db_event = await crud.get_event(child_id, date) if not db_event: raise HTTPException(status.HTTP_404_NOT_FOUND, f"Event not found") EventPydantic = pydantic_model_creator(Event, exclude=("child", )) event = await EventPydantic.from_tortoise_orm(db_event) event_dict = event.dict() for meal_dict in event_dict["meals"]: meal_dict["rations"] = meal_dict["meal_rations"] del meal_dict["meal_rations"] for ration_dict in meal_dict["rations"]: food_dict = ration_dict["food"] for k, v in food_dict.items(): ration_dict[k] = v del ration_dict["food"] return event_dict
async def get_resource(resource: str, query: QueryItem = Depends(get_query), model=Depends(get_model)): menu = app.model_menu_mapping[resource] qs = model.all() if query.where: qs = qs.filter(**query.where) sort = query.sort for k, v in sort.items(): if k in menu.sort_fields: if v == -1: qs = qs.order_by(f"-{k}") elif v == 1: qs = qs.order_by(k) resource = await app.get_resource(resource) result = await qs.limit(query.size).offset((query.page - 1) * query.size) creator = pydantic_model_creator(model, include=resource.resource_fields.keys(), exclude=model._meta.m2m_fields) return GetManyOut(total=await qs.count(), data=list( map(lambda x: creator.from_orm(x).dict(), result)))
async def run(): await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.generate_schemas() Employee_Pydantic = pydantic_model_creator(Employee) # print(Employee_Pydantic.schema_json(indent=4)) root = await Employee.create(name="Root") loose = await Employee.create(name="Loose") _1 = await Employee.create(name="1. First H1", manager=root) _2 = await Employee.create(name="2. Second H1", manager=root) _1_1 = await Employee.create(name="1.1. First H2", manager=_1) _1_1_1 = await Employee.create(name="1.1.1. First H3", manager=_1_1) _2_1 = await Employee.create(name="2.1. Second H2", manager=_2) _2_2 = await Employee.create(name="2.2. Third H2", manager=_2) await _1.talks_to.add(_2, _1_1_1, loose) await _2_1.gets_talked_to.add(_2_2, _1_1, loose) p = await Employee_Pydantic.from_tortoise_orm(await Employee.get(name="Root")) print(p.json(indent=4))
if user_id is not None: return await cls.get_or_none(id=user_id, deleted_at=None) if email is not None: return await cls.get_or_none(email=email, deleted_at=None) return None @classmethod def create(cls, **kwargs): kwargs["hashed_password"] = auth.get_password_hash(kwargs["password"]) kwargs["refresh_token"] = uuid.uuid4().hex return super().create(**kwargs) def get_access_token(self): return auth.create_access_token(data={ "sub": self.email, "username": self.username }) User_Pydantic = pydantic_model_creator(User, name="User", include=( "email", "username", )) UserIn_Pydantic = pydantic_model_creator(User, name="UserIn", include=("username", ), exclude_readonly=True)
from tortoise.contrib.pydantic import pydantic_model_creator from tortoise.models import Model class Tournament(Model): """ This references a Tournament """ id = fields.IntField(pk=True) name = fields.CharField(max_length=100) #: The date-time the Tournament record was created at created_at = fields.DatetimeField(auto_now_add=True) Tournament_Pydantic = pydantic_model_creator(Tournament) # Print JSON-schema print(Tournament_Pydantic.schema_json(indent=4)) async def run(): await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.generate_schemas() # Create object tournament = await Tournament.create(name="New Tournament") # Serialise it tourpy = await Tournament_Pydantic.from_tortoise_orm(tournament) # As Python dict with Python objects (e.g. datetime)