SAWarning:<child>类型的对象不在会话中,沿着&#39; Parent.children&#39;添加操作。不会继续

时间:2017-12-20 18:47:18

标签: python sqlalchemy flask-sqlalchemy

我坚持这个问题并且我不知道如何解决它。这是我的models.py文件:

models.py

class TripDetail(db.Model):
    """
    Base class for every table that contains info about a trip.
    """
    __abstract__ = True
    __bind_key__ = 'instructions'

    id = db.Column(db.Integer, primary_key=True)
    # list of fields    

class Overview(TripDetail):
    """
    Class that contains general information about a trip.
    """
    __tablename__ = 'overviews'
    __table_args__ = (
        db.ForeignKeyConstraint(['user_id', 'calendar_id'], ['calendars.user_id', 'calendars.id'], ondelete='CASCADE'),
    )  # constraints on other tables, omitted here
    user_id = db.Column(db.Integer, primary_key=True)
    calendar_id = db.Column(db.Integer, primary_key=True)
    calendar = db.relationship('Calendar', backref=db.backref('overviews', cascade='delete'), passive_deletes=True)
    # other fields

class Step(TripDetail):
    __tablename__ = 'steps'

    overview_id = db.Column(db.Integer, db.ForeignKey('overviews.id', ondelete='CASCADE'))
    overview = db.relationship('Overview', backref=db.backref('steps', cascade='delete'), passive_deletes=True)
    # also other fields

这就是我向DB添加项目的方式(响应参数包含一个与类匹配的dict,以便可以直接解压缩):

def add_instruction(response):
    """
    Adds a travel instruction to the database.
    """
    steps = response.pop('steps')
    overview = Overview(**response)
    for step in steps:
        Step(overview=overview, **step)
    db.session.add(overview)
    db.session.commit()
    logger.info(f"Stored instruction with PK {(overview.id, overview.user_id, overview.calendar_id, overview.event_id)}")

现在,overviews表格已正确填写,但steps保持为空。检查日志,我收到此警告:

  

SAWarning:类型不在会话中的对象,沿着&#39; Overview.steps&#39;添加操作。不会继续     (orm_util.state_class_str(state),operation,prop))

我做错了什么?

2 个答案:

答案 0 :(得分:4)

通常,当add()对象加入会话时,它们的相关对象将按您的需要自动添加。该行为由关系cascade控制。

cascade中将'delete'设置为Steps.overview会删除默认'save-update',这就是打开自动添加的内容。您可以将其添加回cascade='save-update, delete',但请查看possible traits并查看您可能需要的其他内容。常见的集合是'all, delete-orphan'

请记住这些是严格的ORM行为;在级联中设置'delete'不会设置列ON [event] CASCADE

答案 1 :(得分:0)

嗯,我通过明确地将创建的步骤添加到会话中来解决这个问题。仍然不知道警告意味着什么,所以我只是把它留在这里。我的修复:

for step in steps:
    step = Step(overview=overview, **step)  # explicitly add
    db.session.add(step)