Обновил дев докер компоуз, работает сводка СА (но там пустые данные)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,6 +16,7 @@ python_parser/app/schemas/test_schemas/test_adapters/__pycache__/
|
|||||||
python_parser/app/schemas/test_schemas/test_app/__pycache__/
|
python_parser/app/schemas/test_schemas/test_app/__pycache__/
|
||||||
|
|
||||||
nin_python_parser
|
nin_python_parser
|
||||||
|
*.pyc
|
||||||
|
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
fastapi:
|
fastapi:
|
||||||
build: ./python_parser
|
image: python:3.11-slim
|
||||||
container_name: svodka_fastapi_dev
|
container_name: svodka_fastapi_dev
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
@@ -24,9 +24,20 @@ services:
|
|||||||
- MINIO_SECRET_KEY=minioadmin
|
- MINIO_SECRET_KEY=minioadmin
|
||||||
- MINIO_SECURE=false
|
- MINIO_SECURE=false
|
||||||
- MINIO_BUCKET=svodka-data
|
- MINIO_BUCKET=svodka-data
|
||||||
|
volumes:
|
||||||
|
# Монтируем исходный код для автоматической перезагрузки
|
||||||
|
- ./python_parser:/app
|
||||||
|
# Монтируем requirements.txt для установки зависимостей
|
||||||
|
- ./python_parser/requirements.txt:/app/requirements.txt
|
||||||
|
working_dir: /app
|
||||||
depends_on:
|
depends_on:
|
||||||
- minio
|
- minio
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
command: >
|
||||||
|
bash -c "
|
||||||
|
pip install --no-cache-dir -r requirements.txt &&
|
||||||
|
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||||
|
"
|
||||||
|
|
||||||
streamlit:
|
streamlit:
|
||||||
image: python:3.11-slim
|
image: python:3.11-slim
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -17,7 +17,7 @@ class SvodkaCAParser(ParserPort):
|
|||||||
# Используем схемы Pydantic как единый источник правды
|
# Используем схемы Pydantic как единый источник правды
|
||||||
register_getter_from_schema(
|
register_getter_from_schema(
|
||||||
parser_instance=self,
|
parser_instance=self,
|
||||||
getter_name="get_data",
|
getter_name="get_ca_data",
|
||||||
method=self._get_data_wrapper,
|
method=self._get_data_wrapper,
|
||||||
schema_class=SvodkaCARequest,
|
schema_class=SvodkaCARequest,
|
||||||
description="Получение данных по режимам и таблицам"
|
description="Получение данных по режимам и таблицам"
|
||||||
@@ -31,16 +31,74 @@ class SvodkaCAParser(ParserPort):
|
|||||||
modes = validated_params["modes"]
|
modes = validated_params["modes"]
|
||||||
tables = validated_params["tables"]
|
tables = validated_params["tables"]
|
||||||
|
|
||||||
# TODO: Переделать под новую архитектуру
|
# Проверяем, есть ли данные в data_dict (из парсинга) или в df (из загрузки)
|
||||||
data_dict = {}
|
if hasattr(self, 'data_dict') and self.data_dict is not None:
|
||||||
|
# Данные из парсинга
|
||||||
|
data_source = self.data_dict
|
||||||
|
elif hasattr(self, 'df') and self.df is not None and not self.df.empty:
|
||||||
|
# Данные из загрузки - преобразуем DataFrame обратно в словарь
|
||||||
|
data_source = self._df_to_data_dict()
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
# Фильтруем данные по запрошенным режимам и таблицам
|
||||||
|
result_data = {}
|
||||||
for mode in modes:
|
for mode in modes:
|
||||||
data_dict[mode] = self.get_data(self.df, mode, tables)
|
if mode in data_source:
|
||||||
return self.data_dict_to_json(data_dict)
|
result_data[mode] = {}
|
||||||
|
for table_name, table_data in data_source[mode].items():
|
||||||
|
if table_name in tables:
|
||||||
|
result_data[mode][table_name] = table_data
|
||||||
|
|
||||||
|
return result_data
|
||||||
|
|
||||||
|
def _df_to_data_dict(self):
|
||||||
|
"""Преобразование DataFrame обратно в словарь данных"""
|
||||||
|
if not hasattr(self, 'df') or self.df is None or self.df.empty:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
data_dict = {}
|
||||||
|
|
||||||
|
# Группируем данные по режимам и таблицам
|
||||||
|
for _, row in self.df.iterrows():
|
||||||
|
mode = row.get('mode')
|
||||||
|
table = row.get('table')
|
||||||
|
data = row.get('data')
|
||||||
|
|
||||||
|
if mode and table and data is not None:
|
||||||
|
if mode not in data_dict:
|
||||||
|
data_dict[mode] = {}
|
||||||
|
data_dict[mode][table] = data
|
||||||
|
|
||||||
|
return data_dict
|
||||||
|
|
||||||
def parse(self, file_path: str, params: dict) -> pd.DataFrame:
|
def parse(self, file_path: str, params: dict) -> pd.DataFrame:
|
||||||
"""Парсинг файла и возврат DataFrame"""
|
"""Парсинг файла и возврат DataFrame"""
|
||||||
# Сохраняем DataFrame для использования в геттерах
|
# Парсим данные и сохраняем словарь для использования в геттерах
|
||||||
self.df = self.parse_svodka_ca(file_path, params)
|
self.data_dict = self.parse_svodka_ca(file_path, params)
|
||||||
|
|
||||||
|
# Преобразуем словарь в DataFrame для совместимости с services.py
|
||||||
|
# Создаем простой DataFrame с информацией о загруженных данных
|
||||||
|
if self.data_dict:
|
||||||
|
# Создаем DataFrame с информацией о режимах и таблицах
|
||||||
|
data_rows = []
|
||||||
|
for mode, tables in self.data_dict.items():
|
||||||
|
for table_name, table_data in tables.items():
|
||||||
|
if table_data:
|
||||||
|
data_rows.append({
|
||||||
|
'mode': mode,
|
||||||
|
'table': table_name,
|
||||||
|
'rows_count': len(table_data),
|
||||||
|
'data': table_data
|
||||||
|
})
|
||||||
|
|
||||||
|
if data_rows:
|
||||||
|
df = pd.DataFrame(data_rows)
|
||||||
|
self.df = df
|
||||||
|
return df
|
||||||
|
|
||||||
|
# Если данных нет, возвращаем пустой DataFrame
|
||||||
|
self.df = pd.DataFrame()
|
||||||
return self.df
|
return self.df
|
||||||
|
|
||||||
def parse_svodka_ca(self, file_path: str, params: dict) -> dict:
|
def parse_svodka_ca(self, file_path: str, params: dict) -> dict:
|
||||||
@@ -147,12 +205,22 @@ class SvodkaCAParser(ParserPort):
|
|||||||
# Сортируем по индексу (id) и по столбцу 'table'
|
# Сортируем по индексу (id) и по столбцу 'table'
|
||||||
combined_df = combined_df.sort_values(by=['id', 'table'], axis=0)
|
combined_df = combined_df.sort_values(by=['id', 'table'], axis=0)
|
||||||
|
|
||||||
# Устанавливаем id как индекс
|
# Преобразуем DataFrame в словарь по режимам и таблицам
|
||||||
# combined_df.set_index('id', inplace=True)
|
# Для сводки СА у нас есть только один режим - 'fact' (по умолчанию)
|
||||||
|
# Но нужно определить режим из данных или параметров
|
||||||
return combined_df
|
mode = params.get('mode', 'fact') # По умолчанию 'fact'
|
||||||
|
|
||||||
|
data_dict = {mode: {}}
|
||||||
|
|
||||||
|
# Группируем данные по таблицам
|
||||||
|
for table_name, group_df in combined_df.groupby('table'):
|
||||||
|
# Удаляем колонку 'table' из результата
|
||||||
|
table_data = group_df.drop('table', axis=1)
|
||||||
|
data_dict[mode][table_name] = table_data.to_dict('records')
|
||||||
|
|
||||||
|
return data_dict
|
||||||
else:
|
else:
|
||||||
return None
|
return {}
|
||||||
|
|
||||||
def extract_all_tables(self, file_path, sheet_name=0):
|
def extract_all_tables(self, file_path, sheet_name=0):
|
||||||
"""Извлечение всех таблиц из Excel файла"""
|
"""Извлечение всех таблиц из Excel файла"""
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -106,19 +106,38 @@ class ReportService:
|
|||||||
# Получаем параметры запроса
|
# Получаем параметры запроса
|
||||||
get_params = request.get_params or {}
|
get_params = request.get_params or {}
|
||||||
|
|
||||||
# Определяем имя геттера из параметра mode
|
# Для svodka_ca определяем режим из данных или используем 'fact' по умолчанию
|
||||||
getter_name = get_params.pop("mode", None)
|
if request.report_type == 'svodka_ca':
|
||||||
if not getter_name:
|
# Извлекаем режим из DataFrame или используем 'fact' по умолчанию
|
||||||
# Если режим не указан, берем первый доступный
|
if hasattr(parser, 'df') and parser.df is not None and not parser.df.empty:
|
||||||
available_getters = list(parser.getters.keys())
|
modes_in_df = parser.df['mode'].unique() if 'mode' in parser.df.columns else ['fact']
|
||||||
if available_getters:
|
# Используем первый найденный режим или 'fact' по умолчанию
|
||||||
getter_name = available_getters[0]
|
default_mode = modes_in_df[0] if len(modes_in_df) > 0 else 'fact'
|
||||||
print(f"⚠️ Режим не указан, используем первый доступный: {getter_name}")
|
|
||||||
else:
|
else:
|
||||||
return DataResult(
|
default_mode = 'fact'
|
||||||
success=False,
|
|
||||||
message="Парсер не имеет доступных геттеров"
|
# Устанавливаем режим в параметры, если он не указан
|
||||||
)
|
if 'mode' not in get_params:
|
||||||
|
get_params['mode'] = default_mode
|
||||||
|
|
||||||
|
# Определяем имя геттера
|
||||||
|
if request.report_type == 'svodka_ca':
|
||||||
|
# Для svodka_ca используем геттер get_ca_data
|
||||||
|
getter_name = 'get_ca_data'
|
||||||
|
else:
|
||||||
|
# Для других парсеров определяем из параметра mode
|
||||||
|
getter_name = get_params.pop("mode", None)
|
||||||
|
if not getter_name:
|
||||||
|
# Если режим не указан, берем первый доступный
|
||||||
|
available_getters = list(parser.getters.keys())
|
||||||
|
if available_getters:
|
||||||
|
getter_name = available_getters[0]
|
||||||
|
print(f"⚠️ Режим не указан, используем первый доступный: {getter_name}")
|
||||||
|
else:
|
||||||
|
return DataResult(
|
||||||
|
success=False,
|
||||||
|
message="Парсер не имеет доступных геттеров"
|
||||||
|
)
|
||||||
|
|
||||||
# Получаем значение через указанный геттер
|
# Получаем значение через указанный геттер
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user