|
@@ -1,7 +1,7 @@
|
|
#!/usr/bin/env python3
|
|
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
-from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect
|
|
|
|
|
|
+from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect,UploadFile,File
|
|
from common.security import valid_access_token,valid_websocket_token
|
|
from common.security import valid_access_token,valid_websocket_token
|
|
from fastapi.responses import JSONResponse,StreamingResponse
|
|
from fastapi.responses import JSONResponse,StreamingResponse
|
|
from common.db import db_czrz
|
|
from common.db import db_czrz
|
|
@@ -21,6 +21,9 @@ from utils.resource_provision_util import *
|
|
from common.websocketManager import *
|
|
from common.websocketManager import *
|
|
import json
|
|
import json
|
|
import traceback
|
|
import traceback
|
|
|
|
+import pandas as pd
|
|
|
|
+from io import BytesIO
|
|
|
|
+import openpyxl
|
|
|
|
|
|
router = APIRouter()
|
|
router = APIRouter()
|
|
|
|
|
|
@@ -41,6 +44,7 @@ def get_data_field(table_id: int, db: Session = Depends(get_db)):
|
|
AND COLUMN_NAME NOT IN :ignore_fields order by ORDINAL_POSITION
|
|
AND COLUMN_NAME NOT IN :ignore_fields order by ORDINAL_POSITION
|
|
""")
|
|
""")
|
|
columns_result = db.execute(columns_query, {
|
|
columns_result = db.execute(columns_query, {
|
|
|
|
+ "layer_name": info.layer_name,
|
|
"schema_name": info.database_name,
|
|
"schema_name": info.database_name,
|
|
"table_name": info.table_name,
|
|
"table_name": info.table_name,
|
|
"ignore_fields": tuple(ignore_fields_list)
|
|
"ignore_fields": tuple(ignore_fields_list)
|
|
@@ -210,7 +214,72 @@ async def delete_data(table_id: int, data_id: int, db: Session = Depends(get_db)
|
|
traceback.print_exc()
|
|
traceback.print_exc()
|
|
return JSONResponse(status_code=500, content={'code': 500, 'msg': f"接口发生错误:{e}"})
|
|
return JSONResponse(status_code=500, content={'code': 500, 'msg': f"接口发生错误:{e}"})
|
|
|
|
|
|
-def get_data_info():
|
|
|
|
- pass
|
|
|
|
-def insert_data():
|
|
|
|
- pass
|
|
|
|
|
|
+
|
|
|
|
+@router.get("/generate_import_template/{table_id}")
|
|
|
|
+async def generate_import_template(table_id: int, db: Session = Depends(get_db)):
|
|
|
|
+ # 获取表结构
|
|
|
|
+ table_structure = get_data_field(table_id, db)
|
|
|
|
+ columns = table_structure["columns"]
|
|
|
|
+ layer_name = table_structure["layer_name"]
|
|
|
|
+
|
|
|
|
+ # 创建 DataFrame column_name
|
|
|
|
+ data = [{col["column_comment"]:col['column_name']} for col in columns]
|
|
|
|
+ column_names = [col["column_comment"] for col in columns]
|
|
|
|
+ df = pd.DataFrame(data=data,columns=column_names)
|
|
|
|
+
|
|
|
|
+ # 将 DataFrame 转换为 Excel 文件
|
|
|
|
+ output = BytesIO()
|
|
|
|
+ with pd.ExcelWriter(output, engine="openpyxl") as writer:
|
|
|
|
+ df.to_excel(writer, index=False, sheet_name=layer_name)
|
|
|
|
+
|
|
|
|
+ # 设置响应头
|
|
|
|
+ output.seek(0)
|
|
|
|
+ headers = {
|
|
|
|
+ "Content-Disposition": f"attachment; filename=import_template_{table_structure['table_name']}.xlsx",
|
|
|
|
+ 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
|
|
+ }
|
|
|
|
+ return StreamingResponse(output, headers=headers,
|
|
|
|
+ media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# 数据批量导入
|
|
|
|
+@router.post("/import_data/{table_id}")
|
|
|
|
+async def import_data(table_id: int, file: UploadFile = File(...), db: Session = Depends(get_db)):
|
|
|
|
+ # 获取表结构
|
|
|
|
+ table_structure = get_data_field(table_id, db)
|
|
|
|
+ table_name = table_structure["table_name"]
|
|
|
|
+ schema_name = table_structure["schema_name"]
|
|
|
|
+ columns = table_structure["columns"]
|
|
|
|
+
|
|
|
|
+ # 读取 Excel 文件
|
|
|
|
+ try:
|
|
|
|
+ workbook = openpyxl.load_workbook(file.file)
|
|
|
|
+ sheet = workbook.active
|
|
|
|
+ except Exception as e:
|
|
|
|
+ raise HTTPException(status_code=400, detail="Invalid Excel file")
|
|
|
|
+
|
|
|
|
+ # 获取字段名和字段备注名
|
|
|
|
+ column_names = [col["column_name"] for col in columns]
|
|
|
|
+ column_comments = [col["column_comment"] for col in columns]
|
|
|
|
+
|
|
|
|
+ # 检查第一行是否为字段备注名
|
|
|
|
+ first_row = [cell.value for cell in sheet[1]]
|
|
|
|
+ if first_row != column_comments:
|
|
|
|
+ raise HTTPException(status_code=400, detail="Excel columns do not match the expected columns")
|
|
|
|
+
|
|
|
|
+ # 检查第二行是否为字段名
|
|
|
|
+ second_row = [cell.value for cell in sheet[2]]
|
|
|
|
+ if second_row != column_names:
|
|
|
|
+ raise HTTPException(status_code=400, detail="Excel columns do not match the expected columns")
|
|
|
|
+
|
|
|
|
+ # 将数据插入到数据库
|
|
|
|
+ try:
|
|
|
|
+ insert_query = text(
|
|
|
|
+ f"INSERT INTO `{schema_name}`.`{table_name}` ({', '.join(column_names)}) VALUES ({', '.join([':' + col for col in column_names])})")
|
|
|
|
+ for row in sheet.iter_rows(min_row=3, values_only=True):
|
|
|
|
+ db.execute(insert_query, dict(zip(column_names, row)))
|
|
|
|
+ db.commit()
|
|
|
|
+ return {"message": "Data imported successfully"}
|
|
|
|
+ except Exception as e:
|
|
|
|
+ db.rollback()
|
|
|
|
+ raise HTTPException(status_code=500, detail=str(e))
|