оптимизация работы с БД

This commit is contained in:
2025-12-06 13:48:42 +03:00
parent f07843de5a
commit 54bf21d52d
8 changed files with 80 additions and 63 deletions
+17 -17
View File
@@ -22,47 +22,47 @@ class CRUD:
is_lst = isinstance(db_data, list)
async with SessionLocal() as db:
if is_lst:
logger.info(f"Создаю {len(db_data)} записей")
logger.debug(f"Создаю {len(db_data)} записей")
try:
db.add_all(db_data)
except InvalidRequestError:
for data in db_data:
await db.merge(data)
else:
logger.info("Создаю запись")
logger.debug("Создаю запись")
db.add(db_data)
await db.commit()
if refresh:
if is_lst:
logger.info(f"Обновляю {len(db_data)} записей")
logger.debug(f"Обновляю {len(db_data)} записей")
for data in db_data:
await db.refresh(data)
else:
logger.info("Обновляю запись")
logger.debug("Обновляю запись")
await db.refresh(db_data)
logger.info("Запись создана")
logger.debug("Запись создана")
return db_data if refresh else None
except Exception as e:
logger.error(f"Ошибка создания: {str(e)}", exc_info=True)
logger.error(f"Ошибка создания: {str(e)}", exc_debug=True)
return None
async def read(query, all: bool = False):
try:
async with SessionLocal() as db:
logger.info(f"Чтение записей. Все: {all}")
logger.debug(f"Чтение записей. Все: {all}")
results = await db.execute(query)
logger.info(f"Чтение завершено")
logger.debug(f"Чтение завершено")
return (
results.unique().scalars().all()
if all
else results.unique().scalars().first()
)
except Exception as e:
logger.error(f"Ошибка чтения: {str(e)}", exc_info=True)
logger.error(f"Ошибка чтения: {str(e)}", exc_debug=True)
return None
async def delete(db_data) -> bool:
def itemInfo(instance):
def itemdebug(instance):
from sqlalchemy import inspect
state = inspect(instance)
@@ -78,7 +78,7 @@ class CRUD:
return {"key": pKey, "value": pValue, "class": instance.__class__}
async def deleteFromDB(data, db):
itemData = itemInfo(data)
itemData = itemdebug(data)
query = delete(itemData["class"]).where(
getattr(itemData["class"], itemData["key"]) == itemData["value"]
)
@@ -87,18 +87,18 @@ class CRUD:
async with SessionLocal() as db:
try:
if isinstance(db_data, list):
logger.info(f"Удаляю записей: {len(db_data)}")
logger.debug(f"Удаляю записей: {len(db_data)}")
for data in db_data:
await deleteFromDB(data, db)
else:
logger.info("Удаляю запись")
logger.debug("Удаляю запись")
await deleteFromDB(db_data, db)
await db.commit()
logger.info("Запись удалена")
logger.debug("Запись удалена")
return True
except Exception as e:
await db.rollback()
logger.error(f"Ошибка удаления: {str(e)}", exc_info=True)
logger.error(f"Ошибка удаления: {str(e)}", exc_debug=True)
return False
async def update(db_data, id, **kwargs):
@@ -107,9 +107,9 @@ class CRUD:
query = update(db_data).where(db_data.id == id).values(**kwargs)
item = await db.execute(query)
await db.commit()
logger.info("Запись обновлена")
logger.debug("Запись обновлена")
return await db.get(db_data, id)
except Exception as e:
await db.rollback()
logger.error(f"Ошибка обновления: {str(e)}", exc_info=True)
logger.error(f"Ошибка обновления: {str(e)}", exc_debug=True)
return None
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+58 -36
View File
@@ -6,6 +6,7 @@ from db.handlers.user import UserHandler
from db.handlers.access import AccessLevelHandler
from db.handlers.records import StocksRecordsHandler
from db.schemas.records import StocksRecords
from utils import logger
@@ -47,7 +48,7 @@ class StocksActions:
reason=reason,
quantity=quantity,
price=price,
return_record_id=True,
return_record=True,
)
logger.info(
f"Оприходование инструмента {toolkit_id} на складе {toolbox_id} прошло {'успешно' if recorded else 'не успешно'}"
@@ -124,6 +125,9 @@ class StocksActions:
)
if not target_toolbox_id:
logger.warning(
f"Производится списание инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {takeQuantity} по цене {stock['price']}"
)
continue
existing = await StockHandler.getByToolboxIdAndToolkitIdAndQPrice(
@@ -165,23 +169,23 @@ class StocksActions:
f"Изменение остатков инструмента {toolkit_id} на склад {target_toolbox_id} по цене {stock['price']} успешно завершено"
)
recorded = await StocksRecordsHandler.add(
action=action,
source_stock_id=stock["id"],
target_stock_id=targetStock.get("id"),
source_toolbox_id=source_toolbox_id,
target_toolbox_id=target_toolbox_id,
toolkit_id=toolkit_id,
init_user_id=user_id,
reason=reason,
quantity=quantity,
price=stock["price"],
)
if not recorded:
logger.error(
f"Ошибка создания записи о {action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id}"
)
return False
# recorded = await StocksRecordsHandler.add(
# action=action,
# source_stock_id=stock["id"],
# target_stock_id=targetStock.get("id"),
# source_toolbox_id=source_toolbox_id,
# target_toolbox_id=target_toolbox_id,
# toolkit_id=toolkit_id,
# init_user_id=user_id,
# reason=reason,
# quantity=quantity,
# price=stock["price"],
# )
# if not recorded:
# logger.error(
# f"Ошибка создания записи о {action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id}"
# )
# return False
logger.info(
f"{action} инструмента {toolkit_id} со склада {source_toolbox_id} на склад {target_toolbox_id} прошло успешно"
@@ -197,7 +201,7 @@ class StocksActions:
reason: str,
user_id: int,
price: int = 0,
return_record_id: bool = False,
return_record: bool = False,
):
logger.info(
f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} ..."
@@ -213,18 +217,28 @@ class StocksActions:
reason=reason,
quantity=quantity,
price=price,
return_record_id=return_record_id,
return_record=return_record,
)
logger.info(
f"Запрос на {action} инструмента {toolkit_id} со склада {source_toolbox_id} в количестве {quantity} по цене {price} {'успешно завершен' if recorded else 'завершен с ошибкой'}"
)
return recorded
async def movingDecision(record_id: int, user_id: int, accepted: bool = True):
async def movingDecision(
record_id: int,
user_id: int,
accepted: bool = True,
record: StocksRecords = None,
):
logger.info(
f"{'Принятие' if accepted else 'Отклонение'} записи о движении инструмента {record_id} ..."
f"{'Принятие' if accepted else 'Отклонение'} записи {record_id if not record else record.id} о движении инструмента {'' if not record else record.toolkit_id} ..."
)
movingRecord = await StocksRecordsHandler.getById(record_id, True)
movingRecord = (
await StocksRecordsHandler.getById(record_id, True)
if not record
else record
)
if not movingRecord:
logger.error(f"Запись {record_id} не найдена")
return False
@@ -235,7 +249,7 @@ class StocksActions:
return False
if not accepted:
return await StocksRecordsHandler.decide(
record_id,
movingRecord,
user_id,
movingRecord.source_stock_id,
movingRecord.quantity,
@@ -264,7 +278,7 @@ class StocksActions:
return False
accept = await StocksRecordsHandler.decide(
record_id,
movingRecord,
user_id,
stocksMovements[0].get("id"),
stocksMovements[0].get("quantity"),
@@ -288,12 +302,12 @@ class StocksActions:
reason=movingRecord.reason,
quantity=stock.get("quantity"),
price=stock.get("price"),
return_record_id=True,
return_record=True,
)
if not recorded:
return False
accept = await StocksRecordsHandler.decide(
record_id=recorded,
record=recorded,
decision_user_id=user_id,
source_stock_id=stock.get("id"),
quantity=stock.get("quantity"),
@@ -329,7 +343,7 @@ class StocksActions:
user_id=user_id,
reason=reason,
price=price,
return_record_id=True,
return_record=True,
)
if not takeRequest:
logger.error(
@@ -340,16 +354,16 @@ class StocksActions:
f"Формирование запроса на получение инструмента {toolkit_id} успешно завершено"
)
logger.info(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} ..."
f"Принятие запроса {takeRequest.id} на получение инструмента {toolkit_id} ..."
)
accepted = await StocksActions.movingDecision(takeRequest, user_id)
accepted = await StocksActions.movingDecision(None, user_id, record=takeRequest)
if not accepted:
logger.error(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} не удалось"
f"Принятие запроса {takeRequest.id} на получение инструмента {toolkit_id} не удалось"
)
return False
logger.info(
f"Принятие запроса {takeRequest} на получение инструмента {toolkit_id} успешно завершено"
f"Принятие запроса {takeRequest.id} на получение инструмента {toolkit_id} успешно завершено"
)
return True
@@ -498,7 +512,7 @@ class StocksActions:
quantity=random.randint(3, 5),
reason=f"{action} инструмента {toolkit.get('title')}. После выполнения заказа",
user_id=user.get("id"),
return_record_id=True,
return_record=True,
)
if not success:
logger.error(
@@ -522,6 +536,7 @@ class StocksActions:
"manager": {"accept": [], "reject": [], "ignore": []},
"storekeeper": {"accept": [], "reject": [], "ignore": []},
}
logger.info("Разбивка списоков запросов ...")
for recordsList in requestsDict.values():
managerList, storekeeperList = (
recordsList[: len(recordsList) // 2],
@@ -550,9 +565,12 @@ class StocksActions:
storekeeperList[len(storekeeperList) // 3 * 2 :],
)
logger.warning("Применение решений ...")
for role in decisionsDict.keys():
logger.warning(f"Принятие записей пользователем {role} ...")
user_id = usersDict.get(role)
for decision in decisionsDict.get(role).keys():
logger.warning(f"Принятие решения {decision} пользователем {role} ...")
match decision:
case "accept":
accepted = True
@@ -560,15 +578,19 @@ class StocksActions:
accepted = False
case "ignore":
continue
for record_id in decisionsDict.get(role).get(decision):
for record in decisionsDict.get(role).get(decision):
logger.info(
f"{'Принятие' if accepted else 'Отклонение'} записи {record.id} пользователем {role} ... "
)
success = await StocksActions.movingDecision(
record_id=record_id,
record_id=None,
user_id=user_id,
accepted=accepted,
record=record,
)
if not success:
logger.error(
f"Принятие записи {record_id} пользователем {role} не удалось"
f"{'Принятие' if accepted else 'Отклонение'} записи {record.id} пользователем {role} не удалось"
)
return False
+5 -9
View File
@@ -20,7 +20,7 @@ class StocksRecordsHandler:
price: float,
source_toolbox_id: int = None,
target_toolbox_id: int = None,
return_record_id: bool = False,
return_record: bool = False,
):
recordData = {
"action": action,
@@ -40,13 +40,13 @@ class StocksRecordsHandler:
record = StocksRecords(**recordData)
await record.save()
logger.info(f"Запись успешно создана, id: {record.id}")
return True if not return_record_id else record.id
return True if not return_record else record
except Exception as e:
logger.error(f"Ошибка создания записи: {str(e)}")
return False
async def decide(
record_id: int,
record: StocksRecords,
decision_user_id: int,
source_stock_id: int,
quantity: int,
@@ -55,12 +55,8 @@ class StocksRecordsHandler:
):
try:
logger.info(
f"{'Принятие' if accept else 'Отклонение'} записи {record_id} от {decision_user_id}"
f"{'Принятие' if accept else 'Отклонение'} записи {record.id} от {decision_user_id}"
)
record = await StocksRecordsHandler.getById(record_id, record=True)
if not record:
logger.error(f"Запись {record_id} не найдена")
return False
record.decision_user_id = decision_user_id
record.decided_at = datetime.now()
record.source_stock_id = source_stock_id
@@ -69,7 +65,7 @@ class StocksRecordsHandler:
record.accepted = accept
await record.save()
logger.info(
f"Запись {record_id} успешно {'принята' if accept else 'отклонена'} {decision_user_id} в {record.decided_at.strftime('%Y-%m-%d %H:%M:%S')}"
f"Запись {record.id} успешно {'принята' if accept else 'отклонена'} {decision_user_id} в {record.decided_at.strftime('%Y-%m-%d %H:%M:%S')}"
)
return True
except Exception as e:
-1
View File
@@ -197,7 +197,6 @@ class UserHandler:
acessLevels = {
accessLevel["title"]: accessLevel["id"] for accessLevel in accessLevelsList
}
logger.info(acessLevels)
password = "Alex0172"
baseUsers = {
"admin": {