refactor: unify data preparations and research input snapshots
Deploy production / deploy (push) Successful in 53s
Deploy production / deploy (push) Successful in 53s
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Replace saved dataset inputs with editable preparations and independent snapshots."""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision = "0015"
|
||||
down_revision = "0014"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_table("template_inputs")
|
||||
op.add_column("catalog_batches", sa.Column("job_id", sa.String(36), nullable=True))
|
||||
op.add_column("catalog_batches", sa.Column("offset", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.execute("UPDATE catalog_batches SET job_id = id")
|
||||
# Preserve unfinished catalog pagination; only legacy research inputs are discarded.
|
||||
jobs = sa.table("sync_jobs", sa.column("id"), sa.column("checkpoint", sa.JSON()))
|
||||
batches = sa.table("catalog_batches", sa.column("id"), sa.column("offset", sa.Integer()))
|
||||
for job_id, checkpoint in op.get_bind().execute(sa.select(jobs.c.id, jobs.c.checkpoint)):
|
||||
offset = (checkpoint or {}).get("offset", 0)
|
||||
if type(offset) is int and offset >= 0:
|
||||
op.get_bind().execute(batches.update().where(batches.c.id == job_id).values(offset=offset))
|
||||
names = {"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s"}
|
||||
fk = next(
|
||||
f
|
||||
for f in sa.inspect(op.get_bind()).get_foreign_keys("catalog_batches")
|
||||
if f["constrained_columns"] == ["id"]
|
||||
)
|
||||
with op.batch_alter_table("catalog_batches", naming_convention=names) as batch:
|
||||
batch.drop_constraint(fk["name"] or "fk_catalog_batches_id_sync_jobs", type_="foreignkey")
|
||||
batch.alter_column("job_id", existing_type=sa.String(36), nullable=False)
|
||||
batch.create_foreign_key("fk_catalog_batches_job", "sync_jobs", ["job_id"], ["id"])
|
||||
batch.create_index("ix_catalog_batches_job_id", ["job_id"])
|
||||
op.create_table(
|
||||
"data_preparations",
|
||||
sa.Column("id", sa.String(36), primary_key=True),
|
||||
sa.Column("name", sa.String(200), nullable=False),
|
||||
sa.Column("note", sa.Text(), nullable=False),
|
||||
sa.Column("scope_key", sa.String(200), nullable=False),
|
||||
sa.Column("scope", sa.JSON(), nullable=False),
|
||||
sa.Column("version", sa.Integer(), nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
|
||||
)
|
||||
op.create_index("ix_data_preparations_scope_key", "data_preparations", ["scope_key"])
|
||||
op.create_table(
|
||||
"preparation_fields",
|
||||
sa.Column(
|
||||
"preparation_id",
|
||||
sa.String(36),
|
||||
sa.ForeignKey("data_preparations.id", ondelete="CASCADE"),
|
||||
primary_key=True,
|
||||
),
|
||||
sa.Column("field_id", sa.String(200), primary_key=True),
|
||||
sa.Column("dataset_id", sa.String(200), nullable=False),
|
||||
sa.Column("content", sa.JSON(), nullable=False),
|
||||
)
|
||||
op.create_index("ix_preparation_fields_dataset_id", "preparation_fields", ["dataset_id"])
|
||||
op.create_table(
|
||||
"research_input_snapshots",
|
||||
sa.Column("id", sa.String(36), primary_key=True),
|
||||
sa.Column("preparation_id", sa.String(36), nullable=False),
|
||||
sa.Column("preparation_version", sa.Integer(), nullable=False),
|
||||
sa.Column("content", sa.JSON(), nullable=False),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
|
||||
sa.UniqueConstraint("preparation_id", "preparation_version"),
|
||||
)
|
||||
op.create_index(
|
||||
"ix_research_input_snapshots_preparation_id", "research_input_snapshots", ["preparation_id"]
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
raise RuntimeError("旧输入模型已移除;回退请恢复升级前数据库备份")
|
||||
Reference in New Issue
Block a user