11#!/usr/bin/env python3
22# -*- coding: utf-8 -*-
3- from typing import Any , Generic , Literal , Sequence , Type , TypeVar
3+ from typing import Any , Generic , Iterable , Literal , Sequence , Type , TypeVar
44
55from pydantic import BaseModel
66from sqlalchemy import Row , RowMapping , and_ , asc , desc , or_ , select
@@ -34,6 +34,19 @@ async def create_model(self, session: AsyncSession, obj: _CreateSchema, **kwargs
3434 instance = self .model (** obj .model_dump ())
3535 session .add (instance )
3636
37+ async def create_models (self , session : AsyncSession , obj : Iterable [_CreateSchema ]) -> None :
38+ """
39+ Create new instances of a model
40+
41+ :param session:
42+ :param obj:
43+ :return:
44+ """
45+ instance_list = []
46+ for i in obj :
47+ instance_list .append (self .model (** i .model_dump ()))
48+ session .add_all (instance_list )
49+
3750 async def select_model_by_id (self , session : AsyncSession , pk : int ) -> _Model | None :
3851 """
3952 Query by ID
@@ -102,7 +115,7 @@ async def select_models_order(
102115 self ,
103116 session : AsyncSession ,
104117 * columns ,
105- model_sort : Literal ['skip ' , 'asc' , 'desc' ] = 'skip ' ,
118+ model_sort : Literal ['default ' , 'asc' , 'desc' ] = 'default ' ,
106119 ) -> Sequence [Row | RowMapping | Any ] | None :
107120 """
108121 Query all rows asc or desc
@@ -112,9 +125,6 @@ async def select_models_order(
112125 :param model_sort:
113126 :return:
114127 """
115- if model_sort != 'skip' :
116- if len (columns ) != 1 :
117- raise SelectExpressionError ('ACS and DESC only allow you to specify one column for sorting' )
118128 sort_list = []
119129 for column in columns :
120130 if hasattr (self .model , column ):
@@ -123,7 +133,7 @@ async def select_models_order(
123133 else :
124134 raise ModelColumnError (f'Model column { column } is not found' )
125135 match model_sort :
126- case 'skip ' :
136+ case 'default ' :
127137 query = await session .execute (select (self .model ).order_by (* sort_list ))
128138 case 'asc' :
129139 query = await session .execute (select (self .model ).order_by (asc (* sort_list )))
@@ -135,7 +145,7 @@ async def select_models_order(
135145
136146 async def update_model (self , session : AsyncSession , pk : int , obj : _UpdateSchema | dict [str , Any ], ** kwargs ) -> int :
137147 """
138- Update an instance of a model
148+ Update an instance of model's primary key
139149
140150 :param session:
141151 :param pk:
@@ -152,13 +162,41 @@ async def update_model(self, session: AsyncSession, pk: int, obj: _UpdateSchema
152162 result = await session .execute (sa_update (self .model ).where (self .model .id == pk ).values (** instance_data ))
153163 return result .rowcount # type: ignore
154164
165+ async def update_model_by_column (
166+ self , session : AsyncSession , column : str , column_value : Any , obj : _UpdateSchema | dict [str , Any ], ** kwargs
167+ ) -> int :
168+ """
169+ Update an instance of model column
170+
171+ :param session:
172+ :param column:
173+ :param column_value:
174+ :param obj:
175+ :param kwargs:
176+ :return:
177+ """
178+ if isinstance (obj , dict ):
179+ instance_data = obj
180+ else :
181+ instance_data = obj .model_dump (exclude_unset = True )
182+ if kwargs :
183+ instance_data .update (kwargs )
184+ if hasattr (self .model , column ):
185+ model_column = getattr (self .model , column )
186+ else :
187+ raise ModelColumnError (f'Model column { column } is not found' )
188+ result = await session .execute (
189+ sa_update (self .model ).where (model_column == column_value ).values (** instance_data )
190+ )
191+ return result .rowcount # type: ignore
192+
155193 async def delete_model (self , session : AsyncSession , pk : int , ** kwargs ) -> int :
156194 """
157195 Delete an instance of a model
158196
159197 :param session:
160198 :param pk:
161- :param kwargs:
199+ :param kwargs: for soft deletion only
162200 :return:
163201 """
164202 if not kwargs :
0 commit comments