# db.py — 基础层:配置常量 + 数据库连接 + SQL 工具 + logger # 被 helpers.py, routes.py, migrations/*, flask_app.py 共同依赖 import os import sys import json import logging from pathlib import Path from datetime import datetime import mysql.connector # 确保 backend 目录在 sys.path 中(兼容 gunicorn --preload 模式) _backend_dir = os.path.dirname(os.path.abspath(__file__)) if _backend_dir not in sys.path: sys.path.insert(0, _backend_dir) logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") # ---------- 路径常量 ---------- ROOT = Path(__file__).resolve().parents[1] DATA_DIR = ROOT / "data" UPLOAD_DIR = DATA_DIR / "uploads" DB_PATH = DATA_DIR / "opc.sqlite" # ---------- 环境变量 ---------- try: from dotenv import load_dotenv load_dotenv(ROOT / ".env") except ImportError: pass WEIXIN_BASE = Path(os.environ.get("WEIXIN_BASE", "/Users/mac/天机阁/地阁/慰心斋")) # 建目录 DATA_DIR.mkdir(parents=True, exist_ok=True) UPLOAD_DIR.mkdir(parents=True, exist_ok=True) # ---------- 数据库连接 ---------- def db(): return mysql.connector.connect( host=os.environ.get("DB_HOST", "127.0.0.1"), port=int(os.environ.get("DB_PORT", "3306")), user=os.environ.get("DB_USER", "opc"), password=os.environ.get("DB_PASSWORD", "opc123456"), database=os.environ.get("DB_NAME", "opc"), charset="utf8mb4", collation="utf8mb4_unicode_ci", ) def now(): return datetime.utcnow().isoformat() def _exec(conn, sql, args=()): """执行 SQL,自动将 ? 转为 MySQL 的 %s""" cur = conn.cursor(dictionary=True) cur.execute(sql.replace("?", "%s"), args) return cur def rows(conn, sql, args=()): cur = _exec(conn, sql, args) rows = cur.fetchall() cur.close() return rows def one(conn, sql, args=()): cur = _exec(conn, sql, args) row = cur.fetchone() cur.close() return row