需求:
想使用Python创建一个ETL工具,其中页面部分采用Django框架,调度的显示及控制通过Web页面进行操作。
因此调度的数据抽取、加载、存储过程跑数过程需要实时(准实时)显示处理记录条数(进度),因此需要开发局部刷新页面,以达到此效果。
备注:由于当前并未创建ETL工具,因此采用读取系统任务列表来举例。
实现过程:
1. django-admin创建项目(创建app)—— 步骤略。
2. 配置urls、templates目录、static目录及其下的js等内容 —— 步骤略。
3. 创建templates/index.html文件,内容如下:
4. 创建(或在app/views.py文件中)函数index和json_tasklist:<!DOCTYPE html> <html> <head> <span style="white-space:pre"> </span><title>RealTime Test</title> <span style="white-space:pre"> </span><meta charset="utf-8"> <span style="white-space:pre"> </span><meta http-equiv="X-UA-Compatible" content="IE=edge"> <span style="white-space:pre"> </span><meta name="viewport" content="width=device-width, initial-scale=1.0"> <span style="white-space:pre"> </span><meta name="author" content="sam"> <span style="white-space:pre"> </span><script src="/static/js/jquery-1.11.3.min.js"></script> <!-- 必要的js文件,jquery版本随意,1.4以上即可。 --> <span style="white-space:pre"> </span><script> function getjson(){ $.getJSON('/json/json_tasklist/', {}, function($jsondata) { //通过http://localhost:8000/json/json_tasklist/页面获取json数据 //当然,通过Django template tag技术也可以使用"{{json_data}}"方式传入json数据,使用什么方式自己随意了。 var $str_html = "<table><tr><th>映像名称</th><th>PID</th><th>会话名</th><th>会话#</th><th>内存使用</th></tr>"; $.each($jsondata.arr, function($index, $val) { $str_html += '<tr><td>'+$val[0]+'</td><td>'+$val[1]+'</td><td>'+$val[2]+'</td><td>'+$val[3]+'</td><td>'+$val[4]+'</td></tr>'; }); $str_html += "</table>"; $("#json").html($str_html); //生成一个table的html代码并展示出来。 }); } <span style="white-space:pre"> </span>$(function(){ getjson(); //初始化获取数据 $("#start").attr({disabled: 'disabled'}); var $timebreak = 500; //单位:ms var mytime = setInterval(function(){getjson()}, $timebreak); //通过setInterval设置超时执行函数 $("#start").click(function(event) { mytime = setInterval(function(){getjson()}, $timebreak); //点击start按钮开始每$timebreak毫秒刷新json的数据 $("#start").attr({disabled: 'disabled'}); $("#stop").removeAttr('disabled'); }); $("#stop").click(function(event) { clearInterval(mytime); //清除setInterval设置达到停止计数器的效果 $("#stop").attr({disabled: 'disabled'}); $("#start").removeAttr('disabled'); }); <span style="white-space:pre"> </span>}) <span style="white-space:pre"> </span></script> </head> <body> <button id="start">start</button> <button id="stop">stop</button> <p id="json">tasklist</p> </body> </html>
5. runserver:# -*- coding:utf-8 -*- from django.shortcuts import render_to_response from django.http import HttpResponse import json from subprocess import Popen, PIPE def index(req): '''No comment''' template = 'index.html' return render_to_response(template, {}) def json_tasklist(req): '''产生Json数据并显示在页面中 Args: None Returns: dict: {"arr":array_with_tasklist} Raises: None ''' #通过Popen命令执行cmd下的tasklist命令(windows中),在linux里面对应是使用ps -ef命令 #下面以tasklist命令为例,如果是ps -ef命令,分隔符和行格式都要相应变化 p = Popen(['tasklist'], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True) #转义unicode字符串并且按行分割成临时数组 arr_temp = p.stdout.read().decode('gbk').split('\r\n') col_len = [] #此数组用于记录每一个列的宽度 total_col = len(arr_temp[2].split(" ")) #共有多少列(实际上就是5列) for col in arr_temp[2].split(" "): col_len.append(len(col)) arr_p = [] #此数组存储最终的数据结果 for line in arr_temp[2:]: if line != "": #跳过空行(首尾) line_col = [] #每一行列数据的集合数组 left = 0 #数据片段的左端点 right = 0 #数据片段的右端点,结合在一起用来切分line字符串的 for i in range(total_col): if i == 0: left = 0 else: left = right + 1 right = left + col_len[i] line_col.append(line[left:right]) #切开,如果想要更完美一点,应该还需要trim一下的,不过python已经默认帮我们做了。 arr_p.append(line_col) jsondict = {"arr":arr_p} #生成json字典,形如:{"key1":[array1],"key2":"value2",......} jsondata = json.dumps(jsondict) #使用dumps方法格式化数据 return HttpResponse(jsondata)
后记:
1. 这种方式产生的计算压力除了在用户bownser刷新,还有会在服务端产生执行脚本的压力,建议不要实时查询数据库,而是通过读取文件的形式生成json数据,而且调整大的时间间隔,避免频繁调用产生的系统压力。
2. 这里需要调用js文件,如果没有正确配置static,就没法调用js,如果不会调用,可以参考以下文章:
实在不行的话,留言吧。