导入文件建表接口

This commit is contained in:
lhx
2025-09-26 17:19:58 +08:00
parent 18478b148a
commit 52d2753824
6 changed files with 735 additions and 5 deletions

View File

@@ -3,6 +3,7 @@ from sqlalchemy import text, MetaData, Table, Column, create_engine, inspect
from sqlalchemy.exc import SQLAlchemyError
from typing import List, Dict, Any, Optional
from ..core.database import engine
from ..utils.file_import import FileImportUtils
import pandas as pd
class DatabaseService:
@@ -193,4 +194,114 @@ class DatabaseService:
# 排除mysql的系统表和accounts表
return [table for table in inspector.get_table_names() if not table.startswith('mysql') and table != 'accounts']
except Exception as e:
return []
return []
@staticmethod
def import_file_to_database(db: Session, filename: str, file_content: str,
table_name: Optional[str] = None,
force_overwrite: bool = False) -> Dict[str, Any]:
"""从文件导入数据到数据库"""
try:
# 解析文件内容
file_data = FileImportUtils.parse_file(filename, file_content)
if not file_data:
return {
"success": False,
"message": "文件中没有找到有效数据"
}
results = []
inspector = inspect(engine)
existing_tables = inspector.get_table_names()
for item in file_data:
final_table_name = table_name if table_name else item["table_name"]
data = item["data"]
columns = item["columns"]
if not data:
continue
# 检查表是否存在
if final_table_name in existing_tables and not force_overwrite:
return {
"success": False,
"message": f"{final_table_name} 已存在,请使用 force_overwrite=true 覆盖或选择其他表名"
}
# 如果需要覆盖,先删除表
if final_table_name in existing_tables and force_overwrite:
db.execute(text(f"DROP TABLE IF EXISTS `{final_table_name}`"))
db.commit()
# 准备列类型定义
column_types = FileImportUtils.prepare_table_columns(data, columns)
# 创建表
column_definitions = []
for col in columns:
col_type = column_types.get(col, "TEXT")
column_definitions.append(f"`{col}` {col_type}")
create_table_sql = f"""
CREATE TABLE `{final_table_name}` (
id INT AUTO_INCREMENT PRIMARY KEY,
{', '.join(column_definitions)}
)
"""
db.execute(text(create_table_sql))
db.commit()
# 导入数据
df_clean = pd.DataFrame(data)
# 使用pandas的to_sql方法批量导入
df_clean.to_sql(final_table_name, engine, if_exists='append',
index=False, method='multi', chunksize=1000)
results.append({
"table_name": final_table_name,
"rows_imported": len(data),
"columns": columns
})
# 返回结果
if len(results) == 1:
result = results[0]
return {
"success": True,
"message": f"成功导入 {result['rows_imported']} 行数据到表 {result['table_name']}",
"table_name": result["table_name"],
"rows_imported": result["rows_imported"],
"columns": result["columns"]
}
else:
total_rows = sum(r["rows_imported"] for r in results)
table_names = [r["table_name"] for r in results]
return {
"success": True,
"message": f"成功导入 {total_rows} 行数据到 {len(results)} 个表",
"tables": results,
"total_rows": total_rows,
"table_names": table_names
}
except ValueError as e:
return {
"success": False,
"message": str(e)
}
except SQLAlchemyError as e:
db.rollback()
return {
"success": False,
"message": f"数据库操作失败: {str(e)}"
}
except Exception as e:
db.rollback()
return {
"success": False,
"message": f"导入失败: {str(e)}"
}