You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动将创建超30天的Gallery数据迁移至Archive表?

问题说明

我在models.py中定义了Gallery模型,希望将创建时间超过30天的数据自动迁移至名为Archive的表中。现有models.py代码如下:

class Gallery(models.Model):
    id= models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    image = models.ImageField(upload_to='images/')
    video = models.FileField(upload_to='videos/', validators=[FileExtensionValidator( ['mp4', 'mov', 'mkv'] )])
    tag = models.CharField(max_length=100)
    classes = models.ForeignKey(Classes, null=True, blank=True, on_delete=models.CASCADE)
    level = models.ForeignKey(Level, null=True, blank=True, on_delete=models.CASCADE)
    uploded_date = models.DateTimeField(auto_now_add=True)
    

class Archive(models.Model):
    id= models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    image = models.ImageField(upload_to='images/')
    video = models.FileField(upload_to='videos/', validators=[FileExtensionValidator( ['mp4', 'mov', 'mkv'] )])
    tag = models.CharField(max_length=100)
    classes = models.ForeignKey(Classes, null=True, blank=True, on_delete=models.CASCADE)
    level = models.ForeignKey(Level, null=True, blank=True, on_delete=models.CASCADE)
    uploded_date = models.DateTimeField(auto_now_add=True)

尝试过用信号实现,但现有方法只在创建新记录时触发,无法持续检查并迁移超过30天的数据;修改Gallery的create和save方法也没解决问题,求有效方案。


解决方案

1. 先优化模型结构(可选但推荐)

两个模型字段完全一致,先定义抽象基类减少代码重复,同时修正拼写错误uploded_date→uploaded_date:

from django.db import models
from django.core.validators import FileExtensionValidator

class MediaBase(models.Model):
    name = models.CharField(max_length=100)
    image = models.ImageField(upload_to='images/')
    video = models.FileField(upload_to='videos/', validators=[FileExtensionValidator(['mp4', 'mov', 'mkv'])])
    tag = models.CharField(max_length=100)
    classes = models.ForeignKey('Classes', null=True, blank=True, on_delete=models.CASCADE)
    level = models.ForeignKey('Level', null=True, blank=True, on_delete=models.CASCADE)
    uploaded_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True

class Gallery(MediaBase):
    id = models.AutoField(primary_key=True)

class Archive(MediaBase):
    id = models.AutoField(primary_key=True)

2. 核心:定时任务实现自动迁移

信号和模型的save/create方法只能处理实时操作,要实现定期检查并迁移旧数据,必须用定时任务,以下是两种常用方案:

方案A:Django自定义管理命令 + 系统定时任务(轻量首选)

步骤1:创建自定义管理命令

在你的Django app下创建management/commands目录(无则新建),再新建archive_old_gallery.py文件:

from django.core.management.base import BaseCommand
from django.utils import timezone
from datetime import timedelta
from your_app.models import Gallery, Archive

class Command(BaseCommand):
    help = '将Gallery中超过30天的数据迁移到Archive'

    def handle(self, *args, **options):
        # 计算30天前的时间节点
        cutoff_date = timezone.now() - timedelta(days=30)
        # 筛选符合条件的旧数据
        old_items = Gallery.objects.filter(uploaded_date__lt=cutoff_date)
        
        if not old_items.exists():
            self.stdout.write(self.style.SUCCESS('没有需要迁移的旧数据'))
            return
        
        # 批量迁移至Archive
        archive_items = [
            Archive(
                name=item.name,
                image=item.image,
                video=item.video,
                tag=item.tag,
                classes=item.classes,
                level=item.level,
                uploaded_date=item.uploaded_date
            )
            for item in old_items
        ]
        Archive.objects.bulk_create(archive_items)
        
        # 删除Gallery中的旧数据
        old_items.delete()
        
        self.stdout.write(self.style.SUCCESS(f'成功迁移 {len(old_items)} 条数据到Archive'))

步骤2:配置系统定时任务

  • Linux系统:执行crontab -e添加定时规则,例:每天凌晨1点执行
0 1 * * * /path/to/your/virtualenv/bin/python /path/to/your/project/manage.py archive_old_gallery
  • Windows系统:通过「任务计划程序」配置定时执行上述命令

方案B:Celery + Celery Beat(适合复杂定时场景)

若项目已使用Celery,可通过Celery Beat管理定时任务:

步骤1:定义Celery任务

在tasks.py中添加:

from celery import shared_task
from django.utils import timezone
from datetime import timedelta
from your_app.models import Gallery, Archive

@shared_task
def archive_old_gallery_items():
    cutoff_date = timezone.now() - timedelta(days=30)
    old_items = Gallery.objects.filter(uploaded_date__lt=cutoff_date)
    
    if not old_items.exists():
        return
    
    archive_items = [
        Archive(
            name=item.name,
            image=item.image,
            video=item.video,
            tag=item.tag,
            classes=item.classes,
            level=item.level,
            uploaded_date=item.uploaded_date
        )
        for item in old_items
    ]
    Archive.objects.bulk_create(archive_items)
    old_items.delete()
    
    return f'Migrated {len(old_items)} items to Archive'

步骤2:配置Celery Beat定时规则

在项目Celery配置中添加:

from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    'archive-old-gallery-daily': {
        'task': 'your_app.tasks.archive_old_gallery_items',
        'schedule': crontab(hour=1, minute=0),  # 每天凌晨1点执行
    },
}

启动Celery Beat和Worker:

celery -A your_project beat -l info
celery -A your_project worker -l info

3. 可选:实时迁移辅助

若希望新创建的记录到期时自动迁移,可结合django-q2等任务队列,在创建记录时添加延迟任务,但定时任务仍是兜底方案,避免延迟任务丢失。


内容的提问来源于stack exchange,提问作者Sahil Mohile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:45:37