Files
nanocode/new-media-platform/website-new/backend/migrate_storage.py
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

133 lines
5.0 KiB
Python

#!/usr/bin/env python3
"""
数据库迁移脚本:将旧的上传路径迁移到新的存储结构
使用同步 SQLAlchemy 进行数据库操作
"""
import sys
from pathlib import Path
# Add backend to path
sys.path.insert(0, str(Path(__file__).parent))
from sqlalchemy import create_engine, select, text
from sqlalchemy.orm import sessionmaker
from app.config import get_settings
settings = get_settings()
# 创建同步引擎
engine = create_engine(settings.DATABASE_URL.replace('+aiosqlite', ''), echo=False)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def migrate_image_paths():
"""迁移 Image 表中的路径"""
session = SessionLocal()
try:
# 获取所有图片
result = session.execute(text("SELECT id, file_path, thumb_path FROM images"))
images = result.fetchall()
updated_count = 0
for img in images:
img_id = img[0]
old_file_path = img[1]
old_thumb_path = img[2]
new_file_path = old_file_path
new_thumb_path = old_thumb_path
# 迁移 file_path
if old_file_path and not old_file_path.startswith('/storage/'):
if old_file_path.startswith('/'):
# 旧格式: /filename.jpg -> /storage/admin/images/filename.jpg
new_file_path = f"/storage/admin/images{old_file_path}"
else:
# 如果没有前导斜杠,添加一个
new_file_path = f"/storage/admin/images/{old_file_path}"
# 迁移 thumb_path
if old_thumb_path and not old_thumb_path.startswith('/storage/'):
if old_thumb_path.startswith('/'):
# 旧格式: /thumbnails/filename.jpg -> /storage/admin/images/thumbnails/filename.jpg
if old_thumb_path.startswith('/thumbnails/'):
new_thumb_path = f"/storage/admin/images{old_thumb_path}"
else:
new_thumb_path = f"/storage/admin/images/thumbnails{old_thumb_path}"
else:
new_thumb_path = f"/storage/admin/images/thumbnails/{old_thumb_path}"
if old_file_path != new_file_path or old_thumb_path != new_thumb_path:
session.execute(
text("UPDATE images SET file_path = :fp, thumb_path = :tp WHERE id = :id"),
{"fp": new_file_path, "tp": new_thumb_path, "id": img_id}
)
print(f" Image {img_id}: {old_file_path} -> {new_file_path}")
if old_thumb_path != new_thumb_path:
print(f" Thumb: {old_thumb_path} -> {new_thumb_path}")
updated_count += 1
session.commit()
print(f"\n✅ 迁移了 {updated_count} 张图片的路径")
finally:
session.close()
def migrate_news_cover_images():
"""迁移 NewsPost 表中的封面图片路径"""
session = SessionLocal()
try:
# 获取所有新闻文章
result = session.execute(text("SELECT id, cover_image FROM news_posts"))
posts = result.fetchall()
updated_count = 0
for post in posts:
post_id = post[0]
old_cover_image = post[1]
new_cover_image = old_cover_image
# 迁移 cover_image
if old_cover_image and not old_cover_image.startswith('/storage/'):
if old_cover_image.startswith('/'):
if old_cover_image.startswith('/uploads/'):
# 已经是 /uploads/ 格式,迁移到新的 storage 路径
filename = old_cover_image.replace('/uploads/', '')
new_cover_image = f"/storage/admin/images/{filename}"
else:
# 旧格式: /filename.jpg -> /storage/admin/images/filename.jpg
new_cover_image = f"/storage/admin/images{old_cover_image}"
else:
new_cover_image = f"/storage/admin/images/{old_cover_image}"
if old_cover_image != new_cover_image:
session.execute(
text("UPDATE news_posts SET cover_image = :ci WHERE id = :id"),
{"ci": new_cover_image, "id": post_id}
)
print(f" Post {post_id}: {old_cover_image} -> {new_cover_image}")
updated_count += 1
session.commit()
print(f"\n✅ 迁移了 {updated_count} 篇新闻的封面图片路径")
finally:
session.close()
def main():
print("=" * 60)
print("开始数据库路径迁移...")
print("=" * 60)
migrate_image_paths()
migrate_news_cover_images()
print("\n" + "=" * 60)
print("✅ 数据库迁移完成!")
print("=" * 60)
if __name__ == "__main__":
main()