stock-monitor/app/dao/base_dao.py
ycg 569c1c8813 重构股票监控系统:数据库架构升级与功能完善
- 重构数据访问层:引入DAO模式,支持MySQL/SQLite双数据库
- 新增数据库架构:完整的股票数据、AI分析、自选股管理表结构
- 升级AI分析服务:集成豆包大模型,支持多维度分析
- 优化API路由:分离市场数据API,提供更清晰的接口设计
- 完善项目文档:添加数据库迁移指南、新功能指南等
- 清理冗余文件:删除旧的缓存文件和无用配置
- 新增调度器:支持定时任务和数据自动更新
- 改进前端模板:简化的股票展示页面

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 15:44:25 +08:00

114 lines
4.2 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 abc import ABC, abstractmethod
from typing import Dict, Any, Optional, List
import logging
from datetime import datetime, date
from app.database import DatabaseManager
class BaseDAO(ABC):
"""数据访问对象基类"""
def __init__(self):
self.db_manager = DatabaseManager()
self.logger = logging.getLogger(self.__class__.__name__)
def _execute_query(self, query: str, params: Optional[tuple] = None) -> List[Dict]:
"""执行查询语句"""
try:
with self.db_manager.get_cursor() as cursor:
cursor.execute(query, params)
return cursor.fetchall()
except Exception as e:
self.logger.error(f"查询执行失败: {query}, 参数: {params}, 错误: {e}")
raise
def _execute_single_query(self, query: str, params: Optional[tuple] = None) -> Optional[Dict]:
"""执行单条记录查询"""
try:
with self.db_manager.get_cursor() as cursor:
cursor.execute(query, params)
return cursor.fetchone()
except Exception as e:
self.logger.error(f"单条查询执行失败: {query}, 参数: {params}, 错误: {e}")
raise
def _execute_update(self, query: str, params: Optional[tuple] = None) -> int:
"""执行更新语句,返回影响的行数"""
try:
with self.db_manager.get_connection() as conn:
with conn.cursor() as cursor:
cursor.execute(query, params)
affected_rows = cursor.rowcount
conn.commit()
return affected_rows
except Exception as e:
self.logger.error(f"更新执行失败: {query}, 参数: {params}, 错误: {e}")
raise
def _execute_insert(self, query: str, params: Optional[tuple] = None) -> int:
"""执行插入语句返回插入的ID"""
try:
with self.db_manager.get_connection() as conn:
with conn.cursor() as cursor:
cursor.execute(query, params)
inserted_id = cursor.lastrowid
conn.commit()
return inserted_id
except Exception as e:
self.logger.error(f"插入执行失败: {query}, 参数: {params}, 错误: {e}")
raise
def _execute_batch_insert(self, query: str, params_list: List[tuple]) -> int:
"""批量插入数据,返回插入的总行数"""
if not params_list:
return 0
try:
with self.db_manager.get_connection() as conn:
with conn.cursor() as cursor:
cursor.executemany(query, params_list)
affected_rows = cursor.rowcount
conn.commit()
return affected_rows
except Exception as e:
self.logger.error(f"批量插入失败: {query}, 参数数量: {len(params_list)}, 错误: {e}")
raise
def log_data_update(self, data_type: str, stock_code: str, status: str,
message: str = None, execution_time: float = None):
"""记录数据更新日志"""
try:
query = """
INSERT INTO data_update_log
(data_type, stock_code, update_status, update_message, execution_time)
VALUES (%s, %s, %s, %s, %s)
"""
self._execute_insert(query, (data_type, stock_code, status, message, execution_time))
except Exception as e:
self.logger.error(f"记录更新日志失败: {e}")
def get_today_date(self) -> str:
"""获取今天的日期字符串"""
return date.today().strftime('%Y-%m-%d')
def parse_float(self, value: Any) -> Optional[float]:
"""解析浮点数"""
if value is None or value == '':
return None
try:
return float(value)
except (ValueError, TypeError):
return None
def parse_int(self, value: Any) -> Optional[int]:
"""解析整数"""
if value is None or value == '':
return None
try:
return int(value)
except (ValueError, TypeError):
return None