feat(root):add mysql
This commit is contained in:
@@ -17,6 +17,7 @@ from celery import shared_task
|
||||
from .AbstractEngine import AbstractEngineClass
|
||||
from ..utils.Models import FilterItem, FilterScope, OutPutType
|
||||
from ..utils.excel_value_maps import EXCEL_VALUE_MAP_REGISTRY
|
||||
from app.repositories.mysql_const_repo import MySQLConstRepository
|
||||
|
||||
|
||||
# def zero_time_data(date, is_max=False):
|
||||
@@ -39,6 +40,7 @@ class MongoEngine(AbstractEngineClass):
|
||||
rows = []
|
||||
stack = []
|
||||
filters = {}
|
||||
_const_cache: dict = None # کش const ها از MySQL
|
||||
|
||||
async def exe(self):
|
||||
_f = self.filters = self.set_filters()
|
||||
@@ -54,7 +56,7 @@ class MongoEngine(AbstractEngineClass):
|
||||
|
||||
if self.input.e and self.input.e.ot:
|
||||
res = await tmp.to_list(None)
|
||||
self.input.e.d = self.generate_output(res)
|
||||
self.input.e.d = await self.generate_output(res)
|
||||
return {'query': _f, 'sort': self.set_sort(), 'path': self.input.e.d}
|
||||
|
||||
self.rows = tmp.limit(self.input.get_limit()).skip(self.input.skip())
|
||||
@@ -257,11 +259,11 @@ class MongoEngine(AbstractEngineClass):
|
||||
def set_joins(self):
|
||||
pass
|
||||
|
||||
def generate_output(self, _f):
|
||||
async def generate_output(self, _f):
|
||||
print(self.input.e.ot)
|
||||
if self.input.e.ot == OutPutType.EXEL:
|
||||
file_name = str(uuid.uuid4().hex) + '.xlsx'
|
||||
return self.output_generator(_f, file_name=file_name, cols=self.input.e.c)
|
||||
return await self.output_generator(_f, file_name=file_name, cols=self.input.e.c)
|
||||
elif self.input.e.ot == OutPutType.JSON:
|
||||
pass
|
||||
elif self.input.e.ot == OutPutType.PDF:
|
||||
@@ -275,7 +277,7 @@ class MongoEngine(AbstractEngineClass):
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
return temp_dir
|
||||
|
||||
def output_generator(self,query, file_name, cols):
|
||||
async def output_generator(self, query, file_name, cols):
|
||||
datas = query
|
||||
file_dir = os.path.join(self._excel_temp_dir(), file_name)
|
||||
head_cols = list(str(string.ascii_uppercase))
|
||||
@@ -293,10 +295,15 @@ class MongoEngine(AbstractEngineClass):
|
||||
|
||||
# ساختن value_maps از vk (نام مپ) با استفاده از رجیستری
|
||||
value_maps = self._build_value_maps()
|
||||
|
||||
# بارگذاری const ها برای فیلدهای خاص
|
||||
const_maps = await self._load_const_maps(headers)
|
||||
|
||||
for row_index, item in enumerate(datas, start=1):
|
||||
for col_index, col in enumerate(headers):
|
||||
val = self.get_nested_value(item, col)
|
||||
val = self._apply_value_map(col, val, value_maps)
|
||||
val = await self._apply_const_map(col, val, const_maps)
|
||||
worksheet.write(row_index, col_index, val)
|
||||
workbook.close()
|
||||
return file_name
|
||||
@@ -328,6 +335,58 @@ class MongoEngine(AbstractEngineClass):
|
||||
return mapping[str(key)]
|
||||
return val
|
||||
|
||||
async def _load_const_maps(self, headers: List[str]) -> dict:
|
||||
"""
|
||||
شناسایی فیلدهای خاص (مثلاً nature_id, type_id, budget_id) و بارگذاری const ها از MySQL.
|
||||
Returns: dict به صورت {col_key: {id: title_fa}} مثلاً {"design.nature_id": {2: "طبیعت 2", ...}}
|
||||
"""
|
||||
# لیست فیلدهای خاص که باید از const خوانده شوند
|
||||
const_field_names = ['nature_id', 'type_id', 'budget_id'] # میتونی اضافه کنی
|
||||
|
||||
const_maps = {}
|
||||
const_keys_to_load = set()
|
||||
const_column_map = {} # {col_key: const_key} مثلاً {"design.nature_id": "nature"}
|
||||
|
||||
# شناسایی ستونهایی که باید const بخونن
|
||||
for col_key in headers:
|
||||
col_name = col_key.split('.')[-1] # آخرین بخش (nature_id)
|
||||
if col_name in const_field_names:
|
||||
const_key = col_name.replace('_id', '') # nature_id -> nature
|
||||
const_keys_to_load.add(const_key)
|
||||
const_column_map[col_key] = const_key
|
||||
|
||||
# بارگذاری const ها از MySQL
|
||||
if const_keys_to_load:
|
||||
repo = MySQLConstRepository()
|
||||
for col_key, const_key in const_column_map.items():
|
||||
consts_for_key = await repo.get_by_key(const_key)
|
||||
if consts_for_key:
|
||||
const_maps[col_key] = consts_for_key
|
||||
|
||||
return const_maps
|
||||
|
||||
async def _apply_const_map(self, col_key: str, val, const_maps: dict):
|
||||
"""اگر این ستون در const_maps باشد، id را به title_fa تبدیل میکند."""
|
||||
if not const_maps or col_key not in const_maps:
|
||||
return val
|
||||
|
||||
mapping = const_maps[col_key]
|
||||
if not isinstance(mapping, dict):
|
||||
return val
|
||||
|
||||
if val is None:
|
||||
return mapping.get(None, val)
|
||||
|
||||
# تبدیل val به int برای جستجو در mapping
|
||||
key = val if isinstance(val, (int, float)) else (int(val) if isinstance(val, str) and str(val).strip().isdigit() else val)
|
||||
|
||||
if key in mapping:
|
||||
return mapping[key]
|
||||
if isinstance(key, int) and str(key) in mapping:
|
||||
return mapping[str(key)]
|
||||
|
||||
return val
|
||||
|
||||
def get_nested_value(self, data, path, default='-'):
|
||||
"""
|
||||
دریافت مقدار از دیکشنری تو در تو با مسیر dot notation
|
||||
|
||||
Reference in New Issue
Block a user