sqlalchemy - 如何复制深拷贝条目及其所有外来关系

问题描述 投票:1回答:1

现在我有了一个数据库模式:

enter image description here

对于视频,它包含许多段,对于段,它包含许多作业,并且在每个作业中它包含许多路径等等......

现在我想复制片段并组合在一起制作一个新视频。我知道我可以编写一个脚本来从段到作业循环到...到bbox并逐个复制所有条目。但有没有更好的解决方案,我可以更智能地进行深拷贝及其所有外国关系输入?

python mysql sqlalchemy
1个回答
0
投票

我试图找到一个解决方案,但最终添加了上面的评论链接中的一些用户建议的手动复制方法,但我选择了一个更简单的手动方法,在我的情况下,简化的事情。在您的示例中,我的解决方案看起来像这样:

class Video(Model):
    __tablename__ = 'videos'

    id = Column(Integer, primary_key=True)
    vidcol1 = Column(...)
    vidcol2 = Column(...)

    segments = relationship('Segment', uselist=True)

    def copy(self):
        new = Video()
        new.vidcol1 = self.vidcol1
        new.vidcol2 = self.vidcol2
        for segment in self.segments:
            new.segments.append(segment.copy())
        return new


class Segment(Model):
    __tablename__ = 'segments'

    id = Column(Integer, primary_key=True)
    video_id = Column(Integer, ForeignKey('videos.id'))
    segcol1 = Column(...)
    segcol2 = Column(...)

    jobs = relationship('Job', uselist=True)

    def copy(self):
        new = Segment()
        new.segcol1 = self.segcol1
        new.segcol2 = self.segcol2
        for job in self.jobs:
            new.jobs.append(job.copy())
        return new


class Job(Model):
    __tablename__ = 'jobs'

    id = Column(Integer, primary_key=True)
    segment_id = Column(Integer, ForeignKey('segments.id'))
    jobcol1 = Column(...)
    jobcol2 = Column(...)

    paths = relationship('Path', uselist=True)

    def copy(self):
        new = Job()
        new.jobcol1 = self.jobcol1
        new.jobcol2 = self.jobcol2
        for path in self.paths:
            new.paths.append(path.copy())
        return new


class Path(Model):
    __tablename__ = 'paths'

    id = Column(Integer, primary_key=True)
    job_id = Column(Integer, ForeignKey('jobs.id'))
    pthcol1 = Column(...)
    pthcol2 = Column(...)

    bboxs = relationship('BBox', uselist=True)

    def copy(self):
        new = Path()
        new.pthcol1 = self.pthcol1
        new.pthcol2 = self.pthcol2
        for bbox in self.bboxs:
            new.bboxs.append(bbox.copy())
        return new


class BBox(Model):
    __tablename__ = 'bboxs'

    id = Column(Integer, primary_key=True)
    path_id = Column(Integer, ForeignKey('paths.id'))
    boxcol1 = Column(...)
    boxcol2 = Column(...)

    def copy(self):
        new = BBox()
        new.boxcol1 = self.boxcol1
        new.boxcol2 = self.boxcol2
        return new

每个模型负责复制自己的列并调用其直接关系的复制方法。通过这种方式,视频无需了解所有更深层次的关系,您可以执行以下操作:

video_copy = existing_video.copy()
session.add(video_copy)
session.commit()

在我的情况下,我也有多对多的关系(作为辅助表和AssociationObjects)。如果你想添加其他类型的关系,那就不会太复杂了。

© www.soinside.com 2019 - 2024. All rights reserved.