立项与伦理-初步优化,新增.env

This commit is contained in:
Cheng Zhou
2026-01-14 15:33:52 +08:00
parent f9ef5c109f
commit 4fc5f0ee9b
13 changed files with 733 additions and 297 deletions
@@ -0,0 +1,114 @@
"""Add site_id to startup feasibility and ethics.
Revision ID: 20250218_01
Revises: None
Create Date: 2025-02-18
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy import inspect
from sqlalchemy.dialects import postgresql
revision = "20250218_01"
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
bind = op.get_bind()
inspector = inspect(bind)
feasibility_columns = {col["name"] for col in inspector.get_columns("startup_feasibility")}
if "site_id" not in feasibility_columns:
op.add_column("startup_feasibility", sa.Column("site_id", postgresql.UUID(as_uuid=True), nullable=True))
feasibility_fks = {fk["name"] for fk in inspector.get_foreign_keys("startup_feasibility")}
if "fk_startup_feasibility_site_id" not in feasibility_fks:
op.create_foreign_key(
"fk_startup_feasibility_site_id",
"startup_feasibility",
"sites",
["site_id"],
["id"],
ondelete="RESTRICT",
)
ethics_columns = {col["name"] for col in inspector.get_columns("startup_ethics")}
if "site_id" not in ethics_columns:
op.add_column("startup_ethics", sa.Column("site_id", postgresql.UUID(as_uuid=True), nullable=True))
ethics_fks = {fk["name"] for fk in inspector.get_foreign_keys("startup_ethics")}
if "fk_startup_ethics_site_id" not in ethics_fks:
op.create_foreign_key(
"fk_startup_ethics_site_id",
"startup_ethics",
"sites",
["site_id"],
["id"],
ondelete="RESTRICT",
)
# Best-effort backfill for demo data where codes include BJ/SH.
op.execute(
"""
UPDATE startup_feasibility
SET site_id = (
SELECT id FROM sites
WHERE name ILIKE '%北京%' OR city ILIKE '%北京%'
LIMIT 1
)
WHERE site_id IS NULL AND project_no ILIKE '%-BJ-%'
"""
)
op.execute(
"""
UPDATE startup_feasibility
SET site_id = (
SELECT id FROM sites
WHERE name ILIKE '%上海%' OR city ILIKE '%上海%'
LIMIT 1
)
WHERE site_id IS NULL AND project_no ILIKE '%-SH-%'
"""
)
op.execute(
"""
UPDATE startup_ethics
SET site_id = (
SELECT id FROM sites
WHERE name ILIKE '%北京%' OR city ILIKE '%北京%'
LIMIT 1
)
WHERE site_id IS NULL AND approval_no ILIKE '%-BJ-%'
"""
)
op.execute(
"""
UPDATE startup_ethics
SET site_id = (
SELECT id FROM sites
WHERE name ILIKE '%上海%' OR city ILIKE '%上海%'
LIMIT 1
)
WHERE site_id IS NULL AND approval_no ILIKE '%-SH-%'
"""
)
def downgrade() -> None:
bind = op.get_bind()
inspector = inspect(bind)
feasibility_fks = {fk["name"] for fk in inspector.get_foreign_keys("startup_feasibility")}
if "fk_startup_feasibility_site_id" in feasibility_fks:
op.drop_constraint("fk_startup_feasibility_site_id", "startup_feasibility", type_="foreignkey")
feasibility_columns = {col["name"] for col in inspector.get_columns("startup_feasibility")}
if "site_id" in feasibility_columns:
op.drop_column("startup_feasibility", "site_id")
ethics_fks = {fk["name"] for fk in inspector.get_foreign_keys("startup_ethics")}
if "fk_startup_ethics_site_id" in ethics_fks:
op.drop_constraint("fk_startup_ethics_site_id", "startup_ethics", type_="foreignkey")
ethics_columns = {col["name"] for col in inspector.get_columns("startup_ethics")}
if "site_id" in ethics_columns:
op.drop_column("startup_ethics", "site_id")
+2
View File
@@ -28,6 +28,7 @@ async def create_feasibility(
) -> StartupFeasibility:
record = StartupFeasibility(
study_id=study_id,
site_id=record_in.site_id,
submit_date=record_in.submit_date,
accept_date=record_in.accept_date,
approved_date=record_in.approved_date,
@@ -86,6 +87,7 @@ async def create_ethics(
) -> StartupEthics:
record = StartupEthics(
study_id=study_id,
site_id=record_in.site_id,
submit_date=record_in.submit_date,
accept_date=record_in.accept_date,
meeting_date=record_in.meeting_date,
+1
View File
@@ -13,6 +13,7 @@ class StartupEthics(Base):
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
study_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("studies.id"), index=True, nullable=False)
site_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), nullable=True)
submit_date: Mapped[date | None] = mapped_column(Date, nullable=True)
accept_date: Mapped[date | None] = mapped_column(Date, nullable=True)
meeting_date: Mapped[date | None] = mapped_column(Date, nullable=True)
@@ -13,6 +13,7 @@ class StartupFeasibility(Base):
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
study_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("studies.id"), index=True, nullable=False)
site_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), nullable=True)
submit_date: Mapped[date | None] = mapped_column(Date, nullable=True)
accept_date: Mapped[date | None] = mapped_column(Date, nullable=True)
approved_date: Mapped[date | None] = mapped_column(Date, nullable=True)
+6
View File
@@ -6,6 +6,7 @@ from pydantic import BaseModel, ConfigDict
class StartupFeasibilityCreate(BaseModel):
site_id: Optional[uuid.UUID] = None
submit_date: Optional[date] = None
accept_date: Optional[date] = None
approved_date: Optional[date] = None
@@ -13,6 +14,7 @@ class StartupFeasibilityCreate(BaseModel):
class StartupFeasibilityUpdate(BaseModel):
site_id: Optional[uuid.UUID] = None
submit_date: Optional[date] = None
accept_date: Optional[date] = None
approved_date: Optional[date] = None
@@ -22,6 +24,7 @@ class StartupFeasibilityUpdate(BaseModel):
class StartupFeasibilityRead(BaseModel):
id: uuid.UUID
study_id: uuid.UUID
site_id: Optional[uuid.UUID]
submit_date: Optional[date]
accept_date: Optional[date]
approved_date: Optional[date]
@@ -34,6 +37,7 @@ class StartupFeasibilityRead(BaseModel):
class StartupEthicsCreate(BaseModel):
site_id: Optional[uuid.UUID] = None
submit_date: Optional[date] = None
accept_date: Optional[date] = None
meeting_date: Optional[date] = None
@@ -42,6 +46,7 @@ class StartupEthicsCreate(BaseModel):
class StartupEthicsUpdate(BaseModel):
site_id: Optional[uuid.UUID] = None
submit_date: Optional[date] = None
accept_date: Optional[date] = None
meeting_date: Optional[date] = None
@@ -52,6 +57,7 @@ class StartupEthicsUpdate(BaseModel):
class StartupEthicsRead(BaseModel):
id: uuid.UUID
study_id: uuid.UUID
site_id: Optional[uuid.UUID]
submit_date: Optional[date]
accept_date: Optional[date]
meeting_date: Optional[date]