Sqlachemy问题。无法理解差异

时间:2018-11-08 07:20:51

标签: python sql sqlalchemy

我有以下代码

def update(project_id, code, description):

    if project_id is None:
        raise exception

    with session_handler() as session:
        project = session.query(Project).filter_by(project_id=project_id).first()
        project_upd = session.query(Project).filter_by(project_id=project_id)

    if project is None:
        raise ProjectDoesntExist(f"Project {project_id} does not exist.")
    data = _build_update_data(code, description)

    if  not data:
        raise ValueError("No code or description provided")

    project_upd.update(data)

因此,如果我将project_upd.update(data)替换为project.update(data),则会出现以下错误

  

属性错误:项目对象没有属性更新。

我怎么只能使用一个变量?

1 个答案:

答案 0 :(得分:2)

尽管省略了Project模型,但很显然它没有方法update() –这是常态。区别在于project绑定到Project对象,project_upd绑定到Query对象。换句话说,前者代表映射到对象的表中的一行,而后者代表针对该表的查询。

您的选择是:

  1. 仅发出UPDATE语句,并检查它是否与任何行匹配,如果不匹配则抛出。
  2. 获取行/对象for update,检查其是否存在,如果不存在,则进行更新。

如果没有引发异常,我认为session_handler()会提交。如果不是这种情况,请根据需要添加一个明确的session.commit()

1。一条UPDATE语句

def update(project_id, code, description):
    if project_id is None:
        raise exception

    data = _build_update_data(code, description)

    if not data:
        raise ValueError("No code or description provided")

    with session_handler() as session:
        row_count = session.query(Project).\
            filter_by(project_id=project_id).\
            update(data)

        if not row_count:
            raise ProjectDoesntExist(f"Project {project_id} does not exist.")

2。获取并更新

def update(project_id, code, description):
    if project_id is None:
        raise exception

    data = _build_update_data(code, description)

    if not data:
        raise ValueError("No code or description provided")

    with session_handler() as session:
        # Fetch FOR UPDATE so that no concurrent updates may proceed in between
        # getting the `Project` instance and actually updating it.
        project = session.query(Project).\
            filter_by(project_id=project_id).\
            with_for_update().\
            first()

        if project is None:
            raise ProjectDoesntExist(f"Project {project_id} does not exist.")

        for attr, val in data.items():
            setattr(project, attr, val)

在这种情况下,用FOR UPDATE进行锁定可能是不必要的,因为新值似乎并不取决于对象的先前状态。仍然要记住这一点。