Files
ctms/backend/scripts/seed_overview_data.py
T
2026-01-20 08:52:54 +08:00

151 lines
5.3 KiB
Python

"""
项目概览示例数据注入脚本
运行方式:
docker compose run --rm backend python scripts/seed_overview_data.py
"""
import asyncio
import sys
import uuid
from datetime import date, timedelta
from pathlib import Path
# 添加app目录到Python路径
sys.path.insert(0, str(Path(__file__).parent.parent))
from sqlalchemy import select
from app.db.session import SessionLocal
from app.models.site import Site
from app.models.startup_feasibility import StartupFeasibility
from app.models.startup_ethics import StartupEthics
from app.models.finance_contract import FinanceContract
from app.models.kickoff_meeting import KickoffMeeting
from app.models.subject import Subject
async def seed_data():
"""注入示例数据"""
async with SessionLocal() as db:
# 获取第一个项目用于测试
stmt = select(Site.study_id).limit(1)
result = await db.execute(stmt)
study_id_row = result.first()
if not study_id_row:
print("❌ 数据库中没有项目,请先创建项目和中心")
return
study_id = study_id_row[0]
print(f"✓ 使用项目 ID: {study_id}")
# 获取该项目的所有中心
stmt = select(Site).where(Site.study_id == study_id)
result = await db.execute(stmt)
sites = result.scalars().all()
if not sites:
print("❌ 项目下没有中心,请先创建中心")
return
print(f"✓ 找到 {len(sites)} 个中心")
# 为每个中心设置入组目标
targets = [80, 60, 70, 50, 40]
for idx, site in enumerate(sites[:5]):
site.enrollment_target = targets[idx] if idx < len(targets) else 50
print(f" • {site.name}: 目标入组 {site.enrollment_target} 人")
await db.commit()
print("✓ 入组目标已更新")
# 为中心添加启动流程数据
base_date = date(2024, 12, 1)
for idx, site in enumerate(sites[:5]):
# 机构立项
feasibility = StartupFeasibility(
id=uuid.uuid4(),
study_id=study_id,
site_id=site.id,
submit_date=base_date + timedelta(days=idx * 10),
accept_date=base_date + timedelta(days=idx * 10 + 5),
approved_date=base_date + timedelta(days=idx * 10 + 15) if idx < 4 else None,
project_no=f"PROJ-{idx+1:03d}"
)
db.add(feasibility)
# 伦理审批
ethics = StartupEthics(
id=uuid.uuid4(),
study_id=study_id,
site_id=site.id,
submit_date=base_date + timedelta(days=idx * 10 + 20),
accept_date=base_date + timedelta(days=idx * 10 + 25),
meeting_date=base_date + timedelta(days=idx * 10 + 35) if idx < 4 else None,
approved_date=base_date + timedelta(days=idx * 10 + 40) if idx < 4 else None,
approval_no=f"EC-{idx+1:03d}" if idx < 4 else None
)
db.add(ethics)
# 合同签署 (前3个中心)
if idx < 3:
contract = FinanceContract(
id=uuid.uuid4(),
study_id=study_id,
site_name=site.name,
contract_no=f"CT-{idx+1:03d}",
signed_date=base_date + timedelta(days=idx * 10 + 50),
amount=500000.0,
currency="CNY"
)
db.add(contract)
# 启动会 (前3个中心)
if idx < 3:
kickoff = KickoffMeeting(
id=uuid.uuid4(),
study_id=study_id,
site_id=site.id,
kickoff_date=base_date + timedelta(days=idx * 10 + 60),
attendees=["研究者", "CRA", "PM"]
)
db.add(kickoff)
await db.commit()
print("✓ 启动流程数据已添加")
# 为前3个中心添加入组受试者
enrollment_counts = [52, 18, 70]
start_enrollment_date = date(2025, 1, 1)
for idx, site in enumerate(sites[:3]):
count = enrollment_counts[idx] if idx < len(enrollment_counts) else 0
for i in range(count):
# 分散在6个月内入组
enrollment_date = start_enrollment_date + timedelta(days=i * 4)
subject = Subject(
id=uuid.uuid4(),
study_id=study_id,
site_id=site.id,
subject_no=f"S{idx+1:02d}-{i+1:03d}",
status="ENROLLED",
screening_date=enrollment_date - timedelta(days=7),
consent_date=enrollment_date - timedelta(days=3),
enrollment_date=enrollment_date
)
db.add(subject)
print(f" • {site.name}: 已入组 {count} 人")
await db.commit()
print("✓ 受试者入组数据已添加")
print("\n✅ 示例数据注入完成!")
print("请刷新项目概览页面查看效果")
if __name__ == "__main__":
asyncio.run(seed_data())