ETL应用场景中,若对端接口文件未能提供,任务会处于循环等待,直到对端提供为止,该方法极大的消耗了系统资源。为此想到了一种方法,一次获取一个平台的文件,实现思路如下:

1、第一次获取对端平台提供目录下给定日期的所有接口文件,并保存文件列表;

2、后续每隔n分钟重启获取任务,每次先获取文件列表,和上次列表进行对比,当发生如下情况时,会重新获取:

A、有新文件产生;

B、有文件大小变化

实现方法如下:

  1. [ftp.properties]
  2.  
  3. ipaddress = 10.25.xxx.xxx
  4. username = xxxxx
  5. password = xxxxx
  6.  
  7. #\u5F53 encryption \u6709\u503C\u65F6\uFF0C\u5C06\u8FDB\u884C\u5BC6\u7801\u89E3\u6790
  8. encryption =
  9.  
  10. #\u5F53resolve \u4E3A False\u65F6\uFF0C\u9700\u8981\u66FF\u6362\u8FDC\u7A0B\u76EE\u5F55\u548C\u5F53\u524D\u76EE\u5F55\u7684\u53C2\u6570
  11. resolve = 1
  12. remoteDir = /bosscdr/tobak/jf_bass
  13. localDir = /interface/cyg/[SDT_YYYYMMDD]
  14.  
  15. #\u4E0A\u6B21\u4FDD\u5B58\u7684\u6587\u4EF6\u83B7\u53D6\u5217\u8868
  16. lastFileList = /interface/cyg/lastfilelist.txt
  1. # -*- coding:utf-8 -*-
  2. '''
  3. 函数说明 :获取远程文件
  4. 编写时间: 2015-5-5
  5. 编 写 人 : chenyangang
  6. ----------------------------------------
  7. 实现方法:
  8. 1、获取配置文件中制定的ftp服务器信息,用户名采用加密方式
  9. 2、获取远程目录下的文件列表,若存在保存的文件列表,进行比对,提取差异文件
  10. 3、根据差异文件进行文件获取
  11. '''
  12. import datetime
  13. import ConfigParser
  14. import os
  15. import ftplib
  16. import cPickle
  17.  
  18. class GetDataBaseDiff(object):
  19.  
  20. def __init__(self, config, interfaceID = None, interfaceDate = None, delay = 0):
  21. self.config = config
  22. self.interfaceID = interfaceID
  23.  
  24. #默认为当天日期
  25. if interfaceDate == None:
  26. self.interfaceDate = datetime.date.strftime(datetime.date.today() - \
  27. datetime.timedelta(delay),"%Y%m%d")
  28.  
  29. def getConfig(self, interfaceDate):
  30.  
  31. readConfig = ConfigParser.ConfigParser()
  32. with open(self.config,'r') as configFile:
  33.  
  34. readConfig.readfp(configFile)
  35. hostaddr = readConfig.get('ftp.properties','ipaddress')
  36. username = readConfig.get('ftp.properties','username')
  37.  
  38. #是否解析参数和加密
  39. resolve = readConfig.get('ftp.properties','resolve')
  40. encryption = readConfig.get('ftp.properties','encryption')
  41.  
  42. #目录信息
  43. remoteDir = readConfig.get('ftp.properties','remoteDir')
  44. localDir = readConfig.get('ftp.properties','localDir')
  45.  
  46. #存储上次获取文件列表
  47. lastFileList = readConfig.get('ftp.properties','lastFileList')
  48.  
  49. if encryption == '' :
  50. password = readConfig.get('ftp.properties','password')
  51. else:
  52. command = encryption + ' ' + readConfig.get('ftp.properties','password')
  53. password = os.popen(command)
  54.  
  55. if resolve == '' :
  56. month = interfaceDate[0:6]
  57. remoteDir = remoteDir.replace(r"[SDT_YYYYMMDD]", interfaceDate)
  58. remoteDir = remoteDir.replace(r"[SDT_YYYYMM]",month)
  59.  
  60. localDir = localDir.replace(r"[SDT_YYYYMMDD]", interfaceDate)
  61. localDir = localDir.replace(r"[SDT_YYYYMM]",month)
  62.  
  63. return hostaddr, username, password, remoteDir, localDir, lastFileList
  64.  
  65. def connect(self, hostaddr, username, password):
  66.  
  67. try:
  68. connftp = ftplib.FTP(hostaddr)
  69. except ftplib.error_perm:
  70. print "The ipaddress (ipaddress) refused!" %{'ipaddress':hostaddr}
  71.  
  72. try:
  73. connftp.login(username, password)
  74. except ftplib.error_perm:
  75. print "This username (username) refuse connect, please check your\
  76. username or password!" %{'username':username}
  77.  
  78. return connftp
  79.  
  80. def getFileList(self, connftp, remoteDir):
  81.  
  82. #获取文件详细信息,包括权限、文件大小、属主等信息,其中第5项为文件大小
  83. connftp.cwd(remoteDir)
  84. filesDetail = connftp.nlst('-l')
  85.  
  86. #保存文件名称和大小
  87. fileList = {}
  88.  
  89. for fileDetail in filesDetail:
  90. filelistFromDetail = fileDetail.strip().split()
  91. fileList[filelistFromDetail[-1]] = filelistFromDetail[4]
  92.  
  93. return fileList
  94.  
  95. def comparisonFileList(self, lastFileList, newFileList):
  96.  
  97. #装载上一次文件获取信息
  98.  
  99. if len(open(lastFileList, "rb").readlines()) > 0 :
  100. with open(lastFileList, "rb") as fp:
  101. try:
  102. lastfileList = cPickle.load(fp)
  103. except EOFError:
  104. print "Load (filename) was failed"%{'filename':lastFileList}
  105. else:
  106. lastfileList={}
  107.  
  108. lastfileset = set(lastfileList.keys())
  109. newfileSet = set(newFileList.keys())
  110.  
  111. #提取新增文件列表
  112. diffFileList = list(newfileSet - lastfileset)
  113. sameFileName = list(newfileSet & lastfileset)
  114.  
  115. #提取前后文件大小不一致的文件列表
  116. for samefilename in sameFileName:
  117. if newFileList[samefilename] != lastfileList[samefilename]:
  118. diffFileList.append(samefilename)
  119.  
  120. del lastfileList
  121. #保存最新文件获取列表
  122. fp = open(lastFileList, "wb")
  123.  
  124. lastfileList = cPickle.dump(newFileList, fp)
  125. fp.close()
  126.  
  127. return diffFileList
  128.  
  129. def machedFileList(self, diffFileList, interfaceID, interfaceDate):
  130. return [flist for flist in diffFileList if interfaceID in flist \
  131. and interfaceDate in flist]
  132.  
  133. def download(self, connftp, localDir, getFileList):
  134.  
  135. #进入本地目录
  136. if not os.path.isdir(localDir) :
  137. os.makedirs(localDir)
  138.  
  139. try:
  140. os.chdir(localDir)
  141. except :
  142. print 'Dose\'t enter the directory , mybe you have not authority!'
  143.  
  144. #获取最新文件
  145. for remotefile in getFileList:
  146. try:
  147. connftp.retrbinary("RETR %s"%remotefile, open(remotefile,"wb").write)
  148. except ftplib.error_perm:
  149. print 'ERROR: cannot read file "%s"' % remotefile
  150.  
  151. connftp.quit()
  152.  
  153. if __name__ == '__main__' :
  154. interfaceDate = ''
  155. interfaceID = None
  156. getDataBaseDiff = GetDataBaseDiff('./config.properties', interfaceDate, 0)
  157. hostaddr, username, password, remoteDir, localDir, lastFileList = getDataBaseDiff.getConfig(interfaceDate)
  158.  
  159. connectionFtp = getDataBaseDiff.connect(hostaddr, username, password)
  160.  
  161. fileList = getDataBaseDiff.getFileList(connectionFtp, remoteDir)
  162. diffFileList = getDataBaseDiff.comparisonFileList(lastFileList, fileList)
  163.  
  164. if interfaceID is not None and len(diffFileList) >0:
  165. getFileList = getDataBaseDiff.machedFileList(diffFileList, interfaceID, interfaceDate)
  166. getDataBaseDiff.download(connectionFtp, localDir, getFileList)
  167. else:
  168. getDataBaseDiff.download(connectionFtp, localDir, diffFileList)

