代码之家  ›  专栏  ›  技术社区  ›  Renier

如何正确更新表对象(元数据)

  •  0
  • Renier  · 技术社区  · 11 年前

    考虑以下事项:
    我知道要更新定义为:

    class MessageBoard(Base):
        __tablename__ = "messageboard"
        id = Column(
            Integer,
            Sequence('messageboard_id', optional=True),
            primary_key=True
        )
        title = Column(Unicode(40), index=True)
        message = Column(UnicodeText())
        to = Column(Unicode(40), index=True)
        # message_type = Column(Unicode(40), index=True) #could be email, sms, or PIMS interface
        created_by = Column(Unicode(40), index=True)
        create_stamp = Column(DateTime(), index=True)
        complete_stamp = Column(DateTime(), index=True)
        status = Column(Unicode(40), index=True)
        # message_type_id = Column(Integer, ForeignKey("board_message_type.id"))
        message_type = relationship(BoardMessageType, secondary=message_type_to_message, lazy="joined", join_depth=2, backref="messageboard")
        agents = relationship(Agents, secondary=agent_message, lazy="joined", join_depth=2, backref="messageboard")
    

    可以更新如下:

    s.query(
        MessageBoard
    ).filter(
        id == 1
    ).update(
        {"title": "How to update?"}
    )
    

    但我不知道如何更新定义如下的表:

    agent_message = Table(
        "agent_message",
        Base.metadata,
        Column("agents_id", Integer, ForeignKey("agents.id"), primary_key=True, onupdate="cascade"),
        Column("message_id", Integer, ForeignKey("messageboard.id"), primary_key=True),
        Column("status", Boolean, index=True, default=False) #if READ: True 
    )
    

    我尝试过:

    q = agent_message.update().where(
        and_(agent_message.c.message_id == read, agent_message.c.agents_id == self.user.agents_id)
    ).values(
        {"status": True}
    )
    s.execute(q)
    

    但这会引发一个错误,其中sql语句表示我要更新 agents_id 以及 status :

    IntegrityError: (IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (`likeminds_prepaid`.`agent_message`, CONSTRAINT `agent_message_ibfk_1` FOREIGN KEY (`agents_id`) REFERENCES `agents` (`id`))', None) u'UPDATE agent_message SET agents_id=?, status=? WHERE agent_message.message_id = ? AND agent_message.agents_id = ?' ('cascade', 1, u'3', 203671L)
    

    可以找到完整堆栈 here

    我也在谷歌上搜索了很多,但找不到如何更新上面定义的表并包含多个where子句的示例。。。


    更新

    我上面的代码有点错误,而不是使用:

    s.execute(q)
    

    应该是:

    q.execute()
    
    1 回复  |  直到 11 年前
        1
  •  1
  •   univerio    11 年前

    我认为这是由 onupdate="cascade" 参数 Column 构造函数,其含义与 onupdate 的参数 ForeignKey .

    Column documentation (强调矿井):

    • 更新 标量、Python可调用或ClauseElement表示要应用于UPDATE语句中的列的默认值[ 碳化硅 ]在更新时调用 如果更新的SET子句中不存在此列 .

    看起来你想要 onupdate=“级联” ForeignKey 构造函数:

    Column("agents_id", Integer, ForeignKey("agents.id", onupdate="cascade"), primary_key=True)