update file struct
This commit is contained in:
9
base/Config.py
Normal file
9
base/Config.py
Normal file
@@ -0,0 +1,9 @@
|
||||
class ConfigInfo:
|
||||
# 数据库配置
|
||||
db_hk_kline_1d = {
|
||||
'host': 'localhost',
|
||||
'user': 'root',
|
||||
'password': 'bzskmysql',
|
||||
'database': 'hk_kline_1d'
|
||||
}
|
||||
|
||||
90
base/LogHelper.py
Normal file
90
base/LogHelper.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""
|
||||
日志管理类
|
||||
|
||||
日志输出到运行目录指定文件夹
|
||||
日志文件按照:YYYY-MM-dd.log 格式输出
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
class LogHelper:
|
||||
# 内部日志级别映射表
|
||||
_LEVEL_MAP = {
|
||||
'DEBUG': 10,
|
||||
'INFO': 20,
|
||||
'WARNING': 30,
|
||||
'ERROR': 40,
|
||||
'CRITICAL': 50
|
||||
}
|
||||
|
||||
def __init__(self,
|
||||
level='INFO',
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=None,
|
||||
log_dir="logs",
|
||||
logger_name=None):
|
||||
"""
|
||||
初始化日志配置
|
||||
|
||||
:param level: 日志级别,默认为 logging.INFO
|
||||
:param format: 日志格式字符串
|
||||
:param handlers: 日志处理器列表,默认为空(会自动添加控制台处理器)
|
||||
:param log_dir: 日志存储目录,默认为"logs"
|
||||
"""
|
||||
self.level = self._LEVEL_MAP.get(level.upper(), 20) # 默认INFO
|
||||
self.format = format
|
||||
self.handlers = handlers if handlers is not None else []
|
||||
self.log_dir = log_dir
|
||||
self.logger_name = logger_name
|
||||
# 确保日志目录存在
|
||||
os.makedirs(self.log_dir, exist_ok=True)
|
||||
|
||||
def add_console_handler(self, stream=sys.stdout, encoding='utf-8'):
|
||||
"""添加控制台处理器"""
|
||||
console_handler = logging.StreamHandler(stream)
|
||||
console_handler.setFormatter(logging.Formatter(self.format))
|
||||
if encoding:
|
||||
console_handler.encoding = encoding
|
||||
self.handlers.append(console_handler)
|
||||
return self # 支持链式调用
|
||||
|
||||
def _get_daily_log_path(self):
|
||||
"""生成基于当前日期的日志文件路径"""
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
filename = f"{today}.log"
|
||||
return os.path.join(self.log_dir, filename)
|
||||
|
||||
def _add_daily_file_handler(self, encoding='utf-8'):
|
||||
"""添加按日期自动创建的文件处理器"""
|
||||
log_path = self._get_daily_log_path()
|
||||
file_handler = logging.FileHandler(log_path, encoding=encoding)
|
||||
file_handler.setFormatter(logging.Formatter(self.format))
|
||||
self.handlers.append(file_handler)
|
||||
return self # 支持链式调用
|
||||
|
||||
def setup(self):
|
||||
"""应用日志配置(自动添加日期文件处理器)"""
|
||||
# 如果未提供任何处理器,默认添加控制台和日期文件处理器
|
||||
if not self.handlers:
|
||||
self.add_console_handler()
|
||||
self._add_daily_file_handler()
|
||||
|
||||
# 获取或创建logger
|
||||
logger = logging.getLogger(self.logger_name)
|
||||
logger.setLevel(self.level)
|
||||
|
||||
# 移除所有现有处理器(避免重复添加)
|
||||
for handler in logger.handlers[:]:
|
||||
logger.removeHandler(handler)
|
||||
|
||||
# 添加配置的处理器
|
||||
for handler in self.handlers:
|
||||
logger.addHandler(handler)
|
||||
|
||||
# 确保日志消息不会传递给父logger(避免重复记录)
|
||||
logger.propagate = False
|
||||
|
||||
return logger
|
||||
236
base/MySQLHelper.py
Normal file
236
base/MySQLHelper.py
Normal file
@@ -0,0 +1,236 @@
|
||||
"""
|
||||
MySqlHelper 增强版
|
||||
—— 增加事务管理
|
||||
—— 增加ID获取
|
||||
—— 增加表操作等使用功能
|
||||
—— 数据使用过程中出现异常时,才输出日志
|
||||
"""
|
||||
import pymysql
|
||||
from pymysql import Error
|
||||
from typing import List, Dict, Union, Optional, Tuple
|
||||
from contextlib import contextmanager
|
||||
from base.LogHelper import LogHelper
|
||||
|
||||
# 基本用法(自动创建日期日志+控制台输出)
|
||||
logger = LogHelper(logger_name = 'database').setup()
|
||||
|
||||
# # 高级用法(自定义配置)
|
||||
# logger = LogHelper(
|
||||
# level=logging.DEBUG,
|
||||
# log_dir="databaselogs",
|
||||
# format='%(levelname)s - %(message)s'
|
||||
# ).setup()
|
||||
|
||||
|
||||
class MySQLHelper:
|
||||
def __init__(self, host: str, user: str, password: str, database: str,
|
||||
port: int = 3306, charset: str = 'utf8mb4'):
|
||||
"""
|
||||
初始化MySQL连接参数
|
||||
:param host: 数据库地址
|
||||
:param user: 用户名
|
||||
:param password: 密码
|
||||
:param database: 数据库名
|
||||
:param port: 端口,默认3306
|
||||
:param charset: 字符集,默认utf8mb4
|
||||
"""
|
||||
self.host = host
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.database = database
|
||||
self.port = port
|
||||
self.charset = charset
|
||||
self.connection = None
|
||||
self.cursor = None
|
||||
|
||||
def connect(self) -> bool:
|
||||
"""
|
||||
连接到MySQL数据库
|
||||
:return: 连接成功返回True,失败返回False
|
||||
"""
|
||||
try:
|
||||
self.connection = pymysql.connect(
|
||||
host=self.host,
|
||||
user=self.user,
|
||||
password=self.password,
|
||||
database=self.database,
|
||||
port=self.port,
|
||||
charset=self.charset,
|
||||
cursorclass=pymysql.cursors.DictCursor # 返回字典形式的结果
|
||||
)
|
||||
self.cursor = self.connection.cursor()
|
||||
# logger.info("MySQL数据库连接成功")
|
||||
return True
|
||||
except Error as e:
|
||||
logger.error(f"连接MySQL数据库失败: {e}")
|
||||
return False
|
||||
|
||||
def close(self) -> None:
|
||||
"""
|
||||
关闭数据库连接
|
||||
"""
|
||||
if self.cursor:
|
||||
self.cursor.close()
|
||||
if self.connection:
|
||||
self.connection.close()
|
||||
# logger.info("MySQL数据库连接已关闭")
|
||||
|
||||
def execute_query(self, sql: str, params: Union[Tuple, List, Dict, None] = None) -> List[Dict]:
|
||||
"""
|
||||
执行查询操作
|
||||
:param sql: SQL语句
|
||||
:param params: 参数,可以是元组、列表或字典
|
||||
:return: 查询结果列表
|
||||
"""
|
||||
try:
|
||||
self.cursor.execute(sql, params)
|
||||
return self.cursor.fetchall()
|
||||
except Error as e:
|
||||
logger.error(f"查询执行失败: {e}")
|
||||
return []
|
||||
|
||||
def execute_update(self, sql: str, params: Union[Tuple, List, Dict, None] = None) -> int:
|
||||
"""
|
||||
执行更新操作(INSERT/UPDATE/DELETE)
|
||||
:param sql: SQL语句
|
||||
:param params: 参数,可以是元组、列表或字典
|
||||
:return: 影响的行数
|
||||
"""
|
||||
try:
|
||||
affected_rows = self.cursor.execute(sql, params)
|
||||
self.connection.commit()
|
||||
return affected_rows
|
||||
except Error as e:
|
||||
self.connection.rollback()
|
||||
logger.error(f"更新执行失败: {e}")
|
||||
return 0
|
||||
|
||||
def execute_many(self, sql: str, params_list: List[Union[Tuple, List, Dict]]) -> int:
|
||||
"""
|
||||
批量执行操作
|
||||
:param sql: SQL语句
|
||||
:param params_list: 参数列表
|
||||
:return: 影响的行数
|
||||
"""
|
||||
try:
|
||||
affected_rows = self.cursor.executemany(sql, params_list)
|
||||
self.connection.commit()
|
||||
return affected_rows
|
||||
except Error as e:
|
||||
self.connection.rollback()
|
||||
logger.error(f"批量执行失败: {e}")
|
||||
return 0
|
||||
|
||||
# ================== 新增功能方法 ==================
|
||||
def get_last_insert_id(self) -> int:
|
||||
"""
|
||||
获取最后插入行的自增ID
|
||||
:return: 自增ID值
|
||||
"""
|
||||
return self.cursor.lastrowid if self.cursor else 0
|
||||
|
||||
def execute_insert(self, sql: str, params: Union[Tuple, List, Dict, None] = None) -> int:
|
||||
"""
|
||||
执行插入操作并返回自增ID
|
||||
:return: 自增ID值
|
||||
"""
|
||||
self.execute_update(sql, params)
|
||||
return self.get_last_insert_id()
|
||||
|
||||
@contextmanager
|
||||
def transaction(self):
|
||||
"""
|
||||
事务上下文管理器,确保操作原子性
|
||||
用法:
|
||||
with db.transaction():
|
||||
db.execute_update(...)
|
||||
db.execute_many(...)
|
||||
"""
|
||||
try:
|
||||
yield
|
||||
self.connection.commit()
|
||||
except Exception as e:
|
||||
self.connection.rollback()
|
||||
raise e
|
||||
|
||||
def get_one(self, sql: str, params: Union[Tuple, List, Dict, None] = None) -> Optional[Dict]:
|
||||
"""
|
||||
获取单条记录
|
||||
:param sql: SQL语句
|
||||
:param params: 参数,可以是元组、列表或字典
|
||||
:return: 单条记录或None
|
||||
"""
|
||||
try:
|
||||
self.cursor.execute(sql, params)
|
||||
return self.cursor.fetchone()
|
||||
except Error as e:
|
||||
logger.error(f"获取单条记录失败: {e}")
|
||||
return None
|
||||
|
||||
def table_exists(self, table_name: str) -> bool:
|
||||
"""
|
||||
检查表是否存在
|
||||
:param table_name: 表名
|
||||
:return: 存在返回True,否则返回False
|
||||
"""
|
||||
sql = "SHOW TABLES LIKE %s"
|
||||
result = self.execute_query(sql, (table_name,))
|
||||
return len(result) > 0
|
||||
|
||||
def create_table(self, sql: str) -> bool:
|
||||
"""
|
||||
执行建表语句
|
||||
:param sql: CREATE TABLE语句
|
||||
:return: 是否成功
|
||||
"""
|
||||
try:
|
||||
self.cursor.execute(sql)
|
||||
self.connection.commit()
|
||||
return True
|
||||
except Error as e:
|
||||
logger.error(f"创建表失败: {e}")
|
||||
return False
|
||||
|
||||
def drop_table(self, table_name: str) -> bool:
|
||||
"""
|
||||
删除表
|
||||
:param table_name: 表名
|
||||
:return: 是否成功
|
||||
"""
|
||||
try:
|
||||
self.cursor.execute(f"DROP TABLE IF EXISTS {table_name}")
|
||||
self.connection.commit()
|
||||
return True
|
||||
except Error as e:
|
||||
logger.error(f"删除表失败: {e}")
|
||||
return False
|
||||
|
||||
def get_columns(self, table_name: str) -> List[Dict]:
|
||||
"""
|
||||
获取表的列信息
|
||||
:param table_name: 表名
|
||||
:return: 列信息字典列表
|
||||
"""
|
||||
return self.execute_query(f"DESCRIBE {table_name}")
|
||||
|
||||
|
||||
# ================== 事务控制方法 ==================
|
||||
def start_transaction(self):
|
||||
"""显式开始事务"""
|
||||
self.connection.begin()
|
||||
|
||||
def commit(self):
|
||||
"""提交事务"""
|
||||
self.connection.commit()
|
||||
|
||||
def rollback(self):
|
||||
"""回滚事务"""
|
||||
self.connection.rollback()
|
||||
|
||||
# ================== 上下文管理器 ==================
|
||||
def __enter__(self):
|
||||
self.connect()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.close()
|
||||
3
base/__init__.py
Normal file
3
base/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .MySQLHelper import MySQLHelper
|
||||
from .LogHelper import LogHelper
|
||||
from .Config import ConfigInfo
|
||||
Reference in New Issue
Block a user