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:
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user