fix: rename metadata to extra_meta to avoid SQLAlchemy reserved field conflict

SQLAlchemy's 'metadata' attribute is reserved for model metadata, causing
service startup crash. Changed to 'extra_meta' with Column('metadata', JSON)
mapping to preserve database column name.

Affected models (7):
- AssetLibraryModel, AssetModel, AssetClassificationModel
- GenerationTaskModel, DuplicationRecordModel
- TitleLibraryModel, VoiceLibraryModel

Updated all references across:
- packages/adapters/sqlalchemy_impl/{title_library,voice_library,asset}_repository.py
- apps/worker/worker_app/{core/asset_usage.py,tasks/voice_extraction.py}
- apps/api/app/api/routes/{asset_diagnosis.py,assets.py}
This commit is contained in:
API文档维护Agent
2026-06-28 16:49:23 +08:00
parent ea0bde3742
commit 87360051fa
8 changed files with 32 additions and 32 deletions
+4 -4
View File
@@ -49,12 +49,12 @@ def _build_diagnosis(project_id: str, assets: list[Asset]) -> ProjectAssetDiagno
asset
for asset in ready_assets
if (asset.quality_score is not None and asset.quality_score < 60)
or asset.metadata.get("review_status") == "rejected"
or asset.extra_meta.get("review_status") == "rejected"
or asset.status == AssetStatus.ERROR
]
used_assets = [asset for asset in ready_assets if int(asset.metadata.get("generation_use_count") or 0) > 0]
unused_assets = [asset for asset in ready_assets if int(asset.metadata.get("generation_use_count") or 0) == 0]
pending_review_assets = [asset for asset in ready_assets if asset.metadata.get("review_status") == "pending_review"]
used_assets = [asset for asset in ready_assets if int(asset.extra_meta.get("generation_use_count") or 0) > 0]
unused_assets = [asset for asset in ready_assets if int(asset.extra_meta.get("generation_use_count") or 0) == 0]
pending_review_assets = [asset for asset in ready_assets if asset.extra_meta.get("review_status") == "pending_review"]
total_duration = round(sum(float(asset.duration or 0) for asset in video_assets), 2)
estimated_video_count = max(
0, min(len(video_assets), int(total_duration // 5) if total_duration else len(video_assets))
+3 -3
View File
@@ -27,7 +27,7 @@ def _to_asset_response(item) -> AssetResponse:
name=item.name,
storage_key=item.storage_key,
mime_type=item.mime_type,
metadata=item.metadata,
metadata=item.extra_meta,
file_size=item.file_size,
thumbnail_url=item.thumbnail_url,
duration=item.duration,
@@ -69,8 +69,8 @@ def list_assets(
def _apply_asset_review_status(item, review_status: str):
item.metadata = {
**item.metadata,
item.extra_meta = {
**item.extra_meta,
"review_status": review_status,
}
return item
+4 -4
View File
@@ -2,9 +2,9 @@ from datetime import datetime, timezone
def mark_asset_used_for_generation(asset) -> None:
asset.metadata = {
**asset.metadata,
"generation_use_count": int(asset.metadata.get("generation_use_count") or 0) + 1,
asset.extra_meta = {
**asset.extra_meta,
"generation_use_count": int(asset.extra_meta.get("generation_use_count") or 0) + 1,
"last_used_at": datetime.now(timezone.utc).isoformat(),
"review_status": asset.metadata.get("review_status") or "pending_review",
"review_status": asset.extra_meta.get("review_status") or "pending_review",
}
@@ -66,9 +66,9 @@ def extract_voice_task(self: Task, asset_id: str) -> dict:
voice_storage_key = f"assets/{asset_id}/voice.mp3"
storage_service.upload_file(voice_output_path, voice_storage_key)
voice_url = storage_service.get_url(voice_storage_key)
if asset.metadata is None:
asset.metadata = {}
asset.metadata["voice_url"] = voice_url
if asset.extra_meta is None:
asset.extra_meta = {}
asset.extra_meta["voice_url"] = voice_url
asset_repo.update(asset)
session.commit()
logger.info(f"Voice extraction completed for asset {asset_id}: {voice_url}")
@@ -101,9 +101,9 @@ def extract_background_task(self: Task, asset_id: str) -> dict:
bg_storage_key = f"assets/{asset_id}/background.mp3"
storage_service.upload_file(bg_output_path, bg_storage_key)
bg_url = storage_service.get_url(bg_storage_key)
if asset.metadata is None:
asset.metadata = {}
asset.metadata["background_url"] = bg_url
if asset.extra_meta is None:
asset.extra_meta = {}
asset.extra_meta["background_url"] = bg_url
asset_repo.update(asset)
session.commit()
logger.info(f"Background extraction completed for asset {asset_id}: {bg_url}")
@@ -60,7 +60,7 @@ class SQLAlchemyAssetRepository:
codec=asset.codec,
status=asset.status.value,
classification_status=asset.classification_status.value,
classification_result=(json.dumps(asset.metadata) if asset.metadata else None),
classification_result=(json.dumps(asset.extra_meta) if asset.extra_meta else None),
quality_score=asset.quality_score,
uploaded_by_user_id=asset.uploaded_by_user_id or "system",
created_at=asset.created_at,
@@ -85,7 +85,7 @@ class SQLAlchemyAssetRepository:
model.codec = asset.codec
model.status = asset.status.value
model.classification_status = asset.classification_status.value
model.classification_result = json.dumps(asset.metadata) if asset.metadata else None
model.classification_result = json.dumps(asset.extra_meta) if asset.extra_meta else None
model.quality_score = asset.quality_score
model.uploaded_by_user_id = asset.uploaded_by_user_id or model.uploaded_by_user_id
model.updated_at = datetime.now(timezone.utc)
+7 -7
View File
@@ -39,7 +39,7 @@ class ProjectModel(Base):
name = Column(String(100), nullable=False)
description = Column(Text, nullable=False, default="")
shared_users = Column(JSON, nullable=False, default=list) # 被共享的用户 ID 列表
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -52,7 +52,7 @@ class AssetLibraryModel(Base):
kind = Column(String(20), nullable=False, index=True)
asset_count = Column(Float, nullable=False, default=0)
total_size = Column(Float, nullable=False, default=0)
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -82,7 +82,7 @@ class AssetModel(Base):
classification_result = Column(Text, nullable=True)
quality_score = Column(Float, nullable=True)
uploaded_by_user_id = Column(String(36), nullable=False)
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc), index=True)
updated_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -99,7 +99,7 @@ class EditTemplateModel(Base):
clip_count = Column(Integer, nullable=False, default=3)
is_active = Column(Boolean, nullable=False, default=True)
created_by_user_id = Column(String(32), nullable=False, default="")
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -151,7 +151,7 @@ class GenerationTaskModel(Base):
started_at = Column(DateTime, nullable=True)
completed_at = Column(DateTime, nullable=True)
created_by_user_id = Column(String(32), nullable=False, default="")
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -197,7 +197,7 @@ class TitleLibraryModel(Base):
tags = Column(JSON, nullable=False, default=list)
usage_count = Column(Integer, nullable=False, default=0)
is_active = Column(Boolean, nullable=False, default=True, index=True)
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -218,7 +218,7 @@ class VoiceLibraryModel(Base):
file_size = Column(Integer, nullable=False, default=0)
status = Column(String(20), nullable=False, default="completed", index=True)
tags = Column(JSON, nullable=False, default=list)
metadata = Column(JSON, nullable=False, default=dict)
extra_meta = Column('metadata', JSON, nullable=False, default=dict)
created_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, nullable=False, default=lambda: datetime.now(timezone.utc))
@@ -54,7 +54,7 @@ class SQLAlchemyTitleLibraryRepository:
tags=item.tags,
usage_count=item.usage_count,
is_active=item.is_active,
metadata=item.metadata_,
extra_meta=item.metadata_,
)
self.session.add(model)
self.session.commit()
@@ -74,7 +74,7 @@ class SQLAlchemyTitleLibraryRepository:
model.text = item.text
model.tags = item.tags
model.is_active = item.is_active
model.metadata = item.metadata_
model.extra_meta = item.metadata_
self.session.commit()
self.session.refresh(model)
return self._model_to_entity(model)
@@ -108,7 +108,7 @@ class SQLAlchemyTitleLibraryRepository:
tags=model.tags or [],
usage_count=model.usage_count or 0,
is_active=model.is_active,
metadata_=model.metadata or {},
metadata_=model.extra_meta or {},
created_at=model.created_at,
updated_at=model.updated_at,
)
@@ -56,7 +56,7 @@ class SQLAlchemyVoiceLibraryRepository:
file_size=item.file_size,
status=item.status,
tags=item.tags,
metadata=item.metadata_,
extra_meta=item.metadata_,
)
self.session.add(model)
self.session.commit()
@@ -80,7 +80,7 @@ class SQLAlchemyVoiceLibraryRepository:
model.file_size = item.file_size
model.status = item.status
model.tags = item.tags
model.metadata = item.metadata_
model.extra_meta = item.metadata_
self.session.commit()
self.session.refresh(model)
return self._model_to_entity(model)
@@ -119,7 +119,7 @@ class SQLAlchemyVoiceLibraryRepository:
status=model.status,
project_id=model.project_id if model.project_id else None,
tags=model.tags or [],
metadata_=model.metadata or {},
metadata_=model.extra_meta or {},
created_at=model.created_at,
updated_at=model.updated_at,
)