如上,是学习python后,尝试编写的代码。可修改为配置文件中配置多个平台,获取多平台接口数据。

ETL应用:一种一次获取一个平台接口文件的方法的更多相关文章

  1. JS中对获取一个标签的class的方法封一个库

    在JS中我们经常会会用到,获取一个标签的id var aId=document.getElementById("id") 现在虽然有getElementsByClassName这个 ...

  2. 使用fuser命令kill一个终端(特殊文件)的方法

    /*********************************************************************  * Author  : Samson  * Date   ...

  3. 用js如何获取一个上传文件的扩展名

    function suffix(file_name){     var result =/\.[^\.]+/.exec(file_name);     return result; }

  4. 记录一种下载https网址中的mp4文件的方法

    需要下载一个网页中的视频, 页面中的视频播放器为 JW player, 通过搜索发现可以下载对应的视频. 1. 使用chrome浏览器分析 网页中的视频地址: F12或者右键-->检查, 在打开 ...

  5. 通过ES6 封装了一个上传文件的方法 XMLHttpRequest() 通用

    ### 上传进度回显,上传速度回显 ### 源码如下,新建index.js装起来 export class UploadServers { constructor (options) { this.x ...

  6. ASP.NET之MVC 微信公众号授权给第三方平台的技术实现流程(获取第三方平台access_token)

    “出于安全考虑,在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据”.这是文档中的原话,也 ...

  7. Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体

    问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...

  8. java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。

    首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一.  类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...

  9. 获取一个 app 的 URL Scheme 的方法:

    获取一个 app 的 URL Scheme 的方法: 上这个网站 URL Schemes 查一下相应的 app 的 URL Scheme 是否有被收录 第一种方法没找到的话,把相应的 app 的 ip ...

随机推荐

  1. PHP使用CURL获取302跳转后的地址实例

    /*返回一个302地址*/     function  curl_post_302($url, $vars) { $ch = curl_init();          curl_setopt($ch ...

  2. springMVC对简单对象、Set、List、Map的数据绑定和常见问题.

    算了,就不粘贴了,到原文去查看吧! springMVC对简单对象.Set.List.Map的数据绑定和常见问题.

  3. crontab 解析

    一.crontab简介 Linux 提供了一个非常强大且易用的设置周期性执行指令的工具命令--crontab,常常用于设置循环任务的执行. 默认情况下,任何使用者若不被加入/etc/cron.deny ...

  4. ASP.NET动态网站制作(25)-- ADO.NET(4)

    前言:这节课老师主要讲网页当中内容的分页效果,自己写一个分页控件. 内容: 1.首先写出HTML代码: <div id="pager"> <%=GetPagerH ...

  5. [转]Java中怎样把数组转换为ArrayList

    方法汇总: Element[] array = {new Element(1),new Element(2),new Element(3)}; ArrayList<Element> arr ...

  6. ios - 视图 渐变

    // // YViewGradient.m // AoleYou20170907 // // Created by XY IOS on 2018/4/25. // Copyright © 2018年 ...

  7. Linux虚拟机安装完centos后环境配置

    linux下面安装软件 yum install rpm -ivh 编译安装 三部曲:./configure make make install 卸载 rpm -e 安装方法 1)通过yum安装软件 需 ...

  8. Android无线测试之—UiAutomator UiSelector API介绍之三

    节点关系介绍 每一个布局文件都是一个严格的层次结构布局文件,只有对层次结构非常的了解,才能更好的搜索定位我们需要的主键元素 一.XML文档节点关系介绍 备注:查看节点关系主要使用UiAutomatro ...

  9. C++基础题

    刚在网上转看到几道对于巩固基础很有帮助的C++基础题,反正闲着也是闲着,就做了下,具体题型如下: 答案是我自己写,不一定对,如果有朋友看到不对的,欢迎指正,万分感谢! 1. 一个指针类型的对象占用内存 ...

  10. Ubuntu下安装phpMyAdmin

    首先添加必要的apt源 1 apt-get update 确保软件包列表是最新的 apt-get upgrade 更新软件包 安装phpMyAdmin apt-get install phpmyadm ...