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