首页 > 解决方案 > 外键更改时更新引用表

问题描述

使用 SQLAlchemy 1.3.22、Python 3.8、PostgreSQL 12

我有这些模型:

RecordAndTask = Table('record_and_task', Base.metadata, 
                      Column('record_id', String, ForeignKey('record.id'), primary_key=True),
                      Column('task_id', String, ForeignKey('task.id'), primary_key=True))

RecordAndWidget = Table('record_and_widget', Base.metadata,
                        Column('record_id', String, ForeignKey('record.id'), primary_key=True),
                        Column('widget_id', String, ForeignKey('widget.id'), primary_key=True))


class Record(Base):
    __tablename__ = 'record'

    id = Column(String, primary_key=True)

    tasks = relationship('Task', secondary=RecordAndTask, backref=backref('records', lazy='dynamic'), lazy='dynamic')
    widgets = relationship('Widget', secondary=RecordAndWidget, backref=backref('records', lazy='dynamic'), lazy='dynamic')


class Task(Base):
    __tablename__ = 'task'

    id = Column(String, primary_key=True)
    status = Column(String)

    widget_id = Column(String, ForeignKey('widget.id'))


class Widget(Base):
    __tablename__ = 'widget'

    id = Column(String, primary_key=True)

    tasks = relationship('Task', backref='widget', lazy='dynamic')

PostgreSQL 表中的数据。

记录表(3行):

id='record_1'
id='record_2'
id='record_3'

任务表(3行):

id='task_1', status='done', widget_id='widget_1'  
id='task_2', status='failed', widget_id='widget_3'
id='task_3', status='done', widget_id='widget_2'  

小部件表(3 行):

id='widget_1'
id='widget_2'
id='widget_3'

record_and_task(3行):

record_id='record_1', task_id='task_1'
record_id='record_1', task_id='task_2'
record_id='record_2', task_id='task_3'

record_and_widget(3行):

record_id='record_1', widget_id='widget_1'
record_id='record_1', widget_id='widget_3'
record_id='record_2', widget_id='widget_2'

Taskwidget_id中更改时是否可以更改record_and_widget?简单示例(对应上表中的数据)。widget_id

  1. 如果不是,则有必要再次执行任务statusdone
  2. 在此执行期间widget_id可能会发生变化。
  3. 我需要更新record_and_widget表中的关系,因为任务widget_id已更改,例如从更改widget_3widget_2

执行后应该有:

任务

id='task_1', status='done', widget_id='widget_1'  
id='task_2', status='done', widget_id='widget_2'        <-- status changed from 'failed' to 'done', widget_id changed from 'widget_3' to 'widget_2'
id='task_3', status='done', widget_id='widget_2' 

record_and_widget

record_id='record_1', widget_id='widget_1'
record_id='record_1', widget_id='widget_2'              <-- widget_id SHOULD change there (from 'widget_3' to 'widget_2')
record_id='record_2', widget_id='widget_2'

我错过了什么?我在所有对应的模型中都插入了onupdate/cascade='all'参数,但是没有效果。也许我做错了。

标签: pythonpostgresqlsqlalchemymany-to-many

解决方案


推荐阅读