260705_2
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
"""B03 input_files 테이블의 aiomysql Raw SQL 접근."""
|
||||
|
||||
import json
|
||||
from pathlib import PurePosixPath
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
import aiomysql
|
||||
|
||||
|
||||
async def create_input_file(
|
||||
connection: aiomysql.Connection,
|
||||
*,
|
||||
project_id: UUID,
|
||||
file_type: str,
|
||||
original_filename: str,
|
||||
relative_path: str,
|
||||
file_size_bytes: int,
|
||||
upload_by: int | None,
|
||||
crs_epsg: int | None,
|
||||
metadata: dict[str, Any],
|
||||
) -> int:
|
||||
"""업로드 원본 파일 메타데이터를 저장하고 생성된 ID를 반환한다."""
|
||||
normalized_path = PurePosixPath(relative_path)
|
||||
if normalized_path.is_absolute() or ".." in normalized_path.parts:
|
||||
raise ValueError("DB에는 프로젝트 루트 기준 상대 경로만 저장할 수 있습니다.")
|
||||
if normalized_path.parts[:2] != ("B03_FileInput", "input"):
|
||||
raise ValueError("입력 파일 경로는 B03_FileInput/input 아래여야 합니다.")
|
||||
|
||||
async with connection.cursor() as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
INSERT INTO input_files (
|
||||
project_id,
|
||||
file_type,
|
||||
original_filename,
|
||||
raw_file_path,
|
||||
file_size_mb,
|
||||
upload_by,
|
||||
crs_epsg,
|
||||
metadata,
|
||||
status
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, 'UPLOADED')
|
||||
""",
|
||||
(
|
||||
str(project_id),
|
||||
file_type,
|
||||
original_filename,
|
||||
normalized_path.as_posix(),
|
||||
file_size_bytes / (1024 * 1024),
|
||||
upload_by,
|
||||
crs_epsg,
|
||||
json.dumps(metadata, ensure_ascii=False),
|
||||
),
|
||||
)
|
||||
input_file_id = cursor.lastrowid
|
||||
|
||||
if not input_file_id:
|
||||
raise RuntimeError("input_files 레코드 생성 결과에 ID가 없습니다.")
|
||||
return int(input_file_id)
|
||||
|
||||
|
||||
async def get_project_storage_relative_path(
|
||||
connection: aiomysql.Connection,
|
||||
project_id: UUID,
|
||||
) -> str:
|
||||
"""프로젝트의 검증된 저장소 상대 경로를 조회한다."""
|
||||
async with connection.cursor() as cursor:
|
||||
await cursor.execute(
|
||||
"""
|
||||
SELECT storage_path
|
||||
FROM projects
|
||||
WHERE id = %s AND deleted_at IS NULL
|
||||
""",
|
||||
(str(project_id),),
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
|
||||
if not row or not row[0]:
|
||||
raise LookupError("프로젝트 또는 프로젝트 저장 경로를 찾을 수 없습니다.")
|
||||
|
||||
normalized_path = PurePosixPath(str(row[0]).replace("\\", "/"))
|
||||
if normalized_path.is_absolute() or ".." in normalized_path.parts:
|
||||
raise ValueError("프로젝트 저장 경로는 안전한 상대 경로여야 합니다.")
|
||||
return normalized_path.as_posix()
|
||||
Reference in New Issue
Block a user