diff --git a/fastapi-app-upload/main.py b/fastapi-app-upload/main.py index 88bb5b9..3a20367 100644 --- a/fastapi-app-upload/main.py +++ b/fastapi-app-upload/main.py @@ -1,3 +1,4 @@ +import uvicorn from fastapi import FastAPI from contextlib import asynccontextmanager @@ -6,7 +7,6 @@ from database.database import create_tables, delete_tables from routers.uploaded_file_router import router as csv_router - @asynccontextmanager async def lifespan(app: FastAPI): await delete_tables() @@ -16,7 +16,8 @@ async def lifespan(app: FastAPI): yield print("Выключение") - app = FastAPI(lifespan=lifespan) app.include_router(csv_router) +if __name__ == '__main__': + uvicorn.run(app, host='localhost', port=8000) diff --git a/fastapi-app-upload/repositories/uploaded_file_repository.py b/fastapi-app-upload/repositories/uploaded_file_repository.py index b830ef8..c5c0a69 100644 --- a/fastapi-app-upload/repositories/uploaded_file_repository.py +++ b/fastapi-app-upload/repositories/uploaded_file_repository.py @@ -1,12 +1,37 @@ +import os +import pandas as pd # импортируем pandas для работы с CSV +from sqlalchemy import select # импортируем select для работы с SQLAlchemy +from sqlalchemy.ext.asyncio import AsyncSession +from fastapi import HTTPException from database.database import new_session -from database.enums.type_file import FileType from database.models.uploaded_file import UploadedFile +from database.enums.type_file import FileType class UploadedFileRepository: @staticmethod async def upload_file(user_id: int, user_name: str, file_path: str, file_name: str, file_type: FileType, file_size: float): + """Загружает информацию о файле в базу данных.""" async with new_session() as session: - csv_file = UploadedFile(user_id=user_id, user_name=user_name, file_path=file_path, file_name=file_name, file_type=file_type, file_size=file_size ) + csv_file = UploadedFile( + user_id=user_id, + user_name=user_name, + file_path=file_path, + file_name=file_name, + file_type=file_type, + file_size=file_size + ) session.add(csv_file) - await session.commit() \ No newline at end of file + await session.commit() + + @staticmethod + async def get_file_by_user_and_name(user_id: int, file_name: str): + """Получает информацию о файле из базы данных по пользователю и имени файла.""" + async with new_session() as session: + result = await session.execute( + select(UploadedFile).where( + UploadedFile.user_id == user_id, + UploadedFile.file_name == file_name + ) + ) + return result.scalars().first() \ No newline at end of file diff --git a/fastapi-app-upload/routers/uploaded_file_router.py b/fastapi-app-upload/routers/uploaded_file_router.py index 91af5e6..dda65cf 100644 --- a/fastapi-app-upload/routers/uploaded_file_router.py +++ b/fastapi-app-upload/routers/uploaded_file_router.py @@ -1,7 +1,8 @@ import os -from fastapi import APIRouter, UploadFile, File, Form, HTTPException +from fastapi import APIRouter, UploadFile, File, Form, HTTPException, Query from pathlib import Path -from database.database import new_session +import pandas as pd + import shutil from database.enums.type_file import FileType from repositories.uploaded_file_repository import UploadedFileRepository @@ -48,3 +49,48 @@ async def upload_file(user_id: int, user_name: str, file: UploadFile = File(...) return {"message": "Файл успешно загружен", "file_path": str(file_path), "file_size_MB": round(file_size, 2)} + +@router.get("/csv/rows/") +async def get_csv_rows( + user_id: int, + file_name: str, + start_row: int, + end_row: int +): + # Проверка существования файла в базе данных + uploaded_file = await UploadedFileRepository.get_file_by_user_and_name(user_id, file_name) + if not uploaded_file: + raise HTTPException(status_code=404, detail=f"Файл '{file_name}' не найден для пользователя '{user_id}'") + + file_path = Path(uploaded_file.file_path) # Путь к файлу из базы данных + + # Проверка существования файла на диске + if not file_path.exists(): + raise HTTPException(status_code=404, detail=f"Файл '{file_name}' не найден на сервере.") + + # Чтение файла с использованием pandas + try: + if file_name.endswith(".xlsx"): + df = pd.read_excel(file_path) + elif file_name.endswith(".csv"): + df = pd.read_csv(file_path) + else: + raise HTTPException(status_code=400, detail="Неподдерживаемый формат файла") + + # Заменяем NaN на None или другие значения перед отправкой данных + df = df.where(pd.notnull(df), None) + + rows = df.iloc[start_row:end_row].to_dict(orient="records") + + # Преобразуем значения NaN в None + rows = [ + {key: (None if value != value else value) for key, value in row.items()} + for row in rows + ] + + return {"rows": rows} + + except Exception as e: + raise HTTPException(status_code=500, detail=f"Ошибка при чтении файла: {str(e)}") + + diff --git a/fastapi-app-upload/schemas/uploaded_file_upload.py b/fastapi-app-upload/schemas/uploaded_file_upload.py index 45657b3..e69de29 100644 --- a/fastapi-app-upload/schemas/uploaded_file_upload.py +++ b/fastapi-app-upload/schemas/uploaded_file_upload.py @@ -1,7 +0,0 @@ -from pydantic import BaseModel -from datetime import datetime -from typing import Optional - -# CSVFileUpload: для загрузки CSV файла -class UploadedFile(BaseModel): - file_path: str \ No newline at end of file