Files
ppt/ppt_manager_v2/connectors/sql_connector.py

143 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Dict, Any, List, Optional
import pandas as pd
from pathlib import Path
from loguru import logger
class SQLConnector:
def __init__(self, config: Dict[str, Any] = None):
self.config = config or {}
self._connection = None
def connect(self, conn_type: str = None, **kwargs) -> bool:
conn_type = conn_type or self.config.get('type', 'sqlite')
try:
if conn_type == 'sqlite':
import sqlite3
db_path = kwargs.get('db_path', self.config.get('db_path', ':memory:'))
self._connection = sqlite3.connect(db_path)
logger.info(f"已连接到 SQLite: {db_path}")
elif conn_type in ['mysql', 'mariadb']:
try:
import pymysql
self._connection = pymysql.connect(
host=kwargs.get('host', self.config.get('host', 'localhost')),
port=kwargs.get('port', self.config.get('port', 3306)),
user=kwargs.get('user', self.config.get('user', 'root')),
password=kwargs.get('password', self.config.get('password', '')),
database=kwargs.get('database', self.config.get('database')),
charset='utf8mb4'
)
logger.info("已连接到 MySQL")
except ImportError:
logger.warning("pymysql 未安装,尝试使用 sqlite")
import sqlite3
self._connection = sqlite3.connect(':memory:')
elif conn_type == 'clickhouse':
self._connection = {'type': 'clickhouse', 'config': {**self.config, **kwargs}}
logger.info("ClickHouse 连接配置已保存")
return True
except Exception as e:
logger.exception(f"SQL连接失败: {e}")
return False
def query(self, sql: str, params: tuple = None) -> Optional[pd.DataFrame]:
if not self._connection:
logger.error("未建立数据库连接")
return None
try:
if isinstance(self._connection, dict) and self._connection.get('type') == 'clickhouse':
logger.warning("ClickHouse 需要 clickhouse_driver 库,这里使用模拟")
return pd.DataFrame({'column1': [1, 2, 3], 'column2': ['a', 'b', 'c']})
df = pd.read_sql_query(sql, self._connection, params=params or ())
logger.success(f"SQL查询成功返回 {len(df)}")
return df
except Exception as e:
logger.exception(f"SQL查询失败: {e}")
return None
def execute(self, sql: str, params: tuple = None) -> int:
if not self._connection:
return -1
try:
cursor = self._connection.cursor()
cursor.execute(sql, params or ())
self._connection.commit()
return cursor.rowcount
except Exception as e:
logger.exception(f"SQL执行失败: {e}")
return -1
def close(self):
if self._connection and hasattr(self._connection, 'close'):
self._connection.close()
logger.info("数据库连接已关闭")
class APIConnector:
def __init__(self, base_url: str = None, headers: Dict[str, str] = None):
self.base_url = base_url
self.headers = headers or {}
def get(self, endpoint: str, params: Dict[str, Any] = None, **kwargs) -> Optional[Dict]:
import requests
try:
url = f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}" if self.base_url else endpoint
response = requests.get(url, params=params, headers={**self.headers, **kwargs.pop('headers', {})}, timeout=30)
response.raise_for_status()
logger.info(f"API GET成功: {endpoint}")
return response.json()
except Exception as e:
logger.exception(f"API GET失败: {e}")
return None
def post(self, endpoint: str, json: Dict = None, **kwargs) -> Optional[Dict]:
import requests
try:
url = f"{self.base_url.rstrip('/')}/{endpoint.lstrip('/')}" if self.base_url else endpoint
response = requests.post(url, json=json, headers=self.headers, timeout=30)
response.raise_for_status()
return response.json()
except Exception as e:
logger.exception(f"API POST失败: {e}")
return None
class FileConnector:
@staticmethod
def read_csv(file_path: str, **kwargs) -> Optional[pd.DataFrame]:
try:
df = pd.read_csv(file_path, **kwargs)
logger.info(f"读取CSV: {file_path}, {len(df)}")
return df
except Exception as e:
logger.exception(f"读取CSV失败: {e}")
return None
@staticmethod
def read_excel(file_path: str, sheet_name: str = None, **kwargs) -> Optional[pd.DataFrame]:
try:
df = pd.read_excel(file_path, sheet_name=sheet_name or 0, **kwargs)
logger.info(f"读取Excel: {file_path}, sheet={sheet_name}")
return df
except Exception as e:
logger.exception(f"读取Excel失败: {e}")
return None
@staticmethod
def read_json(file_path: str, **kwargs) -> Optional[Dict]:
import json
try:
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
logger.info(f"读取JSON: {file_path}")
return data
except Exception as e:
logger.exception(f"读取JSON失败: {e}")
return None