数据库为同步ORM
This commit is contained in:
@@ -6,6 +6,18 @@ class Settings(BaseSettings):
|
||||
|
||||
env: str = "dev"
|
||||
|
||||
# ──────────── MySQL(业务库)────────────
|
||||
db_host: str = "192.168.31.105"
|
||||
db_port: int = 3306
|
||||
db_user: str = "root"
|
||||
db_password: str = "123456"
|
||||
db_name: str = "offerpie"
|
||||
mysql_pool_size: int = 10
|
||||
mysql_max_overflow: int = 10
|
||||
|
||||
# 连接池获取连接的等待超时(秒)
|
||||
db_pool_timeout: int = 30
|
||||
|
||||
# 火山引擎(OpenAI 兼容风格)
|
||||
volcengine_api_key: str = ""
|
||||
volcengine_base_url: str = "https://ark.cn-beijing.volces.com/api/v3"
|
||||
@@ -14,6 +26,18 @@ class Settings(BaseSettings):
|
||||
anthropic_api_key: str = ""
|
||||
anthropic_base_url: str = ""
|
||||
|
||||
# ──────────── 日志 ────────────
|
||||
logging_level: str = "INFO"
|
||||
log_file_name: str = "spider.log"
|
||||
|
||||
@property
|
||||
def mysql_url(self) -> str:
|
||||
from urllib.parse import quote
|
||||
return (
|
||||
f"mysql+pymysql://{self.db_user}:{quote(self.db_password, safe='')}"
|
||||
f"@{self.db_host}:{self.db_port}/{self.db_name}"
|
||||
)
|
||||
|
||||
model_config = SettingsConfigDict(
|
||||
env_file=".env",
|
||||
env_file_encoding="utf-8",
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
"""MySQL 业务库数据源(同步)"""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import Engine, create_engine
|
||||
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
|
||||
|
||||
from app.config import settings
|
||||
from app.core.logger import log
|
||||
|
||||
# ──────────── 内部变量 ────────────
|
||||
_mysql_engine: Optional[Engine] = None
|
||||
_mysql_session_factory: Optional[sessionmaker[Session]] = None
|
||||
|
||||
|
||||
class MysqlBase(DeclarativeBase):
|
||||
"""MySQL ORM 声明基类"""
|
||||
pass
|
||||
|
||||
|
||||
def init_db() -> None:
|
||||
"""初始化 MySQL 数据源"""
|
||||
global _mysql_engine, _mysql_session_factory
|
||||
|
||||
_mysql_engine = create_engine(
|
||||
settings.mysql_url,
|
||||
pool_size=settings.mysql_pool_size,
|
||||
max_overflow=settings.mysql_max_overflow,
|
||||
pool_timeout=settings.db_pool_timeout,
|
||||
pool_recycle=3600,
|
||||
pool_pre_ping=True,
|
||||
echo=False,
|
||||
)
|
||||
_mysql_session_factory = sessionmaker(_mysql_engine, expire_on_commit=False)
|
||||
|
||||
log.info("MySQL 数据源初始化完成: {}", settings.db_host)
|
||||
|
||||
|
||||
def close_db() -> None:
|
||||
"""关闭 MySQL 数据源"""
|
||||
if _mysql_engine:
|
||||
_mysql_engine.dispose()
|
||||
log.info("MySQL 数据源已关闭")
|
||||
|
||||
|
||||
def MysqlSession() -> Session:
|
||||
"""获取 MySQL 会话(用作 with MysqlSession() as session)"""
|
||||
if _mysql_session_factory is None:
|
||||
raise RuntimeError("数据库未初始化,请先调用 init_db()")
|
||||
return _mysql_session_factory()
|
||||
@@ -0,0 +1,34 @@
|
||||
"""日志配置"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from app.config import settings
|
||||
|
||||
# 日志目录
|
||||
_log_dir = Path("logs")
|
||||
_log_dir.mkdir(exist_ok=True)
|
||||
|
||||
# 移除默认 handler
|
||||
logger.remove()
|
||||
|
||||
# 控制台输出
|
||||
logger.add(
|
||||
sys.stdout,
|
||||
level=settings.logging_level,
|
||||
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
|
||||
)
|
||||
|
||||
# 文件输出(按天轮转,保留30天)
|
||||
logger.add(
|
||||
_log_dir / settings.log_file_name,
|
||||
level=settings.logging_level,
|
||||
rotation="00:00",
|
||||
retention="30 days",
|
||||
encoding="utf-8",
|
||||
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{line} - {message}",
|
||||
)
|
||||
|
||||
log = logger
|
||||
Reference in New Issue
Block a user