最初版本

This commit is contained in:
sa19840531
2026-08-15 14:51:51 +08:00
parent 4e01df4dce
commit ea47ea4449
176 changed files with 21009 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
from __future__ import annotations
from typing import Any
from config import CONFIG
from db import db_connection
REQUIRED: dict[str, set[str]] = {
CONFIG.members_table: {
"id",
"uid",
"username",
"username_clean",
"balance",
"remark",
},
CONFIG.withdraw_table: {
"id",
"username",
"username_clean",
"withdraw_amount",
"withdraw_time",
"status",
"remark",
},
CONFIG.withdraw_request_table: {
"id",
"withdraw_request_id",
"username_raw",
"username_clean",
"withdraw_amount",
"request_time",
"operation",
"audit_status",
"remark",
},
CONFIG.deposit_table: {
"id",
"deposit_id",
"username",
"username_clean",
"deposit_amount",
"actual_arrival_amount",
"status",
"deposit_time",
},
}
def extract_column_name(row: Any) -> str:
"""兼容不同 MySQL/PyMySQL 對欄位名稱大小寫的返回方式。"""
if isinstance(row, dict):
for key in (
"column_name_value",
"column_name",
"COLUMN_NAME",
):
value = row.get(key)
if value is not None:
return str(value)
if row:
return str(next(iter(row.values())))
if isinstance(row, (list, tuple)) and row:
return str(row[0])
raise KeyError(f"無法取得欄位名稱:{row!r}")
def fetch_table_columns(cursor: Any, table: str) -> set[str]:
cursor.execute(
"""
SELECT COLUMN_NAME AS column_name_value
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=%s
AND TABLE_NAME=%s
ORDER BY ORDINAL_POSITION
""",
(
CONFIG.db_name,
table,
),
)
return {
extract_column_name(row)
for row in cursor.fetchall()
}
def main() -> int:
print("API接口系統資料庫預檢")
print("=" * 48)
print(f"資料庫:{CONFIG.db_name}")
print(f"唯讀模式:{CONFIG.read_only_mode}")
print(f"會員表:{CONFIG.members_table}")
print(f"提款記錄表:{CONFIG.withdraw_table}")
print(f"提款申請表:{CONFIG.withdraw_request_table}")
print(f"充值表:{CONFIG.deposit_table}")
print("-" * 48)
failed = False
try:
with db_connection() as conn, conn.cursor() as cursor:
cursor.execute(
"""
SELECT
DATABASE() AS database_name,
@@global.read_only AS global_read_only
"""
)
server_info = cursor.fetchone() or {}
if isinstance(server_info, dict):
database_name = (
server_info.get("database_name")
or server_info.get("DATABASE_NAME")
or CONFIG.db_name
)
if "global_read_only" in server_info:
mysql_read_only = server_info["global_read_only"]
else:
mysql_read_only = server_info.get("GLOBAL_READ_ONLY")
else:
database_name = CONFIG.db_name
mysql_read_only = "unknown"
print(f"目前連線資料庫:{database_name}")
print(f"MySQL global read_only:{mysql_read_only}")
print("-" * 48)
for table, required_columns in REQUIRED.items():
columns = fetch_table_columns(cursor, table)
missing = sorted(required_columns - columns)
if not columns:
failed = True
print(
f"[失敗] {table}: "
"資料表不存在,或目前帳號無 information_schema 讀取權限"
)
continue
if missing:
failed = True
print(
f"[失敗] {table}: "
f"共 {len(columns)} 個欄位,缺少 {missing}"
)
continue
print(
f"[正常] {table}: "
f"{len(columns)} 個欄位,必要欄位完整"
)
except Exception as exc:
print(
f"[失敗] 資料庫預檢執行錯誤:"
f"{type(exc).__name__}: {exc}"
)
return 1
print("-" * 48)
if failed:
print("預檢結果:存在資料表或欄位問題")
return 1
print("預檢結果:全部正常")
return 0
if __name__ == "__main__":
raise SystemExit(main())