Files
server-core/scripts/db/seed.py
T
Pine 31f8703595 chore(seed): 种子脚本去 sqlite 直连 + 大厅/社区演示种子 + 大厅单测
- scripts/db/seed.py:培训种子与 accounts→users 迁移改经 training 数据层(双方言)
- scripts/db/seed_hall_community.py:人才/岗位/服务/帖子演示数据(幂等,离线执行)
- tests/test_hall.py:人才档案/帖子点赞评论计数/register 报名状态机覆盖
2026-08-31 22:20:16 +08:00

114 lines
4.4 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.
# -*- coding: utf-8 -*-
"""数据库种子脚本(非运行态)—— 在迁移后、启动应用前执行。
用法:uv run python scripts/db/seed.py
职责:灌入平台/园区/培训的基础种子数据(角色、权限、用户、默认园区、培训事件课程等)。
全部幂等(按标记行判断,重跑安全)。禁止在应用启动时调用本逻辑。
"""
from __future__ import annotations
import asyncio
import logging
import sys
import os
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
from app.infrastructure.repositories import Database
from app.infrastructure.seed import seed_data as platform_seed
from app import config
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
log = logging.getLogger("db.seed")
def _seed_training() -> None:
"""培训种子(统一总库):排期 + 在线课程(幂等)。
经 training 数据层(SQLAlchemy,方言由 DATABASE_URL 决定)读写,
不再直连 sqlite3。不向旧 ``accounts`` 表种子账号 —— 平台规范账号由
platform_seed 写入 ``users``。
"""
from app.training import db as tdb
try:
if not tdb.list_all("events"):
for e in tdb.SEED_EVENTS:
tdb.insert("events", e)
if not tdb.list_all("courses"):
for c in tdb.SEED_COURSES:
tdb.insert("courses", c)
log.info("培训种子完成(排期/课程)")
except Exception as e: # noqa: BLE001
log.warning("培训种子跳过(表可能未迁移):%s", e)
async def _migrate_accounts_to_users(db) -> None:
"""把培训端 accounts 存量并入平台 users(幂等:已存在账号跳过并保证身份)。
迁移旧小程序账号 → userswx_mini_openid/phone 关联),使微信/手机登录仍命中,
且并入全局唯一账号体系。迁移/种子由用户执行(铁律),禁止运行态调用。
"""
import secrets
from app.training import db as tdb
from app.api.routers.auth import _ensure_opc_identity
migrated = created = 0
try:
rows = tdb.list_all("accounts")
except Exception as e: # noqa: BLE001
log.warning("accounts 读取失败,跳过迁移:%s", e)
return
try:
for row in rows:
username = (row.get("username") or "").strip()
wxid = (row.get("wxid") or "").strip()
phone = (row.get("phone") or "").strip()
if not username and not wxid and not phone:
continue
user = (await db.users.get_by_username(username)) if username else None
if user is None and phone:
user = await db.users.get_by_username(phone)
if user is None and wxid:
user = (await db.users.get_by_wx_mini_openid(wxid)
or await db.users.get_by_wx_openid(wxid))
if user is None:
uname = (username or phone or f"wx_{wxid[:24]}")
user = await db.users.create(
username=uname, password=secrets.token_hex(16),
nickname=(row.get("name") or uname), avatar=(row.get("avatar") or ""),
phone=phone, wx_mini_openid=wxid or "",
wx_openid=(f"wx_{wxid[:24]}" if wxid else ""),
source="mini_program",
auth_type=("wx_openid" if wxid else ("phone" if phone else "unknown")),
role="opc_member",
)
created += 1
await _ensure_opc_identity(db, user["id"])
# 迁移即接管:删掉旧 accounts 行,避免同一逻辑账号落在两套表(多余账号)。
tdb.delete_row("accounts", row["id"])
migrated += 1
log.info("accounts→users 迁移完成:共 %s 条,新建 %s 条(旧 accounts 行已清理)", migrated, created)
finally:
tdb.reset_engine()
async def run() -> None:
db = Database()
try:
await platform_seed(db.session)
await db.session.commit()
log.info("平台种子完成:%s", config.DATABASE_URL)
_seed_training()
await _migrate_accounts_to_users(db)
except Exception as e: # noqa: BLE001
await db.session.rollback()
log.error("种子失败:%s", e)
raise
finally:
await db.close()
if __name__ == "__main__":
asyncio.run(run())