async def test_creating_snapshots(engine: Engine, create_snapshot: Callable,
                                  exclude: Set):

    async with engine.acquire() as conn:
        # get parent
        res: ResultProxy = await conn.execute(
            projects.select().where(projects.c.name == PARENT_PROJECT_NAME))
        parent_prj: Optional[RowProxy] = await res.first()

        assert parent_prj

        # take one snapshot
        first_snapshot_id = await create_snapshot(0, parent_prj, conn)

        # modify parent
        updated_parent_prj = await (await conn.execute(
            projects.update().values(description="foo").where(
                projects.c.id == parent_prj.id).returning(projects))).first()

        assert updated_parent_prj
        assert updated_parent_prj.id == parent_prj.id
        assert updated_parent_prj.description != parent_prj.description
        assert updated_parent_prj.creation_date < updated_parent_prj.last_change_date

        # take another snapshot
        second_snapshot_id = await create_snapshot(1, updated_parent_prj, conn)

        second_snapshot = await (await conn.execute(
            projects_snapshots.select().where(
                projects_snapshots.c.id == second_snapshot_id))).first()

        assert second_snapshot
        assert second_snapshot.id != first_snapshot_id
        assert second_snapshot.created_at == updated_parent_prj.last_change_date

        # get project corresponding to first snapshot
        j = projects.join(projects_snapshots,
                          projects.c.uuid == projects_snapshots.c.project_uuid)
        selected_snapshot_project = await (await conn.execute(
            projects.select().select_from(j).where(
                projects_snapshots.c.id == second_snapshot_id))).first()

        assert selected_snapshot_project
        assert selected_snapshot_project.uuid == second_snapshot.project_uuid
        assert parent_prj.uuid == second_snapshot.parent_uuid

        def extract(t):
            return {k: t[k] for k in t if k not in exclude.union({"name"})}

        assert extract(selected_snapshot_project) == extract(
            updated_parent_prj)
async def test_multiple_snapshots_of_same_project(engine: Engine,
                                                  create_snapshot: Callable):
    async with engine.acquire() as conn:
        # get parent
        res: ResultProxy = await conn.execute(
            projects.select().where(projects.c.name == PARENT_PROJECT_NAME))
        parent_prj: Optional[RowProxy] = await res.first()
        assert parent_prj

        # take first snapshot
        await create_snapshot(0, parent_prj, conn)

        # no changes in the parent!
        with pytest.raises(UniqueViolation):
            await create_snapshot(1, parent_prj, conn)
    def updator(project_uuid: str):
        with postgres_db.connect() as con:
            result = con.execute(
                projects.select().where(projects.c.uuid == project_uuid))
            prj_row = result.first()
            prj_workbench = prj_row.workbench

            result = con.execute(comp_tasks.select().where(
                comp_tasks.c.project_id == project_uuid))
            # let's get the results and run_hash
            for task_row in result:
                # pass these to the project workbench
                prj_workbench[task_row.node_id]["outputs"] = task_row.outputs
                prj_workbench[task_row.node_id]["runHash"] = task_row.run_hash

            con.execute(
                projects.update().values(workbench=prj_workbench).where(
                    projects.c.uuid == project_uuid))