修复init初始化异常
This commit is contained in:
@@ -2,6 +2,7 @@ from contextlib import asynccontextmanager
|
|||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
from app.api.v1.router import api_router
|
from app.api.v1.router import api_router
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
@@ -18,12 +19,46 @@ async def lifespan(_: FastAPI):
|
|||||||
|
|
||||||
if settings.ENV == "development":
|
if settings.ENV == "development":
|
||||||
async with engine.begin() as conn:
|
async with engine.begin() as conn:
|
||||||
|
await _ensure_legacy_primary_keys(conn)
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
async with SessionLocal() as session:
|
async with SessionLocal() as session:
|
||||||
await ensure_admin_exists(session)
|
await ensure_admin_exists(session)
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
async def _ensure_legacy_primary_keys(conn) -> None:
|
||||||
|
# Fix legacy databases where tables with an "id" column were created without a PK.
|
||||||
|
result = await conn.execute(
|
||||||
|
text(
|
||||||
|
"""
|
||||||
|
SELECT c.relname AS table_name
|
||||||
|
FROM pg_class c
|
||||||
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||||
|
WHERE n.nspname = 'public'
|
||||||
|
AND c.relkind = 'r'
|
||||||
|
AND EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM pg_attribute a
|
||||||
|
WHERE a.attrelid = c.oid
|
||||||
|
AND a.attname = 'id'
|
||||||
|
AND a.attisdropped = false
|
||||||
|
)
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM pg_constraint con
|
||||||
|
WHERE con.conrelid = c.oid
|
||||||
|
AND con.contype = 'p'
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
tables = [row.table_name for row in result.fetchall()]
|
||||||
|
for table_name in tables:
|
||||||
|
await conn.execute(
|
||||||
|
text(f'ALTER TABLE "{table_name}" ADD CONSTRAINT "{table_name}_pkey" PRIMARY KEY (id)')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
def create_app() -> FastAPI:
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="CTMS 后端 API",
|
title="CTMS 后端 API",
|
||||||
|
|||||||
+46
-37
@@ -20,6 +20,35 @@ SET default_tablespace = '';
|
|||||||
|
|
||||||
SET default_table_access_method = heap;
|
SET default_table_access_method = heap;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: user_role; Type: TYPE; Schema: public; Owner: ctms_user
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TYPE public.user_role AS ENUM (
|
||||||
|
'ADMIN',
|
||||||
|
'PM',
|
||||||
|
'CRA',
|
||||||
|
'PV',
|
||||||
|
'IMP'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TYPE public.user_role OWNER TO ctms_user;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: user_status; Type: TYPE; Schema: public; Owner: ctms_user
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TYPE public.user_status AS ENUM (
|
||||||
|
'PENDING',
|
||||||
|
'ACTIVE',
|
||||||
|
'REJECTED',
|
||||||
|
'DISABLED'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TYPE public.user_status OWNER TO ctms_user;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: adverse_events; Type: TABLE; Schema: public; Owner: ctms_user
|
-- Name: adverse_events; Type: TABLE; Schema: public; Owner: ctms_user
|
||||||
--
|
--
|
||||||
@@ -428,36 +457,23 @@ CREATE TABLE public.subjects (
|
|||||||
ALTER TABLE public.subjects OWNER TO ctms_user;
|
ALTER TABLE public.subjects OWNER TO ctms_user;
|
||||||
|
|
||||||
--
|
--
|
||||||
--
|
|
||||||
|
|
||||||
id uuid NOT NULL,
|
|
||||||
study_id uuid NOT NULL,
|
|
||||||
milestone_id uuid,
|
|
||||||
title character varying(200) NOT NULL,
|
|
||||||
description text,
|
|
||||||
assignee_id uuid,
|
|
||||||
priority character varying(20) NOT NULL,
|
|
||||||
due_date date,
|
|
||||||
status character varying(20) NOT NULL,
|
|
||||||
completed_at timestamp with time zone,
|
|
||||||
created_by uuid NOT NULL,
|
|
||||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
|
||||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: users; Type: TABLE; Schema: public; Owner: ctms_user
|
-- Name: users; Type: TABLE; Schema: public; Owner: ctms_user
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE public.users (
|
CREATE TABLE public.users (
|
||||||
id uuid NOT NULL,
|
id uuid NOT NULL,
|
||||||
username character varying(50) NOT NULL,
|
email character varying(255) NOT NULL,
|
||||||
hashed_password character varying(255) NOT NULL,
|
password_hash character varying(255) NOT NULL,
|
||||||
role character varying(20) NOT NULL,
|
full_name character varying(255) NOT NULL,
|
||||||
is_active boolean DEFAULT true NOT NULL,
|
role public.user_role NOT NULL,
|
||||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
department character varying(255) NOT NULL,
|
||||||
|
status public.user_status DEFAULT 'PENDING'::public.user_status NOT NULL,
|
||||||
|
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||||
|
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||||
|
approved_by uuid,
|
||||||
|
approved_at timestamp with time zone,
|
||||||
|
avatar_url character varying(500)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@@ -677,21 +693,14 @@ COPY public.subjects (id, study_id, site_id, subject_no, status, screening_date,
|
|||||||
\.
|
\.
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
--
|
|
||||||
|
|
||||||
77777777-7777-7777-7777-777777777777 44444444-4444-4444-4444-444444444444 66666666-6666-6666-6666-666666666666 伦理资料提交 准备伦理文件并提交 33333333-3333-3333-3333-333333333333 HIGH 2025-01-20 DOING \N 22222222-2222-2222-2222-222222222222 2025-12-18 00:55:17.568504+00 2025-12-18 00:55:17.568504+00
|
|
||||||
\.
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: ctms_user
|
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: ctms_user
|
||||||
--
|
--
|
||||||
|
|
||||||
COPY public.users (id, username, hashed_password, role, is_active, created_at) FROM stdin;
|
COPY public.users (id, email, password_hash, full_name, role, department, status, created_at, updated_at, approved_by, approved_at, avatar_url) FROM stdin;
|
||||||
11111111-1111-1111-1111-111111111111 admin@example.com $2b$12$wvADh3A4snBRZH9/24KWbO22h6mgE3TNquzD6cy0Zu7kKKnCouwzW ADMIN t 2025-12-18 00:55:17.568504+00
|
11111111-1111-1111-1111-111111111111 admin@example.com $2b$12$wvADh3A4snBRZH9/24KWbO22h6mgE3TNquzD6cy0Zu7kKKnCouwzW System Admin ADMIN SYSTEM ACTIVE 2025-12-18 00:55:17.568504+00 2025-12-18 00:55:17.568504+00 \N \N \N
|
||||||
22222222-2222-2222-2222-222222222222 pm@example.com $2b$12$qbIguZoGxPDhczU98iWKE.01lpBFnrrw5kbcQdwLLw.oduq9feGcu PM t 2025-12-18 00:55:17.568504+00
|
22222222-2222-2222-2222-222222222222 pm@example.com $2b$12$qbIguZoGxPDhczU98iWKE.01lpBFnrrw5kbcQdwLLw.oduq9feGcu Project Manager PM PMO ACTIVE 2025-12-18 00:55:17.568504+00 2025-12-18 00:55:17.568504+00 \N \N \N
|
||||||
33333333-3333-3333-3333-333333333333 cra@example.com $2b$12$3VtakMu1oJXLMOgu0ylNj.F6iqmIkRgP1XI51hzoIMwHccjeMW2nO CRA t 2025-12-18 00:55:17.568504+00
|
33333333-3333-3333-3333-333333333333 cra@example.com $2b$12$3VtakMu1oJXLMOgu0ylNj.F6iqmIkRgP1XI51hzoIMwHccjeMW2nO CRA User CRA CRA ACTIVE 2025-12-18 00:55:17.568504+00 2025-12-18 00:55:17.568504+00 \N \N \N
|
||||||
\.
|
\.
|
||||||
|
|
||||||
|
|
||||||
@@ -1193,10 +1202,10 @@ CREATE INDEX ix_subjects_study_id ON public.subjects USING btree (study_id);
|
|||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: ix_users_username; Type: INDEX; Schema: public; Owner: ctms_user
|
-- Name: ix_users_email; Type: INDEX; Schema: public; Owner: ctms_user
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE UNIQUE INDEX ix_users_username ON public.users USING btree (username);
|
CREATE UNIQUE INDEX ix_users_email ON public.users USING btree (email);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|||||||
Reference in New Issue
Block a user